Styling
React does not dictate how to write styles. A Vite project offers several ready-made ways: import a plain CSS file, use CSS modules, set a style with the style attribute or add a library such as Tailwind. All of them work through the className attribute — that is what the HTML class attribute is called in JSX.
A plain CSS file
A CSS file is imported right into the component — Vite adds it to the page. Create src/components/PostCard.css:
/* src/components/PostCard.css */
.post-card {
border: 1px solid #ddd;
border-radius: 8px;
padding: 16px;
margin-bottom: 12px;
}// src/components/PostCard.jsx
import './PostCard.css';
export default function PostCard({ post }) {
return (
<article className="post-card">
<h2>{post.title}</h2>
<p>{post.body}</p>
</article>
);
}Post cards get a border and padding. Keep in mind: such styles are global — the .post-card class affects any element in the app with that class.
A conditional class
A class is built with an ordinary JavaScript string:
// src/components/PostCard.jsx
<article className={isFeatured ? 'post-card featured' : 'post-card'}>For complex cases there is a small library, clsx, but template strings are enough to start.
CSS modules
To keep class names from clashing between components, use CSS modules. Just give the file a .module.css ending — src/components/PostCard.module.css:
/* src/components/PostCard.module.css */
.card {
border: 1px solid #ddd;
padding: 16px;
}
.title {
font-size: 20px;
}// src/components/PostCard.jsx
import styles from './PostCard.module.css';
export default function PostCard({ post }) {
return (
<article className={styles.card}>
<h2 className={styles.title}>{post.title}</h2>
</article>
);
}Vite turns card into a unique name like _card_1x2y3, so another module can safely have its own card class. No setup is needed — it works in the Vite template out of the box.
The style attribute
The style attribute takes an object and suits values computed on the fly:
// src/components/ProgressBar.jsx
export default function ProgressBar({ percent }) {
return <div style={{ width: `${percent}%`, height: 8, background: 'green' }} />;
}React treats a number without units as pixels: height: 8 means 8px.
Tailwind CSS
Tailwind is a popular library of ready-made classes: instead of your own CSS you write className="p-4 border rounded" in the markup. For Vite it is installed with npm install tailwindcss @tailwindcss/vite, the plugin is added to vite.config.js and the line @import "tailwindcss"; to src/index.css. See the Tailwind documentation for details.
What to choose
| Way | When it fits |
|---|---|
| Plain CSS | Global styles, small projects |
| CSS modules | Per-component styles without name clashes |
style | Values computed from data |
| Tailwind | The team agreed to style with classes |
Common mistake
In JSX the attribute is className, not class:
// Wrong: React prints a warning to the console.
<article class="post-card">
// Correct:
<article className="post-card">Also note htmlFor instead of for on the label tag.