Skip to content
Node.js Sounds Complicated? This Article Makes It Click

React Styling Guide – How to Add CSS to React Components

The four primary ways to style React elements are:

  • CSS style sheets
  • Inline style attributes
  • CSS Modules
  • CSS-in-JS Libraries

Let’s discuss the four styling techniques.

Using CSS Stylesheets to Style React Elements

Section titled “Using CSS Stylesheets to Style React Elements”

Below are the steps to style JSX elements with regular CSS style sheets.

First, create a CSS stylesheet in your React projects.

Terminal window
touch styles.css

Open the newly created CSS file and declare your styles.

Here’s an example:

styles.css
.text {
color: seagreen;
font-weight: bold;
}

The CSS snippet above instructs browsers to apply a seagreen color and bold font weight on elements with a text class name.

3. Apply the stylesheet’s ruleset to your element

Section titled “3. Apply the stylesheet’s ruleset to your element”

Import your stylesheet into the component file containing the element you wish to style. Then, apply the stylesheet’s ruleset to it.

Here’s an example:

App.js
// Import your stylesheet (the path to your stylesheet may be different).
import "../styles.css";
function App() {
return <div className="text">Oluwatobi is my name.</div>;
}
export default App;

Try it on CodeSandbox

The snippet above instructs React to apply the "text" ruleset on the element with a className="text" attribute.

Using the Inline style Attribute to Style React Elements

Section titled “Using the Inline style Attribute to Style React Elements”

React allows you to apply inline styles to JSX elements in the same way as inline CSS works in HTML. But there are some differences to keep in mind.

First, HTML applies inline styles as a string value:

<div style="color:seagreen; font-weight:bold;">Oluwatobi is my name.</div>

But in React, you must define inline styles as objects, not strings:

<div style={{ color: "seagreen", fontWeight: "bold" }}>
Oluwatobi is my name.
</div>

The snippet above used two sets of curly braces because in JSX, you wrap JavaScript expressions inside curly braces: for instance, <div>{myNameVariable}</div>.

So, suppose the expression is a JavaScript object literal. In that case, you will need two sets of curly braces: for instance, <div>{{ name: "Oluwatobi" }}</div>.

Therefore, in style={{ color: seagreen, fontWeight: bold }}, the first set of curly braces ({...}) tells React that you want to write a JavaScript expression. The second set of curly braces ({ color: seagreen, fontWeight: bold }) is the JavaScript expression (an object) you are assigning as the style attribute’s value.

Here’s an example:

App.js
function App() {
return (
<div style={{ color: "seagreen", fontWeight: "bold" }}>
Oluwatobi is my name.
</div>
);
}
export default App;

Try it on CodeSandbox

The React snippet above instructs the computer to apply an inline style to the div element.

You can see that we wrote fontWeight in camelCase. This is because, under the hood, JSX compiles into plain JavaScript. So it uses the JavaScript Web APIs attribute naming convention.

To make your code easier to read, consider storing your inline style object in a separate variable like so:

App.js
function App() {
// Store your inline style object in a variable:
const textStyles = { color: "seagreen", fontWeight: "bold" };
return <div style={textStyles}>Oluwatobi is my name.</div>;
}
export default App;

Try it on CodeSandbox

As defined on the official documentation, a CSS Module is a CSS file in which all class names and animation names are scoped locally by default.

CSS Modules share many similarities with a regular CSS style sheet. But there are some essential differences.

The syntax for naming a regular CSS stylesheet is [name].css: for instance, codesweetly-styles.css.

But a CSS module’s file naming convention is [name].module.css: for instance, codesweetly-styles.module.css.

Importing a CSS style sheet into your script file makes its rulesets available globally to all components (and child components) of that script.

But importing a CSS module into your script file only makes its rulesets available locally to the component that invokes the module’s rule. Also, that component must be in the script that imports the CSS module.

Here’s an example:

Create a regular CSS stylesheet in your React project and add some rules to it:

styles.css
.imageInfo {
text-align: center;
color: #442109;
}

Also, create a CSS module in the same project and add some rules to it:

styles.module.css
.imageInfo {
border: 8px ridge #71380f;
background-color: #ffe5b4;
padding: 20px 0 7px;
}

Import both the CSS stylesheet and CSS module you’ve just created into your script file:

App.js
import "../styles.css";
import codesweetlyStyles from "../styles.module.css";
function App() {
return (
<div className="imageInfo">
<h1>Random Image</h1>
<img src="https://picsum.photos/400/400" alt="Random Image" />
<p>Get a new image each time you refresh your browser.</p>
</div>
);
}
export default App;

Try it on CodeSandbox

Go ahead and run your app and check its output in your browser.

After running your app, you will notice that React only applied the CSS stylesheet’s ruleset, not the CSS module’s own.

React did so because the stylesheet’s ruleset is globally available to all elements (and child components) of the page where you imported the sheet.

But the ruleset in the module is locally available only to the component that explicitly invokes the rule.

So, to use your CSS module’s style in your component, you must explicitly execute it like so:

