We are all familiar with the standard way of linking style sheets to HTML documents in the <head>
, but this is just one of the ways we write CSS. So how do we write styles in single-page applications (SPAs), such as in React projects?
It turns out that there are multiple ways to write CSS in React applications. Some are similar to traditional methods, while others are quite different. So let's take a look at the different approaches we can use.
Importing External Style Sheets#
As the name suggests, React can import CSS files. The process is similar to linking CSS files in the HTML <head>
:
- Create a new CSS file in the project directory.
- Write CSS.
- Import it into the React file.
For example:
import "./style.css";
Usually, this import is placed at the top of the file.
import { React } from "react";
import "./App.css";
function App() {
return (
<div className="main">
</div>
);
}
export default App;
In the example above, a file named App.css
is imported at the top of App.jsx
.
Writing Inline Styles#
You may have heard in the past that inline styles are not great for maintainability, but in some cases, they do make sense. And maintainability is not an issue in React because CSS is usually already in the same file.
Here's a simple way to write inline styles in React:
<div className="main" style={{ color: "red" }}>
However, a better approach is to pass in an object:
- First, create an object that contains different element styles.
- Then use the
style
attribute to add it to the element.
import { React } from "react";
function App() {
const styles = {
main: {
backgroundColor: "#f1f1f1",
width: "100%",
},
inputText: {
padding: "10px",
color: "red",
},
};
return (
<div className="main" style={styles.main}>
<input type="text" style={styles.inputText}></input>
</div>
);
}
export default App;
The example includes a styles
object that contains two additional objects, one for the element with the .main
class and another for the input
element, with styles similar to what we would expect to see in an external style sheet. These objects are then applied to the style
attribute of the elements in the returned markup.
Note that curly braces are used when referencing the styles instead of the quotes we typically use in pure HTML.
Using CSS Modules#
CSS Modules can be used with React and have the advantage of local scope variables. But what exactly are they?
In the words of the documentation:
CSS Modules works by compiling individual CSS files into both CSS and data. The CSS output is normal, global CSS, which can be injected directly into the browser or concatenated together and written to a file for production use. The data is used to map the human-readable names you've used in the files to the globally-safe output CSS.
In simple terms, CSS Modules allow us to use the same class names in multiple files without conflicts, as each class name has a unique programmatic name. This is particularly useful in large applications. Each class name is scoped locally to the component that imports it.
CSS Module style sheets are similar to regular style sheets, but with a different file extension (e.g., styles.module.css
). Here's how they are set up:
- Create a file with the extension
.module.css
. - Import the module into the React application (as we've seen before).
- Add the
className
to the element or component and reference the specific styles from the imported styles.
Here's a simple example:
@tab styles.module.css
/* styles.module.css */
.heading {
color: #f00;
font-size: 20px;
}
@tab App.jsx
import { React } from "react";
import styles from "./styles.module.css";
function App() {
return (
<h1 className={styles.heading}>Hello World</h1>
);
}
export default App;
Using styled-components#
Have you used styled-components
? It's very popular and allows you to build custom components with actual CSS in JavaScript. styled-components
is essentially a React
component with styles. It includes unique class names, dynamic styles, and better CSS management, with each component having its own isolated styles.
Install the styled-components
npm package in the command line:
npm install styled-components
Next, import it into your React app:
import styled from 'styled-components'
Create a component and assign style properties to it. Note the use of template literals enclosed in backticks in the Wrapper
object:
import { React } from "react";
import styled from "styled-components";
function App() {
const Wrapper = styled.div`
width: 100%;
height: 100px;
background-color: red;
display: block;
`;
return <Wrapper />;
}
export default App;
The Wrapper
component above will be rendered as a div
with these styles.
Conditional Styles#
One of the advantages of styled-components
is that the components themselves are functional, as you can use props
in the CSS. This opens the door to conditional statements and changing styles based on state
or props
.
Here's an example:
import { useState } from "react";
import styled from "styled-components";
function App() {
// display state
const [display, setDisplay] = useState(true);
return (
<>
<Wrapper $display={display} />
<button onClick={() => setDisplay(!display)}>Toggle</button>
</>
);
}
// the wrapper styled component
const Wrapper = styled.div`
width: 100%;
height: 100px;
background-color: red;
display: ${(props) => (props.$display ? "block" : "none")};
`;
export default App;
Here, we manipulate the display
property of the div
. This state is controlled by a button that toggles the state of the div
. This, in turn, switches between two different styles.
In the inline if
statement, we use ?
instead of the usual if/else
syntax. The else
part comes after the semicolon. Remember to always call or use the state after initializing it. For example, in the last demonstration, the state should be above the styles of the Wrapper
component.
Conclusion#
We've looked at several different methods of writing styles in React applications. It's not about one being better than the others; it depends on the specific situation you're in.
Hopefully, you now have a good understanding of them and know that you have a variety of tools in your React styling toolkit.