Managing CSS in a dynamic environment can be challenging, but React provides a number of tools and techniques to make it easier. In this post, we'll look at how to style your React apps, including how to use inline styles, how to work with CSS modules, and how to use third-party libraries like styled-components. We'll also cover best practices for managing CSS in a React application, and how to optimize your code for performance.
In React, you can use inline styles to style individual elements. To use inline styles, you will need to use the style attribute and pass it an object with camelCase style properties.
Here's an example of how you could use inline styles to style a div
element:
import React from "react";
function Example() {
const divStyle = {
color: "red",
backgroundColor: "yellow",
};
return <div style={divStyle}>This div has inline styles</div>;
}
In this example, the divStyle
object defines the inline styles for the div
element. The style attribute is set to the divStyle
object, which applies the styles to the element.
It's important to note that inline styles in React are different from traditional inline styles in HTML. In React, inline styles are objects with camelCase properties, rather than strings with CSS styles. For example, the background-color
style in HTML would be written as backgroundColor
in React.
Conflicts can occur when you have multiple class names that apply the same styles to different elements in your application. This can happen when you have multiple CSS files or when you use generic class names like .button
or .form
.
Suppose we have a such type of code
/* button.css */
.button {
background-color: blue;
color: white;
font-size: 16px;
padding: 8px 16px;
border-radius: 4px;
}
/* form.css */
.button {
background-color: green;
color: black;
font-size: 14px;
padding: 6px 12px;
border-radius: 2px;
}
In this example, both the button.css
and form.css
files define a .button
class with different styles. If both of these files are included in the same HTML document, the styles from the last file to be included will overwrite the styles from the first file.
This can cause conflicts if you have multiple elements with the same class name that should have different styles. For example, if you have a button element and a form element both with the class .button
, they will both have the same styles, which may not be what you intended.
To avoid conflicts like this, you can use techniques like scoping class
names to a specific component or using unique class names for each element. This can help to ensure that the styles applied to a specific element are only applied to that element and its children, rather than being applied globally to all elements with the same class name.
Styled components is a library that allows you to use CSS styles in your React components, while automatically scoping the class names to avoid conflicts. To use styled components, you will need to install the styled-components
library and import the styled function.
npm i --save styled-components
Here's an example of how you could use styled components to style a button component:
import React from "react";
import styled from "styled-components";
const Button = styled.button`
color: white;
background-color: blue;
border-radius: 4px;
font-size: 16px;
padding: 8px 16px;
&:hover {
background-color: darkblue;
}
`;
function MyButton(props) {
return <Button>Click me</Button>;
}
In this example, the Button
component is created using the styled function and a template literal with CSS styles. The Button
component can then be used like any other component, and the styles will be applied to the rendered element.
One of the benefits of using styled components is that the class names are automatically scoped to the component, which helps to avoid conflicts with other class names in your application. In this example, the generated class name for the Button component would be something like .sc-bdnylx-1 gSzQGJ
, which is unique to the component and unlikely to cause conflicts with other class names.
To use props
in a styled component, you can pass the props as arguments to the styled component function. For example, consider the following styled component that accepts a color
prop:
import styled from "styled-components";
const MyButton = styled.button`
color: ${(props) => props.color};
background-color: blue;
border-radius: 4px;
font-size: 16px;
padding: 8px 16px;
&:hover {
background-color: darkblue;
}
`;
In this example, the color
prop is used to set the color
style of the button. The value of the color
prop is passed to the styled component function as an argument, and can be accessed using the props object.
To use this styled component, you can pass the color
prop when you render the component:
<MyButton color="red">Click me</MyButton>
This will render a button with a red text color and the other styles defined in the styled component.
CSS modules are a way to write and use CSS styles in a modular way, with the goal of avoiding conflicts between class names. CSS modules work by automatically generating unique class names for each style, and scoping the class names to the specific component that uses them.
To use CSS modules in a React application, you will need to configure your build process to support CSS modules. This typically involves using a tool like Webpack, which can transform your CSS files into modules that can be imported into your React components.
Once you have configured your build process to support CSS modules, you can import a CSS file into a React component and use the styles in the file by assigning the styles to a JS object. Here's an example of how you could use CSS modules in a React component:
/* styles.css */
.container {
width: 100%;
max-width: 800px;
margin: 0 auto;
padding: 16px;
}
.title {
font-size: 32px;
color: blue;
}
import React from "react";
import styles from "./styles.module.css";
function App() {
return (
<div className={styles.container}>
<h1 className={styles.title}>Welcome to my app</h1>
</div>
);
}
In this example, the styles.css
file is imported into the App
component and assigned to the styles object. The className
prop is used to apply the styles to the rendered elements, with the class names taken from the styles
object.
The class names in the styles object are automatically generated and scoped to the specific component that uses them, which helps to avoid conflicts with other class names in the application.
you can use a different name instead of styles when importing a CSS module
into a React component. To do this, you can use the as keyword when importing the CSS module.
For example, instead of using the styles object, you could use a different name like css:
import React from "react";
import * as css from "./styles.module.css";
function App() {
return (
<div className={css.container}>
<h1 className={css.title}>Welcome to my app</h1>
</div>
);
}
In this example, the css
object is used instead of the styles object to access the class names in the CSS
module.
You can use any valid JavaScript identifier as the name for the imported object, as long as it doesn't conflict with any other variables or keywords in your code.
/* button.css */
.button {
background-color: blue;
color: white;
font-size: 16px;
padding: 8px 16px;
border-radius: 4px;
}
/* form.css */
.button {
background-color: green;
color: black;
font-size: 14px;
padding: 6px 12px;
border-radius: 2px;
}
import React from "react";
import * as buttonStyles from "./button.module.css";
import * as formStyles from "./form.module.css";
function Button(props) {
return <button className={buttonStyles.button}>{props.children}</button>;
}
function Form(props) {
return <form className={formStyles.button}>{props.children}</form>;
}
function App() {
return (
<div>
<Button>Click me</Button>
<Form>Submit</Form>
</div>
);
}
In this example, the button.css
and form.css
files are imported into the Button and Form components as CSS modules, and assigned to the buttonStyles and formStyles
objects, respectively. The className prop is used to apply the styles to the rendered elements, with the class names taken from the buttonStyles and formStyles objects.
Because the class names in the buttonStyles and formStyles
objects are automatically generated and scoped to the specific component that uses them, there is no conflict between the two .button
class names. The styles from the button.css module will only be applied to button
elements rendered by the Button component, and the styles from the form.css
module will only be applied to form
elements rendered by the Form component.