Skip to content

Gatsby Styling — CSS Modules, Global CSS, and CSS-in-JS

DodaTech Updated 2026-06-28 4 min read

Learn how to style Gatsby sites with CSS Modules, global stylesheets, CSS-in-JS libraries like styled-components, and Tailwind CSS for React static sites.

In this lesson, you'll understand the styling options in Gatsby and how to choose the right approach for your project.

What You'll Learn

How to use CSS Modules for component-scoped styles, global CSS for base styles, CSS-in-JS with styled-components, and Gatsby-specific styling considerations.

Why It Matters

Styling approach affects developer experience, bundle size, and maintainability. Gatsby supports multiple styling methods so you can choose what fits your team.

flowchart LR
    A[Styling Options] --> B[CSS Modules]
    A --> C[Global CSS]
    A --> D[CSS-in-JS]
    A --> E[Tailwind CSS]
    B --> F[Component-Scoped]
    C --> G[Base Styles]
    D --> H[Dynamic Styles]
    E --> I[Utility-First]
    style A fill:#639,color:#fff

CSS Modules

Component-scoped CSS that prevents class name collisions:

// src/components/Button.js
import React from 'react';
import * as styles from './Button.module.css';

export default function Button({ children }) {
  return <button className={styles.button}>{children}</button>;
}
/* src/components/Button.module.css */
.button {
  background: #639;
  color: white;
  border: none;
  padding: 8px 16px;
  border-radius: 4px;
  cursor: pointer;
}

.button:hover {
  background: #4a148c;
}

Output: The .button class is hashed to a unique name like Button_button_abc123. Styles don't leak to other components.

Global CSS

Import global stylesheets for base resets and typography:

// gatsby-browser.js
import './src/styles/global.css';
/* src/styles/global.css */
*,
*::before,
*::after {
  box-sizing: border-box;
}

body {
  margin: 0;
  font-family: 'Inter', sans-serif;
  line-height: 1.6;
}

h1, h2, h3 {
  line-height: 1.2;
}

Output: Global styles apply everywhere. Import global.css in gatsby-browser.js to ensure it's included in the build.

CSS-in-JS with styled-components

Dynamic, component-scoped styles with full JavaScript power:

npm install styled-components gatsby-plugin-styled-components
// gatsby-config.js
module.exports = {
  plugins: ['gatsby-plugin-styled-components']
};
// src/components/Card.js
import React from 'react';
import styled from 'styled-components';

const CardWrapper = styled.div`
  border: 1px solid #ddd;
  border-radius: 8px;
  padding: 16px;
  margin: 8px 0;
  box-shadow: ${props => props.elevated ? '0 2px 8px rgba(0,0,0,0.15)' : 'none'};
`;

const Title = styled.h3`
  color: #639;
  margin: 0 0 8px 0;
`;

export default function Card({ title, children, elevated }) {
  return (
    <CardWrapper elevated={elevated}>
      <Title>{title}</Title>
      {children}
    </CardWrapper>
  );
}

Output: The Card component has scoped styles. The elevated prop dynamically changes the box-shadow.

Tailwind CSS

Utility-first CSS with Gatsby:

npm install -D tailwindcss postcss autoprefixer gatsby-plugin-postcss
npx tailwindcss init
// tailwind.config.js
module.exports = {
  content: ['./src/**/*.{js,jsx,ts,tsx}'],
  theme: { extend: {} },
  plugins: []
};
/* src/styles/global.css */
@tailwind base;
@tailwind components;
@tailwind utilities;
// gatsby-config.js
module.exports = {
  plugins: ['gatsby-plugin-postcss']
};
// src/components/Badge.js
import React from 'react';

export default function Badge({ text, variant = 'default' }) {
  const colors = {
    default: 'bg-gray-100 text-gray-800',
    success: 'bg-green-100 text-green-800',
    warning: 'bg-yellow-100 text-yellow-800',
    error: 'bg-red-100 text-red-800'
  };

  return (
    <span className={`inline-block px-2 py-1 rounded text-xs font-medium ${colors[variant]}`}>
      {text}
    </span>
  );
}

Output: Badge uses Tailwind utility classes for styling. No custom CSS needed.

Common Mistakes

  1. Not importing CSS Modules correctly: Use import * as styles from './File.module.css' or import styles from './File.module.css' depending on your setup.
  2. Putting component styles in global CSS: Global CSS should be minimal (resets, typography). Component styles belong in CSS Modules or CSS-in-JS.
  3. Forgetting to install styled-components plugin: Without gatsby-plugin-styled-components, SSR breaks and styles flash on page load.
  4. Not configuring Tailwind's content paths: Tailwind scans your source files for class names. If paths are wrong, classes won't generate.
  5. Using CSS-in-JS for everything: CSS Modules are simpler for static styles. Use CSS-in-JS only when you need dynamic styling based on props.

Practice Questions

  1. What naming convention activates CSS Modules in Gatsby? Answer: Files ending with .module.css are treated as CSS Modules. Regular .css files are global.

  2. How do you add global styles in Gatsby? Answer: Import a CSS file in gatsby-browser.js: import './src/styles/global.css'.

  3. What plugin is required for styled-components SSR? Answer: gatsby-plugin-styled-components. It ensures styles are extracted during the build.

  4. How do you style based on component props? Answer: Use CSS-in-JS (styled-components, emotion) or pass class names conditionally with CSS Modules.

Challenge

Build a component that uses all three styling approaches: a Card with CSS Modules base styles, a Button with styled-components for prop-based variants, and layout utility classes from Tailwind.

Mini Project

Create a blog post template styled with CSS Modules for the article layout, styled-components for dynamic theme colors, and global CSS for base typography and resets.

FAQ

Does Gatsby support Sass/SCSS?

: Yes. Install gatsby-plugin-sass and sass. Use .scss files anywhere in your project.

Can I use CSS Modules with Sass?

: Yes. Name your files Component.module.scss and import them like CSS Modules.

Does CSS-in-JS affect build performance?

: Yes, especially at scale. CSS Modules and Tailwind are faster for large sites. Use CSS-in-JS selectively.

How do I add Google Fonts?

: Install gatsby-plugin-google-fonts or add a <link> tag in the HTML head via gatsby-ssr.js.

What's Next

Learn about Gatsby Static Assets and Images to handle images, fonts, and static files in your Gatsby site.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro