Table of Contents
You might have come across different ways to style React components. In this article, we will discuss the most popular ways to do it and the advantages and disadvantages of using them.
Inline Styling
If you want to add a style quickly, you can make use of the style
prop to pass the styles to the element as shown below:
1import React from "react"23const InlineStyle = () => {4 return (5 <div>6 <button7 style={{8 backgroundColor: "#0ea5e9",9 border: "none",10 color: "white",11 borderRadius: "0.5rem",12 padding: "0.5rem 1rem",13 cursor: "pointer",14 }}15 >16 Hover Me17 </button>18 <p19 style={{20 color: "green",21 background: "lightGreen",22 padding: "0.5rem 1rem",23 }}24 >25 Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ea ab26 exercitationem soluta, consequatur obcaecati suscipit numquam dolorem,27 dignissimos quas nobis error repellat minus sed accusamus placeat, rerum28 illum magnam aspernatur?29 </p>30 </div>31 )32}3334export default InlineStyle
As you could see, we have to pass the styles in a JavaScript object to the style prop. You can see a demo of using inline styles here.
Advantages
- With inline styles, we do not want to create a separate css file and switch between the css and the component file while applying styles.
Disadvantages
-
As you may have seen in the demo, nothing happens when you hover over the button. This is because, with inline styles, you will not be able to add pseudo selectors like
:hover
,:focus
etc. -
This requires you to write css in the js format, which many people who are used to writing css in a traditional way may not like.
-
We cannot reuse the styles, or use any selectors, which makes the code lengthy and unmaintainable.
In-Page Styles
In Page styles are nothing but inline styles extracted to a separate JavaScript object:
1import React from "react"23const InPageStyle = () => {4 return (5 <div>6 <button style={styles.button}>Hover Me</button>7 <p style={styles.paragraph}>8 Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ea ab9 exercitationem soluta, consequatur obcaecati suscipit numquam dolorem,10 dignissimos quas nobis error repellat minus sed accusamus placeat, rerum11 illum magnam aspernatur?12 </p>13 </div>14 )15}1617const styles = {18 button: {19 backgroundColor: "#0ea5e9",20 border: "none",21 color: "white",22 borderRadius: "0.5rem",23 padding: "0.5rem 1rem",24 cursor: "pointer",25 },26 paragraph: {27 color: "green",28 background: "lightGreen",29 padding: "0.5rem 1rem",30 },31}3233export default InPageStyle
The advantage of using styles this way is you can reuse the styles within the component. If you place it in a common file and export the styles, then you can use it throughout the application.
Global styles
Global styles are the traditional way of having a css file containing all the styles related to the entire application.
To make use of global styles, create a css file as shown below:
1.button {2 background-color: #0ea5e9;3 border: none;4 color: white;5 border-radius: 0.5rem;6 padding: 0.5rem 1rem;7 cursor: pointer;8}910.button:hover {11 background-color: rgb(37, 99, 235);12}13.paragraph {14 color: green;15 background: lightGreen;16 padding: 0.5rem 1rem;17}
Now include the global.css
in the topmost component in your project:
1import React from "react"2import "./global.css"34const GlobalStyle = () => {5 return (6 <div>7 <button className="button">Hover Me</button>8 <p className="paragraph">9 Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ea ab10 exercitationem soluta, consequatur obcaecati suscipit numquam dolorem,11 dignissimos quas nobis error repellat minus sed accusamus placeat, rerum12 illum magnam aspernatur?13 </p>14 <button className="button">Hover Me</button>15 </div>16 )17}1819export default GlobalStyle
Advantages
- Unlike inline styles, we can have different types of selectors to share the styling between components.
- Since style is separated into a different file, it helps in having a cleaner code.
Disadvantages
- Since all the styles are stored in a single css file, if multiple people are working on the project, then it might result in both code conflict and styling conflicts.
Create react app comes with default
index.css
, which is an example of global css styling.
You can see a demo of the global css here.
CSS Modules
CSS Modules is a way to have separate css styles for each module. Let's separate the buttons and paragraphs into different components.
1import React from "react"2import styles from "./ButtonOne.module.css" // Import css modules stylesheet as styles34const ButtonOne = () => {5 return (6 <div>7 <button className={styles.button}>Hover Me</button>8 </div>9 )10}1112export default ButtonOne
1import React from "react"2import styles from "./ButtonTwo.module.css" // Import css modules stylesheet as styles34const ButtonTwo = () => {5 return (6 <div>7 <button className={styles.button}>Hover Me</button>8 </div>9 )10}1112export default ButtonTwo
1import React from "react"2import styles from "./Paragraph.module.css" // Import css modules stylesheet as styles34const Paragraph = () => {5 return (6 <div>7 <p className={styles.paragraph}>8 Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ea ab9 exercitationem soluta, consequatur obcaecati suscipit numquam dolorem,10 dignissimos quas nobis error repellat minus sed accusamus placeat, rerum11 illum magnam aspernatur?12 </p>13 </div>14 )15}1617export default Paragraph
Now let's add the styles for all the 3 components:
1.button {2 background-color: #0ea5e9;3 border: none;4 color: white;5 border-radius: 0.5rem;6 padding: 0.5rem 1rem;7 cursor: pointer;8}910.button:hover {11 background-color: rgb(37, 99, 235);12}
1.button {2 background-color: rgb(239, 68, 68);3 border: none;4 color: white;5 border-radius: 0.5rem;6 padding: 0.5rem 1rem;7 cursor: pointer;8}910.button:hover {11 background-color: rgb(185, 28, 28);12}
1.paragraph {2 color: green;3 background: lightGreen;4 padding: 0.5rem 1rem;5}
Finally, let's include all the components in our app:
1import React from "react"2import ButtonOne from "./ButtonOne"3import ButtonTwo from "./ButtonTwo"4import Paragraph from "./Paragraph"56const CssModules = () => {7 return (8 <div>9 <ButtonOne />10 <Paragraph />11 <ButtonTwo />12 </div>13 )14}1516export default CssModules
If you inspect the demo page and see, you will observe that the classes are named in the format <ComponentName>_<ClassName>_<RandomString>
.
This is done to avoid any conflicts between the css modules.
Advantages
-
Since each module has a separate css file, multiple developers can work in parallel without css or merge conflicts.
Disadvantages
- There can be code duplication if the same style is used across the modules (which can be solved by pushing the common styles to a global stylesheet).
So far we have seen methods supported in react by default. Now we will see some third-party libraries, which help in styling the app.
Styled Components
Styled Components helps in defining the styles of a component by passing the actual css using template literals (back ticks), as shown below:
1const Button = styled.button`2 border-radius: 3px;3 padding: 0.5rem 0;4 margin: 0.5rem 1rem;5 width: 11rem;6 background: transparent;7 color: white;8 border: 2px solid white;9`
Now we just need to include the Button component wherever it is needed.
To make use of styled components, we need to install it first (you may use npm i styled-components
if you prefer to.):
1yarn add styled-components
Consider the following code:
1import React from "react"2import styled, { css } from "styled-components"34const Button = styled.button`5 background: transparent;6 border-radius: 3px;7 border: 2px solid palevioletred;8 color: palevioletred;9 margin: 0.5em 1em;10 padding: 0.25em 1em;11 cursor: pointer;1213 ${props =>14 props.primary &&15 css`16 background: palevioletred;17 color: white;18 `}19`2021const Paragraph = styled.p`22 color: green;23 background: lightGreen;24 padding: 0.5rem 1rem;25`2627const StyledComponents = () => {28 return (29 <div>30 <Button>Normal Button</Button>31 <Paragraph>32 Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ea ab33 exercitationem soluta, consequatur obcaecati suscipit numquam dolorem,34 dignissimos quas nobis error repellat minus sed accusamus placeat, rerum35 illum magnam aspernatur?36 </Paragraph>37 <Button primary>Primary Button</Button>38 </div>39 )40}4142export default StyledComponents
Styled Component can receive props and then apply different styles if that prop matches some condition.
Like in our case, we are changing the color and the background of the button, if the prop primary
is set to true.
A demo of the above code can be found here.
We can also extend an existing style as shown below:
1const Button = styled.button`2 border-radius: 3px;3 padding: 0.5rem 0;4 margin: 0.5rem 1rem;5 width: 11rem;6 background: transparent;7 color: white;8 border: 2px solid white;9`10const EnhancedButton = styled(Button)`11 :hover {12 color: red;13 }14`
The EnhancedButton
will get all the styles from the Button
component and the styles defined by itself.
Emotion
Emotion is alternative to styled-components. We can install emotion in React by running the following command:
1yarn add @emotion/react
Now we can use emotion in our app:
1/** @jsxRuntime classic */2// this comment tells babel to convert jsx to calls to a function called jsx instead of React.createElement3/** @jsx jsx */4import { css, jsx } from "@emotion/react"56const color = "white"78const Emotion = () => {9 return (10 <div>11 <button12 css={css`13 margin: 0.5em 1em;14 padding: 0.25em 1em;15 cursor: pointer;16 background-color: hotpink;17 font-size: 24px;18 border-radius: 4px;19 border: none;20 &:hover {21 color: ${color};22 }23 `}24 >25 Hover Me26 </button>27 <p28 css={css`29 color: green;30 background: lightGreen;31 padding: 0.5rem 1rem;32 `}33 >34 Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ea ab35 exercitationem soluta, consequatur obcaecati suscipit numquam dolorem,36 dignissimos quas nobis error repellat minus sed accusamus placeat, rerum37 illum magnam aspernatur?38 </p>39 </div>40 )41}4243export default Emotion
If you see, it is a bit similar to styled components, which uses the backtick syntax.
In fact, there is a package called @emotion/styled, which helps in writing css in styled-component way!
The demo for the above code can be found here.
SASS support
If you wish to use SCSS in your app, then you can do so by installing node-sass
:
Now create file named styles.scss
with the following content:
1$myColor: purple;23h2 {4 color: $myColor;5}
Then use it in the component by importing it:
1import React from "react"2import "./styles.scss"34const Sass = () => {5 return (6 <div>7 <h2>Styling using SASS</h2>8 </div>9 )10}1112export default Sass
Other libraries
There are other libraries as well like tailwind, and component libraries like Semantic UI, React Bootstrap, Ant Design, Chakra UI, BluePrint, Material UI, etc., which you can try out.
Source code and Demo
You can view the complete source code here and a demo here.
Do follow me on twitter where I post developer insights more often!