Skip to content

React Tutorial Styling React Applications

Using CSS Stylesheets in a React Project

Lesson 82 of 156 2 min read By Deepak Paswan Updated Oct 10, 2026

Full-project lesson · needs Node.js, npm and real project files, so it does not run in the in-page playground.

The most direct way to style a React app is the one you already know: write a CSS file and use class names. React only changes how you attach the classes (className instead of class).

Import the CSS file

In a Vite project you import a CSS file from JavaScript. Vite adds the styles to the page for you (and, in production, bundles them into a file).

Create src/components/Card.css:

src/components/Card.css
CSS
.card {
  border: 1px solid #d0d7de;
  border-radius: 8px;
  padding: 16px;
  max-width: 320px;
}

.card__title {
  margin: 0 0 8px;
  color: #1a5276;
}

Create src/components/Card.jsx, which imports it:

src/components/Card.jsx
JSX
import './Card.css'

function Card({ title, children }) {
  return (
    <section className="card">
      <h2 className="card__title">{title}</h2>
      {children}
    </section>
  )
}

export default Card

And use it in src/App.jsx:

src/App.jsx
JSX
import Card from './components/Card.jsx'

function App() {
  return (
    <Card title="Styled with CSS">
      <p>This card gets its look from Card.css.</p>
    </Card>
  )
}

export default App

This is verified: the project was built with Vite and the title’s computed colour is the one in the CSS file.

Global scope: the important caveat

An imported .css file is not scoped to the component. Its rules go into one global stylesheet that applies to the whole page, like any other CSS. If another file also defines .card, they collide, and the later one wins. Three ways to stay safe:

  1. Use a naming convention. BEM (.card__title, .card--featured) or a prefix per component keeps names unique.
  2. Keep selectors flat and low in specificity. Prefer one class per rule over div > ul li a.
  3. Use CSS Modules, which make names unique automatically; see CSS Modules.

Global styles

Put resets, fonts, CSS variables and base element styles in one global file and import it once, in main.jsx. The Vite template does this with src/index.css:

src/main.jsx
JSX
import './index.css'

CSS custom properties are the best way to share design values (colours, spacing) across components:

src/index.css
CSS
:root {
  --brand: #1a5276;
  --radius: 8px;
}
script.js
JS
.card { border-radius: var(--radius); }

Dynamic styles

For styles that depend on props or state, switch class names rather than writing CSS in JavaScript; see Conditional Classes. For values that must be computed (a progress bar width), use an inline style or a CSS variable set inline.

Where to put CSS files

Place a component’s CSS next to the component: Card.jsx and Card.css in the same folder. They are easy to find, and you delete them together.

Assets inside CSS

Relative url() paths inside imported CSS are resolved by Vite, which also fingerprints the files:

style.css
CSS
.hero { background-image: url('./hero.png'); }

Common mistakes

  • Using class instead of className in JSX.
  • Forgetting to import the CSS file. The component renders unstyled and no error appears.
  • Writing generic names such as .title or .button, which clash with other files.
  • Expecting component-scoped CSS from a plain .css import. It is global.

Key points

  • import './File.css' adds the styles; apply them with className.
  • Plain CSS imports are global, so name carefully or use CSS Modules.
  • Keep shared design values in CSS variables and keep CSS next to its component.