React is a declarative, efficient, and flexible JavaScript library for building user interfaces. It lets you compose complex UIs from small and isolated pieces of code called “components”. Components make the task of building UIs much easier. Components let you split the UI into independent and reusable pieces.
Styling components in React can be done in different methods and approaches. Each of these methods can style our React application depending on the complexity or size of our application or what we want to achieve.
In this tutorial, we will take a look at the different methods we can use to style components in React applications and also the pros and cons of using each method. Some of the different methods of styling components we will learn are:
- Inline CSS
- CSS Stylesheet
- CSS-in-JS(Styled-components)
- CSS modules
- Utility-first CSS(Tailwind CSS)
Prerequisites
A basic understanding of CSS and ReactJs is needed to follow along with this tutorial.
Styling Components in React
Inline CSS
Inline CSS is a direct way of writing CSS directly into our JSX code.
We can apply the styles directly to an element and in order to do these, the value of the style property must be a JavaScript object.
We can write inline CSS in two ways: either using the JavaScript object directly into the element or declaring the JavaScript object as a variable and then applying it to the element.
import React from "react";
export default function App() {
return (
<div className="App">
<p style={{ fontSize: "25px", color: "blue" }}>Click the button</p>
<button
style={{
border: "1px solid green",
color: "green",
padding: "15px 25px",
borderRadius: "5px",
}}
>
Click me
</button>
</div>
);
}
In this first example, the javascript object is used directly in the element. One important thing to note is that when writing inline CSS all properties that contain two words must be written in camelCase
. This means that words like background-color
will be written as backgroundColor
.
import React from "react";
export default function App() {
const paragraph = {
fontSize: "25px",
color: "blue"
};
const btn = {
border: "1px solid green",
color: "green",
padding: "15px 25px",
borderRadius: "5px",
textAlign: "left"
};
return (
<div className="App">
<p style={paragraph}>Click the button</p>
<button style={btn}>Click me </button>
</div>
);
}
In this method, the javascript object is declared as a variable and then we accessed the value in our JSX element.
Advantages of Using Inline CSS
It is a very direct method of styling components.
It is very easy to use.
Inline CSS allows you to apply style rules to specific elements.
Downsides of Using Inline CSS
It is not ideal for large-scale applications as the styling will be bulky and this will make our code messy.
It hinders us from utilizing the power of CSS for example, pseudo-classes, pseudo-selectors, media queries, keyframe animation, etc.
CSS Stylesheet
CSS stylesheet is a method of using an external CSS file that contains styles that can be imported into our React component. In this case, we write all our CSS in a file and then name it with a .css
file extension.
When we create a React application using create-react-app, it autoconfigures Webpack for us and Webpack allows us to import our files correctly.
For instance, if we have a Card.js
file, we will create a Card.css
file that contains our CSS code and then we will use the import
keyword in our js file to access the CSS styling.
After importing the Card.css
file into the Card.js
file, we will use the className
property to access the styles.
Card.css code:
.card {
font-family: sans-serif;
text-align: center;
background-color: rgb(0, 87, 138);
width: 15rem;
height: auto;
border-radius: 20px;
padding: 2rem 0;
color: white
}
.card-header{
text-decoration: underline
}
.card-button{
border: 1px solid rgb(110, 98, 214);
background-color: white;
padding: 10px 30px;
border-radius: 5px
}
.card-button:hover{
background-color: red;
color: white
}
Card.js code
import React from "react";
import "./styles.css";
const Card = () => {
return (
<div className="card">
<h3 className="card_header">Things to do</h3>
<div className="card_content">
<p>Wash the dishes</p>
<p>Clean the garage</p>
<p>Send an email</p>
</div>
<button className="card_button">Start</button>
</div>
);
}
export default Card;
When using a CSS stylesheet, it is advisable to use a class naming pattern called BEM (Block Element Modifier)
. BEM
is a naming convention that makes our code easier to work with and also understand.
Using BEM
helps to make our class names unique, and it also helps to avoid re-using class names in places where we do not want to. You can read more about BEM
here
Advantages of Using CSS Stylesheet
- It is the most popular method of styling.
- It is easier to make changes to the style when needed.
- We can use all the CSS methods and techniques, such as keyframe animations, media queries, pseudo-selectors.
Downsides of Using CSS Stylesheet
As the application grows bigger, the stylesheet will become very bulky and this will make it hard to navigate.
Without using a proper naming convention, i.e. BEM, the code will be hard to read and understand and this could lead to lots of mistakes and errors in our code.
CSS-in-JS
CSS-in-JS is a technique for writing CSS styles directly into a JavaScript file. It helps to define styles in JS in a more component-approach manner, this means that it scopes each style to an individual component.
There are a bunch of libraries that can implement the CSS-in-JS approach. The common ones are:
- Styled-components
- JSS
- Emotion
- Styled-JSX
Let's take a look at how styled-components work.
Styled-Components
Styled-components is the most common way of writing CSS-in-JS. Styled-components let us write plain CSS in our Javascript component without having to worry about class name collisions. It allows us to use all CSS features, including media queries, keyframe animation, nesting, etc.
Styled-components utilizes tagged template literals, which is similar to the template literals in ES6. It can be used in both React and React native applications.
In order to use Styled-component in our application, we have to follow the steps below:
- Install the library as a dependency. Run the code below to install styled-components.
# with npm
npm install --save styled-components
# with yarn
yarn add styled-components
- Import the library into our component.
import styled from "styled component"
- We create a variable that holds our style. The variable can be associated with any valid HTML element.
const Card = styled.div`
// lines of code
`
- We will now use our variable name as a wrapper to hold the contents in our JSX.
The code sample below shows how to implement Styled-component in our application using the steps listed above.
import React from "react";
import styled from "styled-components";
const CardContent = styled.div`
font-family: sans-serif;
text-align: center;
background-color: rgb (0, 87, 138);
width: 15rem;
height: auto;
border-radius: 20px;
padding: 2rem 0;
color: white;
`;
const CardHeader = styled.h3`
text-decoration: underline;
`;
const Button = styled.button`
border: 1px solid rgb(110, 98, 214);
background-color: white;
padding: 10px 30px;
border-radius: 5px;
`;
const Card = () => {
return (
<CardContent>
<CardHeader>Things to do</CardHeader>
<div>
<p>Wash the dishes</p>
<p>Clean the garage</p>
<p>Send an email</p>
</div>
<Button className="card-button">Start</Button>
</CardContent>
);
};
export default Card;
Advantages of Styled-Components
Styled-components generate unique class names for our styles. This means that we do not have to worry about class names colliding or styles conflicting, since each style is tied to an individual component.
It is easier to maintain. We can debug our code easily no matter how big the codebase is.
Styled-components makes it possible to nest our CSS selectors just as we would in Sass. Only in this case, we do not have to install Sass.
Downsides of Using Styled-component.
A third-party JavaScript library will be added to our application, and this means more load to our project. It is easier for the browser to run CSS than tons of JS.
It may take a while for developers to get used to the styled-components syntax as it differs from the traditional way of writing CSS.
Tailwind CSS
Tailwind CSS
is a utility-first CSS
library for rapidly building custom user interfaces. Tailwind enables you to write inline styling and achieve a fantastic user interface without leaving your HTML/JSX code and writing a single line of CSS.
Check out the Tailwind CSS documentation for directions on how to install and configure tailwindcss into your project
How to use Tailwind CSS in React Apps.
Let's style a button using Tailwind CSS
<button class="bg-purple-500 text-white py-2 px-6 font-semibold rounded border hover:bg-pink-600">Sign In</button>
Here’s what each class means in this example:
bg-purple-500
: sets the background color to purple. The value 600 is just a shade number that ranges from (50-900).text-white
: sets the color of the button to white.py-2
: adds padding to the element in the y-direction i.e padding-top and padding-bottompx-6
:adds padding to the element in the x-direction i.e padding-top and padding-bottomfont-semibold
: This gives the font-weight of 600.rounded
: This class sets the border radius to 0.25remborder
: sets border width to 1pxhover:bg-pink-600
:This class turns the purple background to pink when it is hovered on.
You can visit this codesandbox for a very detailed example.
Advantages of using Tailwind CSS
Tailwind CSS saves time. By using tailwind we get access to several CSS classes, all we have to do is just add the classes directly into our JSX elements.
Tailwind CSS solves the problem of naming conventions seamlessly by providing utility-based classes that can be used all the time.
Tailwind CSS uses a default mobile-first approach and the availability of utility classes makes it easier to build complex responsive layouts freely.
Downsides of Using Tailwind CSS
When writing Tailwind CSS, we have to write a lot of classes into our JSX and this can make our codebase very messy and hard to read and understand.
Tailwind CSS doesn't provide default styled components like in Boostrap or Bulma. You need to implement it from scratch.
CSS Modules
A CSS module is a simple CSS file but a key difference is by default when it is imported every class name and animation inside the CSS module is scoped locally to the component that is importing it also CSS file name should follow the format ‘filename.module.css’. This allows us to use a valid name for CSS classes without worrying about conflicts with other class names in our application.
One fantastic attribute CSS modules is that they can be used with either normal CSS or SASS. Plus, if we use Create React App we can start using CSS modules with no setup at all otherwise, we will need webpack and a couple of loaders that enable webpack to bundle CSS files.
import React from "react";
import style from "./card.module.css";
const Card = () => (
<div className={style.cardBody}>
<p className={style.cardContent}>This is the content of the card</p>
</div>
);
export default Card;
.cardBody {
background-color: #ddd;
width: 20rem;
height: 15rem
}
.cardContent {
padding: 15px;
font-size: 20px;
color: blue
}
Advantages of Using CSS Modules
- Modular and reusable CSS,
- No more styling conflicts,
- Explicit dependencies,
- Local scope
Downsides of Using CSS Modules
Extra build tools (e.g. webpack).
Mixing CSS Modules and global CSS classes is cumbersome.
Conclusion
All the styling methods that we have outlined in this tutorial can be tailored to suit the needs of our project.
Each one also has its own advantages and disadvantages and this is why you should consider the kind of project you're working on before selecting one. Most organizations also have their preferred method and this is done to avoid conflict in the codebase.
Whichever method you decide to go with, just know that you are still writing CSS and the only different might be the syntax.