R
Rishtaara
Next.js: Zero to Full-Stack
Lesson 9 of 42Article13 min

Sass, CSS-in-JS & Specificity Tips

Next.js supports Sass out of the box after you install the sass package. You can use .scss files globally or as CSS Modules (.module.scss).

Using Sass in Next.js

Next.js supports Sass out of the box after you install the sass package. You can use .scss files globally or as CSS Modules (.module.scss).

Sass gives nested rules, variables, and mixins — helpful when you already know SCSS from older projects.

Real-life example: Sass is a blender for CSS — you put simple ingredients (variables, nesting) in and pour out richer styles without rewriting everything by hand.

Install Sass
npm install sass
components/Panel.module.scss
$border: #e2e8f0;

.panel {
  padding: 1rem;
  border: 1px solid $border;

  .heading {
    margin: 0;
    font-size: 1.125rem;
  }
}
components/Panel.tsx
import styles from "./Panel.module.scss";

export function Panel() {
  return (
    <section className={styles.panel}>
      <h2 className={styles.heading}>Sass module panel</h2>
    </section>
  );
}

CSS-in-JS note for App Router

Many CSS-in-JS libraries need runtime access to the browser. In the App Router, put those styles inside Client Components ("use client") or follow each library's Next.js 15 guide.

Server Components prefer CSS Modules, Tailwind, or Sass without a client-only runtime.

Real-life example: CSS-in-JS that needs the browser is like a lamp that only works with electricity — use it in rooms with power (Client Components), not in a solar-only shed (pure Server Components) unless the library supports it.

Tip: For new Rishtaara projects, Tailwind + CSS Modules cover most needs without CSS-in-JS complexity.
Client component pattern for runtime CSS-in-JS
"use client";

// Example shape — follow your library docs for Next.js 15+
export function StyledBadge({ label }: { label: string }) {
  return (
    <span
      style={{
        display: "inline-block",
        padding: "0.25rem 0.5rem",
        background: "#e0f2fe",
        borderRadius: 6,
      }}
    >
      {label}
    </span>
  );
}

CSS Modules specificity tip

CSS Module classes are unique, but a global CSS rule with higher specificity or !important can still override them. Keep global CSS minimal.

When two module classes fight, prefer composing classes in the component or nesting in Sass/Modules instead of stacking !important.

Real-life example: Specificity is a queue at a ticket window — a VIP pass (!important or a more specific selector) cuts the line. Do not hand out VIP passes unless you must.

  • Prefer one clear class per element from a module
  • Avoid styling tags globally (like button { }) if modules style buttons too
  • Use Tailwind utilities or modules — mixing both on one element is fine if intentional
  • Debug with browser DevTools — see which rule wins and from which file
Compose module classes instead of !important
import styles from "./Alert.module.css";

type Props = { variant?: "info" | "danger" };

export function Alert({ variant = "info" }: Props) {
  const className =
    variant === "danger"
      ? styles.alert + " " + styles.danger
      : styles.alert + " " + styles.info;

  return <div className={className}>Check your Next.js styles</div>;
}