Skip to main content

Styling with Plain CSS (Part 1): Importing CSS Files #23

📖 Introduction

Welcome to a new series focused on making your React applications visually appealing! Now that you have a firm grasp of JSX, it's time to learn how to apply styles. While there are many advanced ways to style React components, the most straightforward and familiar method is using plain, traditional CSS.

This article will walk you through the foundational approach: creating an external CSS stylesheet, importing it into your component, and applying classes using the className prop you've already learned about.


📚 Prerequisites

Before we begin, please ensure you have a solid grasp of the following concepts:

  • Basic CSS: You should know how to write CSS rules with selectors (especially class selectors), properties, and values.
  • React Components: You should be comfortable creating a simple React component.
  • The className Prop: You must know that JSX uses className instead of class to apply CSS classes.

🎯 Article Outline: What You'll Master

In this article, you will learn:

  • The Standard Approach: How to use external CSS files to style your React components.
  • Importing CSS: The correct syntax for importing a stylesheet directly into a component file.
  • Applying Classes: How to use className to link your JSX elements to the styles in your CSS file.
  • Global Scope: Understanding that styles imported this way are global and can affect your entire application.
  • Practical Example: Building and styling a simple component from scratch.

🧠 Section 1: The Core Concept: Separating Styles

For decades, the standard web development practice has been to keep structure (HTML), logic (JavaScript), and presentation (CSS) in separate files. React, especially with modern build tools like Vite or Create React App, fully supports this pattern.

The process is simple:

  1. You write your CSS in a .css file, just like you always have.
  2. You import that file into the JavaScript file where your component is defined.
  3. The build tool (e.g., Vite) processes this import and ensures the CSS is loaded onto the page.
  4. You use the className prop in your JSX to apply the classes you defined.

This approach is intuitive for anyone coming from a traditional web development background.


💻 Section 2: Step-by-Step Implementation

Let's build a simple "Alert" component to see this in action.

2.1 - Create the CSS File

First, let's create a new file named Alert.css in the same directory as our component. This file will contain the styles for our alert message.

/* Alert.css */

.alert {
padding: 12px 16px;
border-radius: 4px;
color: #333;
margin-bottom: 10px;
}

.alert-success {
background-color: #d4edda;
border-left: 5px solid #28a745;
}

.alert-error {
background-color: #f8d7da;
border-left: 5px solid #dc3545;
}

Here, we've defined a base .alert class and two modifier classes, .alert-success and .alert-error, to change the color based on the alert type.

2.2 - Create and Style the React Component

Next, create a new file for our component, Alert.jsx.

// Alert.jsx
import React from 'react';

// Step 1: Import the CSS file
import './Alert.css';

function Alert(props) {
// Step 2: Use the className prop to apply the classes
// We combine the base 'alert' class with a dynamic class
const alertClassName = `alert alert-${props.type}`;

return (
<div className={alertClassName}>
{props.message}
</div>
);
}

export default Alert;

Code Breakdown:

  1. import './Alert.css';: This is the crucial line. We import the stylesheet directly into our component's JavaScript file. The build tool understands that this means the styles in Alert.css should be made available when this component is used.
  2. **const alertClassName = \alert alert-$`;**: We dynamically create the full class string. We always want the base alertclass, and we add eitheralert-successoralert-errorbased on thetype` prop passed to the component.
  3. <div className={alertClassName}>: We pass our generated string of class names to the className prop. React will render this as <div class="alert alert-success"> (or alert-error) in the final HTML.

2.3 - Use the Component

Now we can use our styled Alert component in our main App.js file.

// App.js
import React from 'react';
import Alert from './Alert';

function App() {
return (
<div>
<h1>Application Dashboard</h1>
<Alert type="success" message="Your profile was updated successfully!" />
<Alert type="error" message="Failed to upload file. Please try again." />
</div>
);
}

export default App;

When you run this application, you will see two styled alert boxes, one green and one red, demonstrating that our CSS was successfully imported and applied.


🛠️ Section 3: The Pitfall of Global Scope

It is critical to understand that when you import a stylesheet this way, the styles are global.

This means that the class names you define in Alert.css (e.g., .alert, .alert-success) are available to your entire application. If another component somewhere else in your app also happens to use a class named .alert, it will receive the same styles.

This can lead to unintentional style conflicts in large applications. For example, if another developer creates a Warning.css file with a different-looking .alert class, the two styles will compete, and the one that gets loaded last will "win."

We will explore solutions to this problem, like CSS Modules, in a future article. For now, the best practice to avoid this is to use specific, unique class names.

A Better Naming Convention (BEM-like): A common strategy is to prefix your class names with the component's name.

Alert.css (Improved):

.Alert {
/* ... */
}
.Alert--success {
/* ... */
}
.Alert--error {
/* ... */
}

Alert.jsx (Improved):

const alertClassName = `Alert Alert--${props.type}`;

By using .Alert instead of .alert, you significantly reduce the chance of a name collision with another component's styles.


💡 Conclusion & Key Takeaways

Using plain CSS stylesheets is the most traditional and often the quickest way to get started with styling in React. It leverages existing CSS knowledge and integrates smoothly into the React ecosystem.

Let's summarize the key takeaways:

  • Import Your CSS: You can import .css files directly into your component files just like you import JavaScript modules.
  • Use className: The className prop is used to apply one or more CSS classes to your JSX elements.
  • Styles are Global: Be aware that styles imported this way are added to the global scope, which can lead to conflicts in larger projects.
  • Use Specific Naming: Adopt a naming convention (like BEM) to make your class names unique and avoid style collisions.

Challenge Yourself: Create a Button component. In a corresponding Button.css file, create a base .Button class and modifier classes for different colors and sizes (e.g., .Button--primary, .Button--danger, .Button--large). Import the CSS and use the Button component with different props to render various button styles.


➡️ Next Steps

You now know the most fundamental way to style a React application. In the next article, "Styling with Plain CSS (Part 2)", we will explore best practices for organizing your CSS files for maintainability and scalability as your application grows.

Thank you for your dedication. Stay curious, and happy coding!


glossary

  • Stylesheet: A CSS file containing rules that describe how HTML elements should be displayed.
  • Global Scope: In the context of CSS, this means that styles are applied to the entire document. A class name defined in one file can be used and will have an effect on any element in the entire application.
  • BEM (Block, Element, Modifier): A popular CSS naming methodology that aims to create unique, descriptive, and conflict-free class names by following a Block__Element--Modifier pattern.

Further Reading