Styling with Plain CSS (Part 2): Organizing CSS Files #24
π Introductionβ
In the previous article, we learned the fundamental technique of styling React components by importing a standard CSS file. While this method is simple and effective, it comes with a major challenge as applications grow: managing the global nature of CSS.
This article focuses on best practices for organizing your CSS files to create a scalable and maintainable styling architecture. We'll discuss the concept of co-locating styles with components and how to structure your project to balance global and component-specific styles.
π Prerequisitesβ
Before we begin, please ensure you have a solid grasp of the following concepts:
- Importing CSS in React: You should be comfortable with the
import './styles.css';
syntax. - The Global Scope Problem: A clear understanding that CSS imported this way applies to the entire application, as discussed in the previous article.
π― Article Outline: What You'll Masterβ
In this article, you will learn:
- β The Co-location Principle: The benefits of keeping component-specific styles in the same directory as the component itself.
- β File Naming Conventions: Best practices for naming your CSS files to correspond with their components.
- β Structuring a Project: A practical folder structure for managing your styles.
- β Global vs. Component Styles: How to create a main stylesheet for global rules (like fonts and variables) while keeping component styles separate.
- β Practical Example: Refactoring a simple project to use this organized structure.
π§ Section 1: The Core Concept: Co-locationβ
Co-location is the practice of placing files that are closely related in the same directory. In React, this means keeping a component's JavaScript (.jsx
), its styles (.css
), and its tests (.test.js
) all together in one folder.
The Problem with a Single styles
Folder:
A common approach in older web projects was to have a single /styles
folder containing all CSS files. This becomes difficult to manage in a component-based framework like React because:
- It's hard to know which styles belong to which component.
- Deleting a component might leave behind "orphan" CSS files.
- The risk of global class name collisions is very high.
The Benefit of Co-location:
By placing Button.css
inside the Button
component folder, you create a self-contained, modular unit. Everything the Button
component needs to function and look correct is in one place. This makes the component easier to understand, maintain, and even move to other projects.
π» Section 2: A Practical Folder Structureβ
Let's establish a clean and scalable folder structure for a project.
src/
βββ assets/
β βββ fonts/
β βββ images/
β
βββ components/
β βββ Button/
β β βββ Button.jsx
β β βββ Button.css
β β
β βββ Alert/
β βββ Alert.jsx
β βββ Alert.css
β
βββ index.css // Our GLOBAL stylesheet
βββ App.jsx // Our main application component
Breakdown of the Structure:
src/components/
: This directory holds all our reusable components.src/components/Button/
: Each component gets its own folder.Button.jsx
andButton.css
: The component's logic and styles live side-by-side. The CSS file is named identically to the component file (except for the extension) for maximum clarity.src/index.css
: This is our one truly global stylesheet. It's the perfect place for styles that need to apply everywhere.
π οΈ Section 3: Global Styles vs. Component Stylesβ
The key to this organization is deciding what belongs in the global index.css
versus what belongs in a component-specific file like Button.css
.
3.1 - What Goes in index.css
(Global Styles)β
Your global stylesheet should define the foundational look and feel of your entire application. It should contain styles you almost never want to override.
Good candidates for index.css
:
- CSS Resets: A reset (like
margin: 0; box-sizing: border-box;
) to ensure consistent rendering across browsers. - Font Definitions:
font-family
,font-size
for thebody
orhtml
tags. - CSS Variables: Defining global color palettes, spacing units, etc.
- Basic Typography: Default styles for
h1
,h2
,p
,a
tags.
Example index.css
:
/* index.css */
:root {
--primary-color: #007bff;
--text-color: #333;
--background-color: #fff;
}
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
background-color: var(--background-color);
color: var(--text-color);
}
You import this file only once, in your application's entry point, which is typically src/index.js
or src/main.jsx
.
3.2 - What Goes in Button.css
(Component Styles)β
Component stylesheets should contain styles that are only relevant to that specific component.
Example Button.css
:
/* components/Button/Button.css */
.Button {
padding: 10px 20px;
border: 1px solid var(--primary-color); /* Uses global variable */
background-color: var(--primary-color);
color: white;
border-radius: 5px;
cursor: pointer;
font-size: 1rem;
}
.Button:hover {
opacity: 0.9;
}
This file is then imported only inside Button.jsx
. This mental modelβkeeping component styles local and foundational styles globalβis the key to scalable CSS in React.
β¨ Section 4: Best Practices for Organizationβ
- One Component, One Folder: Every component should live in its own folder.
- Co-locate Files: Keep the component's JSX, CSS, and tests together in that folder.
- Name Files Consistently: Name the CSS file the same as the component file (e.g.,
UserProfile.jsx
andUserProfile.css
). - Global Styles in
index.css
: Use a single entry-point CSS file for your global styles and import it only once in your app's main entry file. - Use Component-Based Naming: As discussed previously, use a naming convention like BEM (
.Button
,.Button--primary
) in your component CSS to prevent the remaining risk of global conflicts.
π‘ Conclusion & Key Takeawaysβ
Organizing your CSS files is just as important as organizing your components. A well-structured project is easier to navigate, maintain, and scale. By co-locating component-specific styles and defining a clear global style foundation, you can avoid many of the common pitfalls of CSS in large applications.
Let's summarize the key takeaways:
- Co-location is Key: Place a component's CSS file in the same folder as its JSX file for modularity and maintainability.
- Separate Global and Local: Use a main
index.css
file for global styles (fonts, variables, resets) and component-specific files for everything else. - Import Globally Once: Your main global stylesheet should be imported only once, at the root of your application.
- Component-First Mindset: This organizational structure reinforces the component-based architecture of React itself.
Challenge Yourself:
Take the Alert
and Button
components from the previous lessons and refactor your project to match the folder structure described in this article. Create a global index.css
with a custom font and a primary color variable, then make sure the Alert
and Button
components use that global variable in their own co-located stylesheets.
β‘οΈ Next Stepsβ
You now have a solid strategy for organizing plain CSS in a React project. However, this approach still relies on naming conventions to avoid conflicts. In the next article, "Inline Styles in React (Part 1)", we will explore a completely different method of styling that avoids the issue of global scope entirely.
Thank you for your dedication. Stay curious, and happy coding!
glossaryβ
- Co-location: The practice of placing related files together in the same directory. For React, this means grouping a component's logic, styles, and tests.
- Global Styles: CSS rules that apply to the entire application.
- Component Styles: CSS rules that are intended to apply only to a specific component.
- CSS Reset: A set of CSS rules that aims to remove and neutralize the default styling of HTML elements provided by browsers.