Built by Facebook, React is a declarative, efficient, and flexible JavaScript library used for creating custom user interfaces. As of the time of writing, the total number of live websites using React for their UI is well north of 11.9 million. Statistically, 3.3% of all websites use this JavaScript library, including some of the most popular sites known to man.
In this article, we’ll explore the different ways of styling React components with CSS. This will include the pros and cons of each method, as well as some best practices. Read on as we dive deep into the art of creating beautiful UIs with React + CSS.
Inline styles
This is the most straightforward way to style any React app, as it doesn’t require creating a separate stylesheet. Plainly put, it involves adding CSS styling alongside your React.js code. Notably, styles applied inline have higher precedence than other styles. This means that inline styles will override any formatting specified in any external stylesheets you may have.
import React from "react";
import ReactDOM from "react-dom/client";
export default function Greeting() {
return <h2 style={{ backgroundColor: "lightgray" }}>Hello World!</h2>;
}
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<Greeting />);
Advantages of inline styling
It is a fast and straightforward way of styling React components
It comes in handy when prototyping
Has great preference
Disadvantages of inline styling
Tedious, especially for large applications
Lots of inline styles hinder your code’s readability
You can’t use some CSS features with inline styling, such as animations, selectors, etc.
In a nutshell, inline styles are great when building a small app or prototyping your components. However, as your app grows, you may need to switch to another CSS styling option.
Importing external stylesheets
This is one of the most common styling techniques used by React developers. Admittedly, this method keeps improving as more features are introduced to the CSS standard. For instance, there are CSS variables to store dynamic values, selectors to pick out child elements with precision, and new pseudo-classes such as “:is” and “:where.”
To utilize this technique, create a CSS file in your project directory, in which you’ll write your formatting styles. Most importantly, remember to import it into your React file as illustrated below:
//index.js
import React from "react";
import ReactDOM from "react-dom/client";
import "./styles.css";
export default function Greeting() {
return (
<div className="main">
<h2>Hello World!</h2>
</div>
);
}
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<Greeting />);
//styles.css
* {
box-sizing: border-box;
margin: 0px;
}
.main {
background-color: lightgray;
width: 100vw;
}
h2 {
color: red;
}
This technique enables easy reusability of styling guidelines. However, one major problem that arises as your app grows bigger is the naming convention. After a while, it becomes difficult to think of unique class names for each element.
It is also vital to remember that CSS cascades to all children elements. This means that any styles you import from an external stylesheet and apply to a component also transfer to any children elements of the said component.
Advantages
Cleans out inline styles from component files, improving readability
Enhances reusability, as you can apply the same CSS styles to several components
Offers all modern CSS tools like variables, advanced selectors, and pseudo-classes
Disadvantages
Styles cascade to a component and its children
You must use a reliable naming convention to prevent styles from conflicting
Using CSS modules
CSS modules provide an ingenious solution to the conflicting class nomenclature problem we faced with stylesheets. Essentially, modules allow us to use the same class name in multiple components without clashes, as each class name is converted to a unique programmatic name. What’s more, CSS declared using modules does not cascade to child components, which helps us better target individual components.
A CSS module is akin to a regular stylesheet, except its name must contain the “.module” extension before the “.css.” For instance, in place of styles.css, our module is named styles.modules.css. If we use SASS/SCSS, the name must also contain “.module” before the appropriate extension (More on this to follow).
//index.js
import React from "react";
import ReactDOM from "react-dom/client";
import styles from "./styles.module.css";
export default function Greeting() {
return (
<div className={styles["main"]}>
<h2 className={styles["h2"]}>Hello World!</h2>
</div>
);
}
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<Greeting />);
Notice how we have to import the CSS module file into our React file. If you’re using create-react-app, you can use CSS modules with no additional setup. Here’s a super simple example of a CSS module:
//styles.module.css
* {
box-sizing: border-box;
margin: 0px;
}
.main {
background-color: lightgray;
width: 100vw;
}
h2 {
color: red;
}
Notably, CSS modules are written just like regular CSS but used as objects (inline styling).
Advantages
Styles scope to singular components
Modules generate unique programmatic class names, ensuring no style clashes
You can use modules with SASS or CSS
Can be employed with no additional setup in CRA apps
Disadvantages
- Referencing class names and using styles like object properties can be confusing for novices
Using styled components
Much like React allows you to use HTML in your JavaScript using JSX, adding CSS to your JS file is also made possible by styled-components. This means you can style your components without creating a CSS file. What’s more, each style you apply scopes to individual components. As a result, you can alter one component’s CSS without affecting a bazillion other components.
To use this technique, first, navigate to the root folder of your project. Install the styled-components package by running the command “npm install styled-components.” Remember to import it into your React app as follows:
import React from 'react';
import ReactDOM from 'react-dom/client';
import styled from 'styled-components';
const Wrapper = styled.div`
width: 100vw;
height: 33vh;
background-color: lightgray;
display: block;
`;
const Button = styled.button`
color: limegreen;
border: 2px solid limegreen;
font-size: 1em;
margin: 1em;
padding: 0.25em 1em;
border-radius: 3px;
&:hover {
opacity: 0.9;
}
`;
function Greeting() {
return (
<Wrapper>
<h2>Hello, World!</h2>
<Button>Click me</Button>
</Wrapper>
);
}
export default Greeting;
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Greeting />);
Notice how we use template literals denoted by backticks when assigning styled properties to a component. The Wrapper component will be rendered as a div with the specified styles in our example above.
While using styled components, you can write normal CSS, including nested styles and pseudo-classes. You can associate these styles with any valid HTML element and create new components with these styles.
Interestingly, since the tagged template literal is essentially a component, you can pass it props to give it dynamic features.
Advantages
It makes for predictable styling, as properties scope to individual components
It can be used with props to reuse, export, or even extend styles
It’s not prone to class name conflicts
Disadvantages
- Requires additional JavaScript libraries, which may make your app bulkier
SASS/SCSS
Short for syntactically awesome style sheets, SASS is basically CSS on steroids. This means it comes with numerous powerful features and tools, many of which do not exist in regular CSS. To mention a few, these include features like variables, nesting, and extending styles.
SASS stylesheets take either of two extensions, “.scss” and “.sass.” SCSS styling resembles the syntax of normal CSS. SASS styling, in contrast, does not require the signature curly braces used in CSS.
Here’s an SCSS stylesheet with style nesting:
//styles.scss
section {
ul {
margin: 0;
padding: 0;
list-style: none;
}
li {
display: inline-block;
}
a {
display: block;
padding: 5px 10px;
text-decoration: none;
}
}
For comparison, here is the same code written in SASS:
//styles.sass
section
ul
margin: 0
padding: 0
list-style: none
li
display: inline-block
a
display: block
padding: 5px 10px
text-decoration: none
Notice how SASS does not require semicolons at the end of each statement. Further, since this is not regular CSS, you’ll need to compile it into plain CSS using a library like node-sass. If your app is a Create React App project, install this library by running the command "npm install node-sass." You can then import your stylesheets into your JS file as usual.
Advantages of SASS/SCSS
Comes with advanced CSS features such as variables, nesting, extending, and mixins
Gets rid of boilerplate CSS code
Disadvantages
Styles have global scope, hence can bring about conflicts
Requires additional libraries
Conclusion
What’s the best way to style React components, you ask? We’ve looked at a handful of options, but which truly reigns supreme? The truth is, your choice of styling technique will depend on your unique situation. Hopefully, you now understand the five ways to include CSS in your React project, and you can confidently add them to your arsenal. Happy coding!
Top comments (0)