In this article, we will learn 3 different ways to write CSS in React.
React promotes component-driven development, where the state, logic, style, and everything should be isolated to component itself, but it should be designed in such a way that multiple components can be composed together to create a module and components can also be extended.
Keeping this in mind we are going to see 3 different ways to apply styles to HTML elements in React.
- Gobal styling using regular CSS.
- Component level styling using CSS modules.
- Creating styled component or Element level styling with styled-components.
Global styling with CSS files in React
We can create the normal CSS file for each component or a single global CSS file and apply the styles to the HTML elements using the selectors. Id, Class, and other CSS selectors.
//index.css p{ color: red; font-size: 1.5em; }
import "./index.css"; const App = () => { return <h1>Learnersbucket.com</h1>; }; export default App;
While this works like a charm the only problem here is that styles are global and it will apply the style to all the HTML elements that matches the selector.
Even if you have separate CSS files for each component, it will conflict with the others as while creating the bundle, all the styles will be dumped in a single CSS file.
Component level styling with CSS modules in React
CSS modules are created by naming the CSS files as *.modules.css
where *
can be the name of the file.
It creates a locally scoped CSS in which the class selectors and animation names can be accessed as JavaScript objects within the components.
// app.module.css .red { color: red; }
import Styles from "./app.module.css"; const App = () => { return ( <> <h1 className={Styles.red}>Learnersbucket.com</h1> </> ); }; export default App;
This really keeps the styles isolated to the component itself, but the problem with this is we cannot merge multiple classes (objects) directly.
We will need one extra package for that called classNames and because it is spelled similarly to the className
which used for HTML class, it can be hard to understand it initially to many.
// app.module.css .red { color: red; } .large { font-size: 3em; }
import Styles from "./app.module.css"; import ClassNames from "classnames"; const App = () => { return ( <> <h1 className={ClassNames(Styles.red, Styles.large)}> Learnersbucket.com </h1> </> ); }; export default App;
Using styled-components to style the components in Reactjs
One of the best way to style the components or HTML elements in React is by using the styled-components.
It allows you to write CSS in JavaScript, which fulfills the purpose of component driven development as the style is isolated to the component itself.
import Styled from "styled-components"; const OutlinedButton = Styled.button` background: transparent; border-radius: 3px; color: black; border: 1px solid; display: inline-block; margin: 0.5rem 1rem; padding: 0.5rem 0; transition: all .25s ease; width: 10rem; cursor: pointer; &:hover{ color: red; } `; const Test = () => { return ( <> <OutlinedButton>Click me</OutlinedButton> </> ); }; export default Test;
The style will be applied to any HTML element with all the sudo states and it is returned as component that we can use as any other component in React.
As you can see in the above code, we have also written the styles of the hover state in the styled-component only.
It also accepts props that makes it easier to apply dynamic styles.
import Styled from "styled-components"; const OutlinedButton = Styled.button` background: ${(props) => (props.fill ? "gray" : "transparent")}; border-radius: 3px; color: ${(props) => (props.fill ? "white" : "black")}; border: 1px solid; display: inline-block; margin: 0.5rem 1rem; padding: 0.5rem 0; transition: all .25s ease; width: 10rem; cursor: pointer; &:hover{ color: ${(props) => (props.fill ? "blue" : "red")};; } `; const Test = () => { return ( <> <OutlinedButton fill>Click me</OutlinedButton> </> ); }; export default Test;
The styled-components can aslo be extended. It overrides the styles in the extend components
import Styled from "styled-components"; const OutlinedButton = Styled.button` background: ${(props) => (props.fill ? "gray" : "transparent")}; border-radius: 3px; color: ${(props) => (props.fill ? "white" : "black")}; border: 1px solid; display: inline-block; margin: 0.5rem 1rem; padding: 0.5rem 0; transition: all .25s ease; width: 10rem; cursor: pointer; &:hover{ color: ${(props) => (props.fill ? "blue" : "red")};; } `; const FilledButton = Styled(OutlinedButton)` background: green; border-color: yello; `; const Test = () => { return ( <> <OutlinedButton fill>Click me</OutlinedButton> <FilledButton fill>I am filled</FilledButton> </> ); }; export default Test;
Props from the extended component is passed to the base component and all the effects takes place as per the course.