Skip to content

Style Application

a) CSS Modules:

CSS Modules allow you to write CSS that’s scoped to a specific component, preventing style conflicts across your application.

How to use CSS Modules:

  1. Create a CSS file with a .module.css extension, e.g., Button.module.css
  2. Import the styles in your component file
  3. Use the imported styles as an object

Example:

Button.module.css:

.button {
background-color: blue;
color: white;
padding: 10px 20px;
border: none;
border-radius: 5px;
}

Button.js:

import React from "react";
import styles from "./Button.module.css";
function Button({ children }) {
return <button className={styles.button}>{children}</button>;
}
export default Button;

Key benefits:

  • Locally scoped class names
  • Reusable styles
  • Compatibility with existing CSS workflows

b) styled-components:

styled-components is a CSS-in-JS library that allows you to write actual CSS code to style your components.

How to use styled-components:

  1. Install the library: npm install styled-components
  2. Import styled-components in your component file
  3. Create styled components using the styled object

Example:

import React from "react";
import styled from "styled-components";
const StyledButton = styled.button`
background-color: blue;
color: white;
padding: 10px 20px;
border: none;
border-radius: 5px;
`;
function Button({ children }) {
return <StyledButton>{children}</StyledButton>;
}
export default Button;

Key benefits:

  • No class name bugs
  • Easier deletion of CSS
  • Dynamic styling based on props
  1. Apply basic styling to your components

Let’s apply some basic styling to a simple Todo application using both CSS Modules and styled-components.

Using CSS Modules:

TodoApp.module.css:

.container {
max-width: 500px;
margin: 0 auto;
padding: 20px;
font-family: Arial, sans-serif;
}
.input {
width: 100%;
padding: 10px;
margin-bottom: 10px;
}
.button {
background-color: #4caf50;
color: white;
padding: 10px 20px;
border: none;
cursor: pointer;
}
.list {
list-style-type: none;
padding: 0;
}
.item {
background-color: #f1f1f1;
margin: 5px 0;
padding: 10px;
display: flex;
align-items: center;
}
.checkbox {
margin-right: 10px;
}

TodoApp.js:

import React, { useState } from "react";
import styles from "./TodoApp.module.css";
function TodoApp() {
const [todos, setTodos] = useState([]);
const [input, setInput] = useState("");
const addTodo = (e) => {
e.preventDefault();
if (input) {
setTodos([...todos, { id: Date.now(), text: input, completed: false }]);
setInput("");
}
};
const toggleTodo = (id) => {
setTodos(
todos.map((todo) =>
todo.id === id ? { ...todo, completed: !todo.completed } : todo,
),
);
};
return (
<div className={styles.container}>
<form onSubmit={addTodo}>
<input
className={styles.input}
value={input}
onChange={(e) => setInput(e.target.value)}
placeholder="Add a todo"
/>
<button className={styles.button} type="submit">
Add
</button>
</form>
<ul className={styles.list}>
{todos.map((todo) => (
<li key={todo.id} className={styles.item}>
<input
type="checkbox"
className={styles.checkbox}
checked={todo.completed}
onChange={() => toggleTodo(todo.id)}
/>
<span
style={{
textDecoration: todo.completed ? "line-through" : "none",
}}
>
{todo.text}
</span>
</li>
))}
</ul>
</div>
);
}
export default TodoApp;

Using styled-components:

import React, { useState } from "react";
import styled from "styled-components";
const Container = styled.div`
max-width: 500px;
margin: 0 auto;
padding: 20px;
font-family: Arial, sans-serif;
`;
const Input = styled.input`
width: 100%;
padding: 10px;
margin-bottom: 10px;
`;
const Button = styled.button`
background-color: #4caf50;
color: white;
padding: 10px 20px;
border: none;
cursor: pointer;
`;
const List = styled.ul`
list-style-type: none;
padding: 0;
`;
const Item = styled.li`
background-color: #f1f1f1;
margin: 5px 0;
padding: 10px;
display: flex;
align-items: center;
`;
const Checkbox = styled.input`
margin-right: 10px;
`;
function TodoApp() {
const [todos, setTodos] = useState([]);
const [input, setInput] = useState("");
const addTodo = (e) => {
e.preventDefault();
if (input) {
setTodos([...todos, { id: Date.now(), text: input, completed: false }]);
setInput("");
}
};
const toggleTodo = (id) => {
setTodos(
todos.map((todo) =>
todo.id === id ? { ...todo, completed: !todo.completed } : todo,
),
);
};
return (
<Container>
<form onSubmit={addTodo}>
<Input
value={input}
onChange={(e) => setInput(e.target.value)}
placeholder="Add a todo"
/>
<Button type="submit">Add</Button>
</form>
<List>
{todos.map((todo) => (
<Item key={todo.id}>
<Checkbox
type="checkbox"
checked={todo.completed}
onChange={() => toggleTodo(todo.id)}
/>
<span
style={{
textDecoration: todo.completed ? "line-through" : "none",
}}
>
{todo.text}
</span>
</Item>
))}
</List>
</Container>
);
}
export default TodoApp;

Both these examples achieve similar styling, but with different approaches. CSS Modules keep your CSS separate from your JavaScript, while styled-components allow you to write your styles directly in your component files.

The choice between CSS Modules and styled-components often comes down to personal or team preference, as well as the specific needs of your project.