React CSS-in-JS

Writing CSS directly in JavaScript components

💅 What is CSS-in-JS?

CSS-in-JS lets you write CSS styles directly in your JavaScript files using libraries like styled-components. This approach combines styling with component logic for better maintainability and dynamic styling capabilities.


const Button = styled.button`color: blue;`;
                                    

Understanding CSS-in-JS

CSS-in-JS is a styling approach where you write CSS styles using JavaScript. Popular libraries like styled-components and Emotion allow you to create styled React components with full access to props and state. This method provides powerful dynamic styling, automatic vendor prefixing, and eliminates unused styles.

🎨

Dynamic Styling

Styles based on props and state

🔧

Component-Based

Styles tied to components

âš¡

No Class Names

Automatic unique identifiers

📦

Scoped Styles

No global style conflicts

🔹 Styled Components Basics

Create styled components using template literals:

import styled from 'styled-components';

// Create a styled button component
const Button = styled.button`
  background-color: #007bff;
  color: white;
  padding: 12px 24px;
  border: none;
  border-radius: 6px;
  font-size: 16px;
  cursor: pointer;
  transition: background-color 0.3s;

  &:hover {
    background-color: #0056b3;
  }
`;

// Use it like a regular component
function App() {
  return (
    <div>
      <Button>Click Me</Button>
    </div>
  );
}

Output:

🔹 Props-Based Styling

Use props to create dynamic styles:

import styled from 'styled-components';

const Button = styled.button`
  padding: 10px 20px;
  border: none;
  border-radius: 5px;
  font-size: 16px;
  cursor: pointer;
  background-color: ${props => props.primary ? '#007bff' : '#6c757d'};
  color: white;
  opacity: ${props => props.disabled ? 0.6 : 1};
  
  &:hover {
    background-color: ${props => props.primary ? '#0056b3' : '#545b62'};
  }
`;

// Usage
function App() {
  return (
    <div>
      <Button primary>Primary Button</Button>
      <Button>Secondary Button</Button>
      <Button primary disabled>Disabled Button</Button>
    </div>
  );
}

Output:

🔹 Extending Styles

Create variations by extending existing styled components:

import styled from 'styled-components';

const Button = styled.button`
  padding: 10px 20px;
  border: none;
  border-radius: 5px;
  cursor: pointer;
  font-size: 16px;
`;

const PrimaryButton = styled(Button)`
  background-color: #007bff;
  color: white;
`;

const OutlineButton = styled(Button)`
  background-color: transparent;
  color: #007bff;
  border: 2px solid #007bff;
`;

const DangerButton = styled(Button)`
  background-color: #dc3545;
  color: white;
`;

// Usage
<PrimaryButton>Primary</PrimaryButton>
<OutlineButton>Outline</OutlineButton>
<DangerButton>Danger</DangerButton>

Output:

🔹 Theming

Create consistent themes across your application:

import styled, { ThemeProvider } from 'styled-components';

const theme = {
  colors: {
    primary: '#007bff',
    secondary: '#6c757d',
    success: '#28a745',
    danger: '#dc3545'
  },
  spacing: {
    small: '8px',
    medium: '16px',
    large: '24px'
  }
};

const ThemedButton = styled.button`
  background-color: ${props => props.theme.colors.primary};
  padding: ${props => props.theme.spacing.medium};
  color: white;
  border: none;
  border-radius: 5px;
  cursor: pointer;
`;

function App() {
  return (
    <ThemeProvider theme={theme}>
      <ThemedButton>Themed Button</ThemedButton>
    </ThemeProvider>
  );
}

🔹 Nested Styles

Write nested styles like in Sass:

import styled from 'styled-components';

const Card = styled.div`
  background: white;
  border-radius: 8px;
  padding: 20px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.1);

  h3 {
    color: #333;
    margin-bottom: 10px;
    font-size: 20px;
  }

  p {
    color: #666;
    line-height: 1.6;
  }

  button {
    margin-top: 15px;
    padding: 8px 16px;
    background: #007bff;
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;

    &:hover {
      background: #0056b3;
    }
  }
`;

// Usage
<Card>
  <h3>Card Title</h3>
  <p>Card content goes here</p>
  <button>Action</button>
</Card>

🔹 Global Styles

Define global styles for your entire application:

import { createGlobalStyle } from 'styled-components';

const GlobalStyle = createGlobalStyle`
  * {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
  }

  body {
    font-family: 'Arial', sans-serif;
    background-color: #f5f5f5;
    color: #333;
  }

  h1, h2, h3 {
    color: #222;
  }
`;

function App() {
  return (
    <>
      <GlobalStyle />
      <div>Your app content</div>
    </>
  );
}

CSS-in-JS Benefits:

  • Dynamic styling: Use JavaScript logic in styles
  • Component-scoped: Styles automatically scoped to components
  • No class name bugs: Unique class names generated automatically
  • Better DX: Autocomplete and type checking for styles
  • Dead code elimination: Unused styles are removed

🧠 Test Your Knowledge

What is the main advantage of CSS-in-JS?