Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Global CSS and CSS modules

Next.js has two main ways to write plain CSS. Global styles apply to the whole site: fonts, colours, body spacing. CSS modules belong to one component: their class names are made unique automatically, so .title in one component will not break .title in another.

Global styles

The app/globals.css file already exists and is imported in the root layout with import './globals.css'. Add some base rules to it:

/* app/globals.css */
body {
  max-width: 720px;
  margin: 0 auto;
  padding: 16px;
  line-height: 1.6;
}
 
a {
  color: #2563eb;
}

Reload any page: the text forms a centred column and links turn blue.

A CSS module

A module file name ends with .module.css and sits next to the component. Let us make a post card. Create components/PostCard.module.css:

/* components/PostCard.module.css */
.card {
  border: 1px solid #e5e7eb;
  border-radius: 8px;
  padding: 16px;
  margin-bottom: 12px;
}
 
.title {
  margin: 0 0 8px;
}

And the component itself, components/PostCard.tsx:

// components/PostCard.tsx
import Link from 'next/link';
import styles from './PostCard.module.css';
 
export default function PostCard({ slug, title }: { slug: string; title: string }) {
  return (
    <article className={styles.card}>
      <h2 className={styles.title}>
        <Link href={`/posts/${slug}`}>{title}</Link>
      </h2>
    </article>
  );
}

The import returns an object: keys are the class names from the file, values are unique names such as PostCard_card__x7Ab2.

Using the card

// app/posts/page.tsx (fragment)
import PostCard from '@/components/PostCard';
 
{posts.map((post) => (
  <PostCard key={post.slug} slug={post.slug} title={post.title} />
))}

On /posts every post sits in a frame with rounded corners.

When to use what

ApproachGood for
app/globals.cssResets, fonts, colours, the body, a, h1 tags
*.module.cssStyling a specific component
Tailwind CSSStyles as classes right in the markup — next lesson

Several module classes are combined with a template string: className={`${styles.card} ${styles.active}`}.

Common mistake

Importing a plain .css file, not a module, from a component and writing classes like .title in it. Such styles are global: they apply to every element with that class on the site and start to clash. For component styles always use the Name.module.css naming.

Thanks for reading!

Donate to the site — we work hard for you.