App.js
import "../styles.css";
import codesweetlyStyles from "../styles.module.css";
function App() {
return (
<div className={`imageInfo ${codesweetlyStyles.imageInfo}`}>
<h1>Random Image</h1>
<img src="https://picsum.photos/400/400" alt="Random Image" />
<p>Get a new image each time you refresh your browser.</p>
</div>
);
}
export default App;

Try it on CodeSandbox

The snippet above uses the codesweetlyStyles.imageInfo code to instruct React to apply the CSS module’s imageInfo ruleset to the div element.

To compose styles together while using a regular CSS style sheet, you must apply multiple classes to your element.

Example: Composing rulesets with regular CSS style sheets

Section titled “Example: Composing rulesets with regular CSS style sheets”
styles.css
.container {
border: 4px solid blueviolet;
padding: 30px 15px;
}
.text {
color: seagreen;
font-weight: bold;
}
App.js
import "../styles.css";
function App() {
return <div className="container text">Oluwatobi is my name.</div>;
}
export default App;

Try it on CodeSandbox

Using multiple classes on an element to implement style composition is not the best practice because CSS will use the order of style definitions in the stylesheet to determine the order of precedence based on the CSS cascading rules.

But CSS modules provide a composes declaration that offers greater flexibility in composing your styles to suit your project’s needs.

Example: Composing rulesets with CSS modules

Section titled “Example: Composing rulesets with CSS modules”
styles.module.css
.container {
border: 4px solid blueviolet;
padding: 30px 15px;
}
.text {
composes: container;
color: seagreen;
font-weight: bold;
}
App.js
import styles from "../styles.module.css";
function App() {
return <div className={styles.text}>Oluwatobi is my name.</div>;
}
export default App;

Try it on CodeSandbox

Although you can define multiple composes declarations in a ruleset, they must precede other rules.

Example: All composes declarations must come before other rules

Section titled “Example: All composes declarations must come before other rules”
styles.module.css
.container {
border: 4px solid blueviolet;
padding: 30px 15px;
}
.curved {
border-radius: 20px;
}
.text {
composes: container;
composes: curved;
color: seagreen;
font-weight: bold;
}

Try it on CodeSandbox

You can simplify the .text ruleset by using a single composes declaration for multiple classes.

Example: Composing classes with a single composes declaration

Section titled “Example: Composing classes with a single composes declaration”
styles.module.css
.container {
border: 4px solid blueviolet;
padding: 30px 15px;
}
.curved {
border-radius: 20px;
}
.text {
composes: container curved;
color: seagreen;
font-weight: bold;
}

Try it on CodeSandbox

Using a CSS-in-JS Library to Style React Elements

Section titled “Using a CSS-in-JS Library to Style React Elements”

A CSS-in-JS library allows you to use the complete features of CSS directly within your JavaScript file.

Some of the popular CSS-in-JS libraries are Linaria, Emotion, Pigment CSS, and Panda CSS.

Feel free to try any CSS-in-JS library you prefer. However, we will use Emotion here to illustrate how such a styling technique works in a React application.

So, go ahead and install the library into any of your React projects by running:

Terminal window
npm i @emotion/react

After you’ve installed Emotion, import it and use it in your component file like so:

App.js
// The comment below is essential. Emotion will not work without it.
/** @jsxImportSource @emotion/react */
// Define your styles using the JavaScript object syntax.
const codesweetlyStyles = {
border: "8px ridge #71380f",
backgroundColor: "#ffe5b4",
padding: "20px 0 7px",
textAlign: "center",
color: "maroon",
"@media(min-width: 768px)": {
color: "darkslategray",
},
};
// Apply the styles to your element.
function App() {
return (
<div css={codesweetlyStyles}>
<h1>Random Image</h1>
<img src="https://picsum.photos/400/400" alt="Random Image" />
<p>Get a new image each time you refresh your browser.</p>
</div>
);
}
export default App;

Try it on CodeSandbox

The snippet above does the following:

  1. Uses the /** @jsxImportSource @emotion/react */ comment (JSX Pragma) to tell the Babel JSX plugin to convert the script’s JSX calls to an Emotion function called jsx instead of React.createElement. Make sure you place the pragma directive above your import statements. Otherwise, the Emotion library will not work.
  2. Defines styles in a JavaScript object.
  3. Uses Emotion’s css prop feature to apply the styles to the JSX element.

Notice that the css prop is like the inline style attribute. The main difference is that the css props support more CSS features like nested selectors, auto vendor-prefixing, media queries, and event states (such as hover, focus, and active). Therefore, using CSS-in-JS libraries like Emotion lets you write highly flexible and responsive styles directly in your JavaScript files.

Now, go ahead and run your app and check its output in your browser.

And that’s it! You now know how to use the CSS-in-JS library to style your React elements.

I used Emotion in this article because I like how clean their syntax looks. Feel free to test other CSS-in-JS libraries, such as Pigment CSS. You may find one that suits you better.

A Beginner's Guide to React: Learn JSX, Hooks, and Real-World App Development