SyntaxStudy
Sign Up
Tailwind CSS Adding Custom Utilities and Components in CSS Layers
Tailwind CSS Beginner 1 min read

Adding Custom Utilities and Components in CSS Layers

Tailwind organises its CSS into three layers: base (normalise and element styles), components (reusable class patterns), and utilities (single-purpose utility classes). You can inject custom CSS into each layer using the @layer directive, which ensures your additions cascade correctly and can be overridden in the expected way. Styles in @layer utilities benefit from all Tailwind variant support — hover, responsive, dark, and others — just like built-in utilities. Adding styles to @layer base is appropriate for opinionated base element styles: custom focus-visible rings, default link colours, custom scrollbar styling, and body typography defaults. @layer components holds your extracted component classes from @apply — keeping them here ensures that utility classes still override them as expected. @layer utilities is for bespoke utility classes you want available project-wide with full variant support. Using CSS custom properties (variables) in combination with @layer base is a powerful pattern for dynamic theming. Define your brand colors as CSS variables on :root and dark: on .dark, then reference them in @layer utilities as bg-[var(--color-brand)] or in tailwind.config.js using the theme extension. This approach enables seamless runtime theme switching without recompiling the CSS.
Example
/* ── src/styles/globals.css ───────────────────────── */

@tailwind base;
@tailwind components;
@tailwind utilities;

/* Custom base layer: design token variables + element defaults */
@layer base {
  :root {
    --color-primary:     #4f6ef7;
    --color-primary-hover: #3a52e8;
    --color-surface:     #ffffff;
    --color-text:        #111827;
  }

  .dark {
    --color-primary:     #6d8dfc;
    --color-primary-hover: #93adfd;
    --color-surface:     #1f2937;
    --color-text:        #f9fafb;
  }

  body {
    @apply text-gray-900 dark:text-gray-100 bg-white dark:bg-gray-950;
    font-feature-settings: 'rlig' 1, 'calt' 1;
  }

  h1, h2, h3, h4 {
    @apply font-bold tracking-tight;
  }

  a:focus-visible {
    @apply outline-none ring-2 ring-blue-500 ring-offset-2;
  }
}

/* Custom component layer */
@layer components {
  .page-container {
    @apply max-w-7xl mx-auto px-4 sm:px-6 lg:px-8;
  }

  .section-heading {
    @apply text-3xl font-extrabold tracking-tight text-gray-900 dark:text-white;
  }
}

/* Custom utility layer */
@layer utilities {
  .text-balance {
    text-wrap: balance;
  }

  .scrollbar-hide {
    -ms-overflow-style: none;
    scrollbar-width: none;
  }
  .scrollbar-hide::-webkit-scrollbar {
    display: none;
  }

  .gradient-mask-b {
    -webkit-mask-image: linear-gradient(to bottom, black 60%, transparent 100%);
    mask-image: linear-gradient(to bottom, black 60%, transparent 100%);
  }
}