Skip to main content

Introduction to CSS-in-JS (Part 1): `styled-components` #29

📖 Introduction

So far, we've explored styling React components with traditional CSS files, inline styles, and the locally-scoped CSS Modules. Now, we venture into one of the most powerful and modern paradigms in React styling: CSS-in-JS.

This approach fundamentally changes how we think about styles by allowing us to write actual CSS code directly within our JavaScript files. This article will introduce the concept and benefits of CSS-in-JS, with a practical look at one of its most popular libraries, styled-components.


📚 Prerequisites

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

  • React Components: You should be comfortable creating and exporting a basic React component.
  • JavaScript ES6: Familiarity with Tagged Template Literals is helpful, but not required, as the syntax will be explained.
  • Basic CSS: You should be comfortable writing standard CSS properties and values.

🎯 Article Outline: What You'll Master

In this article, you will learn:

  • What CSS-in-JS Is: Understanding the core concept of writing CSS directly in your JavaScript.
  • The Benefits: Why you might choose this pattern (scoped styles, dynamic styling, co-location).
  • Introducing styled-components: A look at one of the most popular CSS-in-JS libraries.
  • Creating Your First Styled Component: The basic syntax using tagged template literals.
  • Using Styled Components: How to render your newly created styled components just like any other React component.

🧠 Section 1: The Core Concept: What is CSS-in-JS?

CSS-in-JS is a pattern where CSS is composed using JavaScript instead of being defined in external .css files. Libraries that implement this pattern allow you to create React components with their styles attached directly to them.

Instead of mapping styles to components via a className, with CSS-in-JS, the component itself is the style.

Key Benefits:

  • True Scoping: Styles are automatically scoped to the component they are defined with. There is zero risk of class name collisions.
  • Dynamic Styling: You can easily and intuitively use props and state to change a component's styles, as the styles are defined within the same JavaScript context.
  • Painless Maintenance: All the styling for a component lives in the same file as the component logic, making it easy to find, change, and delete styles. If you delete a component, you delete its styles automatically.
  • Vendor Prefixing: The library automatically handles vendor prefixes, so you can write modern CSS without worrying about cross-browser compatibility.

💻 Section 2: Getting Started with styled-components

styled-components is one of the most popular libraries for implementing the CSS-in-JS pattern.

2.1 - Installation

First, you need to add it to your project.

npm install styled-components

2.2 - Creating a Styled Component

styled-components uses a JavaScript feature called Tagged Template Literals. It might look strange at first, but the concept is straightforward.

You create a component by calling styled followed by a dot and the HTML tag you want to create (e.g., styled.h1, styled.button, styled.div). Immediately after that, you write your CSS inside backticks (...).

Let's create a simple styled <h1> title and a styled <section> wrapper.

// code-block-1.jsx
import React from 'react';
// Step 1: Import the 'styled' object from the library
import styled from 'styled-components';

// Step 2: Create a component that will render an <h1> tag
const Title = styled.h1`
font-size: 1.5em;
text-align: center;
color: #BF4F74;
`;

// Step 3: Create another component that will render a <section> tag
const Wrapper = styled.section`
padding: 4em;
background: papayawhip;
`;

// Step 4: Use the components like any other React component
function MyApp() {
return (
<Wrapper>
<Title>
Hello World!
</Title>
</Wrapper>
);
}

export default MyApp;

Code Breakdown:

  1. import styled from 'styled-components';: We import the default export from the library.
  2. const Title = styled.h1...: We are creating a new React component named Title. This component will always render an <h1> HTML element. The CSS inside the backticks will be applied directly to it.
  3. const Wrapper = styled.section...: Similarly, we create a Wrapper component that renders a <section> with its own specific styles.
  4. <Wrapper> and <Title>: We can now use these variables as if they were regular React components. The library handles creating the elements and applying the styles with unique, generated class names under the hood.

🛠️ Section 3: How It Works

You might be wondering what styled-components is actually doing. At build time and runtime, it:

  1. Takes the CSS you wrote inside the template literal.
  2. Generates a unique CSS class name (e.g., sc-a1b2c3d4-0).
  3. Injects the CSS into the <head> of your document with that unique class name.
  4. Ensures that the component you created (Title, Wrapper) gets that unique class name passed to it.

This process gives you the benefits of both traditional CSS (like caching and performance) and inline styles (scoping and dynamic capabilities) without the major drawbacks of either.


✨ Section 4: Best Practices

  • Define Styled Components Outside the Render Method: Always define your styled components at the top level of your module. If you define them inside the render function of another component, they will be recreated on every render, which will severely impact performance and break caching.
  • Give Them Descriptive Names: Name your styled components clearly (e.g., PageWrapper, SubmitButton, ErrorMessage). This makes your JSX more readable than a div with a className.
  • Start Simple: Don't feel the need to make every single element a styled component. Start by styling the main "blocks" of your UI and add more granular styled components as needed.

💡 Conclusion & Key Takeaways

CSS-in-JS, and specifically styled-components, offers a fundamentally different way to approach styling in React. By tying styles directly to components, you create a more modular, maintainable, and less error-prone system.

Let's summarize the key takeaways:

  • CSS-in-JS writes CSS in JavaScript: This pattern brings the full power of JavaScript to your styling workflow.
  • styled-components creates React components: When you define a style, you are actually creating a new component with those styles attached.
  • Tagged Template Literals are the Syntax: The styled.h1... syntax is how you define the styles for your component.
  • Automatic Scoping: You get locally scoped styles for free, eliminating any concern about class name collisions.

Challenge Yourself: Create a Card component using styled-components. It should be a div with a border, border-radius, padding, and a box-shadow. Inside the card, create a styled h3 for a title and a styled p for the body text.


➡️ Next Steps

You've just scratched the surface of what's possible with CSS-in-JS. In the next article, "Introduction to CSS-in-JS (Part 2): Creating and styling components with styled-components", we will explore how to make these components dynamic by adapting their styles based on props.

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


glossary

  • CSS-in-JS: A styling paradigm where CSS is written inside JavaScript files, often co-located with the component logic.
  • styled-components: A popular CSS-in-JS library for React and React Native that uses tagged template literals to create styled components.
  • Tagged Template Literal: An advanced feature of JavaScript that allows you to parse template literals with a function. styled-components uses this to read your CSS and create a component.

Further Reading