Table of contents
Introduction
It is no longer news that React is one of the most powerful and used Javascript frameworks. It is built on a style of programming known as Declarative Programming, where you need to 'declare' what you want to do and React will handle all the how-to i.e details. But React is not just all about composing components and making sure your logics work, it is also about styling and making sure your app looks good, nobody wants an ugly UI.
In this article, you will learn the major ways you can style your React apps using CSS, The best practices in styling React apps, How to conditionally render styles in React and a lot more.
Prerequisite
You must have a basic understanding of React, Javascript and CSS before you dive into this article to fully understand the contents, nevertheless, I've simplified the concepts in this article so you can understand everything perfectly.
Ways to Use CSS in React Apps
There are several ways to use the Cascading Style Sheet(CSS) in your React apps, In this section, you learn the four(4) most common and efficient ways to do it. They are;
Inline CSS
External CSS
Styled Components
CSS Modules
Inline CSS
This is when CSS styles are written in the React JSX codes, it is used to apply CSS styles to a single HTML element in the DOM. It is important to mention that the Inline CSS takes the most priority and as a result overrides all other forms of styling applied to the same HTML element.
To use Inline CSS, the style
attribute is used just before the closing tag of the target HTML element in the JSX code. This attribute
takes a javascript object as its value, the keys in this object are CSS property names written in camelCase e.g backgroundColor
, as opposed to the kebab case- hyphens(-)-used in CSS sheets and their values, are the CSS styles being applied. Illustrations of this are given in the code snippets below:
function MyReactComponent(){
return <button style={{ backgroundColor: 'red', borderRadius: 10, padding: 20 }}>
Inline CSS example</button>
}
In the above code snippet, the style attribute has been used to attach an inline style to the button
element, you should take note of how the CSS property names have been written in camelCase and not the kebab case used in CSS sheets. Also worthy of note is the absence of units in the borderRadius
and padding
values, this is general for numeric inline style properties with a "px" unit; If you'd like to use other units like "em" "rem" etc. the values are written as strings, an illustration is given below;
function MyComponent(){
return <div style={{ color: 'blue', margin: "10rem", padding:"2em", boxShadow: '1px 2px 9px #F4AAB9' }}> Inline Styled Component</div>
}
export default MyComponent
Also, an alternative way to write Inline styles is to create a javascript object with styling information and pass it into the style
attribute as shown below:
function App(){
const titleStyle = {
color: "red",
backgroundColor: "black",
padding: 20,
fontFamily: "serif"
};
return (
<div>
<h1 style={titleStyle}>Inline CSS</h1>
<p>Let's style our React App!</p>
</div>
);
}
export default App
A further example of Inline CSS
const App = () => {
return (
<div>
<div
style={{
boxShadow: '1px 2px 9px #F4AAB9',
margin: '4em',
padding: '1em',
}}
>
Hello World
</div>
</div>
)
}
export default App
One major flaw that is seen with Inline CSS is that it makes your React components bulky and often difficult to debug. Also, it leads to excessive code repetition which you typically want to avoid when programming.
External CSS
This is done by creating a new CSS file in your project directory using the .css
extension and then adding your regular CSS inside the file, after which you import the file into your React component. An example of this is given below:
The CSS styles in a file dir
.style.css
.container { text-align: center; border: 1px; box-shadow: '1px 2px 9px #F4AAB9'; margin: 4em; padding: 1em; } .title { text-align: center; color: red; } p { color: yellow; }
The React Component named
App.js
import React from 'react'; import ".style.css"; function App(){ return ( <div className="container"> <h1 className="title">Inline CSS</h1> <p>Let's style our React App!</p> </div> ); } export default App
Importing the stylesheet into the React component
App.js
applies the styles to the HTML elements. The problem with this way of styling our React app is that the CSS styles are not scoped to the components they are imported to and as a result, they become globally available. This can lead to styling problems especially when you have multiple developers working on the same project and they use the sameclassName
for their elements.
Styled Components
This is a third-party library used to build components that have certain styles attached to them and these styles do not affect elements outside such components. The styled-components are a CSS-in-JS tool that enables the coupling of React components and their CSS styles in the same file, behind the scenes this library attaches unique classNames
to HTML elements so you do not need to worry about classNames
conflicts as in External CSS.
The styled components have certain advantages over other ways of styling React Apps, these are;
Dynamic Styles: With Styled components, It is easier to create dynamic styles and render styles conditionally in your React App.
JS and CSS in the Same File: With the styled component it is possible to write your CSS in your React Components without bloating your components as in Inline CSS. This makes it even easier to render styles conditionally by passing state management props.
Vendor Automatic Prefixing: Vendor names like
ms
,moz
,webkit
etc do not need to be used in CSS property names as the Styled Component library does this for you behind the scenes.Easy Maintenance and Debugging: styled-components are easy to debug and maintain, especially since style changes only affect components that import them i.e the styles are scoped only to components that import them.
Step by Step Guide on how to use Styled Components
Install the library on your project using your terminal:
npm install --save styled-components
Import
styled
from styled-component in your React Component file:import React from 'react'; import styled from 'styled-components'
Now you are ready to create your first styled component. Create a new variable, the name is totally up to you.
import React from 'react'; import styled from 'styled-components' const MyButton= styled.button``
The Imported
styled
object contains all the HTML elements as methods. In this example, we have called abutton
method which will return an HTML element-abutton
-that can then be stored in theMyButton
component and used anywhere in the code. Also, there is a strange syntax in the code snippet above, the two backticks(``)
, you've probably never seen it before; this is known as a Tagged Template literal. It is a regular javascript syntax that has been incorporated by the styled component libraryNext, you can then begin to add your regular CSS styles between the two backticks.
import React from 'react'; import styled from 'styled-components' const MyButton= styled.button` background: transparent; border-radius: 3px; border: 2px solid palevioletred; color: palevioletred; margin: 0.5em 1em; padding: 0.25em 1em; &:focus:{ background-color: red; } @media (min-width:789px){ width: auto; } `
And there you have it, you've created your first styled component. Notice how d CSS selectors were omitted in the styling and how
&
is used to replace the selector that should have been before thefocus
pseudo-selector? This is because the styled component library adds the right selectors behind the scene.After you've successfully added styles, all that is left is to use the styled component in your component
import React from 'react'; import styled from 'styled-components' const MyButton= styled.button` width: 100% background: transparent; border-radius: 3px; border: 2px solid palevioletred; color: palevioletred; margin: 0.5em 1em; padding: 0.25em 1em; &:focus:{ background-color: red; } @media (min-width:789px){ width: auto; } ` function App() { return ( <div> <p> Style Components is awesome!</p> <MyButton>Yes</MyButton> </div> ) } export default App;
CSS Modules
CSS modules are CSS files In which all the classNames
and CSS selectors are scoped locally and can only be available in another file when they are imported. The classes and selectors act like local variables in Javascript, with these modules you can have elements with similar class names in your program without having to worry about styling conflicts. Behind the scenes, CSS classes in the modules are given unique ClassNames, you'll see this when you inspect the DOM on your chrome developer tools.
If you enjoy having your CSS and javascript codes separated in different files without the risk of style conflicts as in the external CSS, then the CSS styling module is the one for you. One advantage of the CSS modules is that it ships with React projects created with create-react-app
and create-vite
so you do not need to install it separately.
Step by Step Guide on how to use CSS Modules.
Create a new CSS file with the
.module.css
extension e.gstyle.module.css
Next, using the Named import syntax, you import your CSS file into the React component you want to style
import React from 'react'; import styles from '/style.module.css';
After importing the CSS module into your Component as in the above code snippet, you then get access to the javascript object
styles
that contain all the classes present in your CSS module.Add your CSS styles into your
.module.css
file:.container { text-align: center; border: 1px; box-shadow: '1px 2px 9px #F4AAB9'; margin: 4em; padding: 1em; } .header { text-align: center; color: red; } .text { color: yellow; }
Finally, you can style your JSX tags by setting the
className
prop value to bestyle.(your_css_class)
import React from 'react' import styles from '/style.module.css'; function App(){ return ( <div className={styles.container}> <h1 className={styles.header}>CSS Modules </h1> <span className={styles.text}>Hello World</span> </div> ); } export default App
Conditional/Dynamic Styling
So far you've learned several ways to style your React App using static CSS. In this section, you'll learn how to add Conditional or Dynamic styles. Conditional styles are styles that are rendered only when a particular condition is true e.g when a user submits an empty form, you may want to notify them this Is not allowed by changing the color of the input field or you may want to notify the user a particular task is successful by changing the position of an HTML element. All of these and more are possible with the Dynamic Rendering feature on React.
Conditional Styling Using Inline CSS
The code snippet below shows step by step guide to rendering styles conditionally using Inline CSS.
In this example, the
background-color
of asubmit
button is set to change upon successful form submission. First, we have a form-handling component with all the logic to handle and submit a formimport React from 'react' import { useState } from 'React' function FormHandler(){ const [userName,setUserName]=useState() const onChangeHandler=(event)=>{ //This even listerner listens to changes in the input field setUserName(event.target.value)//this sets the state "userName } const submitHandler=(event)=>{ //This event listener handles form submission event.preventDefault()//this prevents the default submit behaviour //Code to add Conditional styles will be written here } return ( <div> <label>Your name:</h1> <input onChange={onChangeHandler}/> <button style={{ backgroundColor: 'green', borderRadius: 10, padding: 4 }} onSubmit={submitHandler}>Submit</button> </div> ); }
In the code snippet below logic to change the
button
color from red to green upon valid submission has been added in thesubmitHandler
.You'll notice also that the inline styling on thebutton
element has also been updated to conditionally render a red-colored button whenisValid
is false and a green-colored one when true.import React from "react" import {useState} from "React" function FormHandler(){ const [isClicked,setIsClicked]= useState(false) const [userName,setUserName]=useState("") const changeHandler=(event)=>{ setUserName(event.target.value) } const submitHandler=(event)=>{ event.preventDefault() if(userName.trim() !==""){ setIsClicked((prev)=>!prev) } } return( <div> <label>Your name:</h1> <input onChange={onChangeHandler}/> <button style= {{ backgroundColor: `${isClicked? "green" : "red"}`, borderRadius: 10, padding: 4 }} onSubmit={submitHandler}>Submit</button> </div> ) }
Conditional Styling Using External CSS
Conditional styling can also be used with the External CSS In a similar way it has been applied to the Inline CSS. The Code snippets below show step by step guide to achieving this.
In this Illustration, the functionality to change the color of the
<h1>
HTML element upon button click will be implemented.First, prepare an external CSS file with your styles in it.
.header{ color: yellow; text-align: center; } .header clicked{ color: green; } button{ background: transparent; border-radius: 3px; border: 2px solid palevioletred; color: palevioletred; margin: 0.5em 5em; padding: 0.25em 1em; }
Import the
style.css
file into the React Componentimport React from 'react' import { useState } from 'React' import "./style.css" function App (){ return( <div> <h1 className="header">Hello World!</h1> <button>click me</button> </div> ) } export default App
Add the logic to change the color of the
h1
tag using the state management hook-useState
and External CSS.import React from 'react' import { useState } from 'React' import "./style.css" function App (){ const [isClicked,setIsClicked]=useState(false) const clickHandler=()=>{ setIsClicked((prev)=> !prev) //sets the value of the isClicked to the opposite of the prev value. } return( <div> <h1 className={`header ${isClicked && "clicked"}`}>Hello World!</h1> <button onClick={clickHandler}>click Me</button> </div> ) } export default App
In the code snippet above, when the value of
isClicked
becomestrue
the newclicked
CSS style will be added to change the color of thehi
tag to green.
Conditional Styling With Styled Components
It's relatively easy to render styles conditionally when using the styled components. The ability to write CSS in JS in this tool enables developers to use React props in their CSS styles, this makes Conditional styling and rendering even easier.
The code snippets below show how conditional styling can be used in styled components to change the border-color
of a button
on hover.
Set up a React component using the style component to style its element
import React from 'react'; import styled from 'styled-components' import { useState } from 'React' const Button= styled.button` width: 100% background: transparent border-radius: 3px; border: 2px solid ${props=> (props.hover ? "gold" : "palevioletred")}; color: palevioletred; margin: 0.5em 1em; padding: 0.25em 1em; &:focus:{ background-color: red; } ` function App() { const [ishovered, setHovered]=useState(false) const hoverHandler=()=>{ setHovered((prev)=> !prev) } return ( <div> <p> Style Components is awesome!</p> <Button hover={isHovered} onMouseEnter={hoverHandler}>Yes</Button> </div> ) } export default App;
In the code snippet above, a ternary operator has been used to conditional change the
border-color
of thebutton
using thehover
prop as a condition.
Conditional Styling with CSS Modules
The CSS modules also support the conditional rendering of CSS styles. This is illustrated in the code snippets below.
In this illustration, conditional styling is used to highlight the
<span>
element upon click. First, set up a React Component using a CSSstyle.module.css
file..container { text-align: center; border: 1px; box-shadow: '1px 2px 9px #F4AAB9'; margin: 4em; padding: 1em; } .hello-header { text-align: center; color: red; } .text { color: yellow; } .text highlight { background-color: yellow; }
import React from 'react' import { useState } from 'React' import style from "./style.module.css" function App (){ //The on click logic will be added here return( <div className={style.container}> <h1 className={style["hello-header"]}>Hello World!</h1> <span className={style.text}>click me</span> </div> ) } export default App
Adding Logic to highlight the
span
upon click.import React from 'react' import { useState } from 'React' import style from "./style.module.css" function App (){ const [isHightlighed,setIsHighlighted]=useState(false) const clickHandler=()=>{ setIsHighlighted((prev)=> !prev) } return( <div className={style.container}> <h1 className={style["hello-header"]}>Hello World!</h1> <span className={`${style.text} ${isHighlighted ? "highlight" : " "}`} onClick={clickHandler}>click me</span> </div> ) } export default App
From the code snippets you've seen so far in this section, it is quite obvious that dynamic rendering of CSS styles involves the addition or removal of className
using the state management hook-useState
.
Conclusion
In this article, you've learned several ways you can style your React apps with CSS and also how to render style conditionally using each of these tools.
In reality, the styling tool you will use for your React Apps completely depends on which one of these tools you're most comfortable with, they are all powerful and capable tools for styling all React Apps. I use the CSS modules in most of my React projects because I like to separate my CSS from JS code and I also hate to worry about class names while styling my Apps. For me, the CSS modules offer the best of both worlds. You can access the styled components docs here.
It's a wrap, I hope you enjoyed reading this piece as much as I enjoyed writing it, drop a like and comment below. Until next time, folks.