Tailwind Custom Config

Tailwind comes with a default set of colors, font sizes, spacing, and breakpoints. Custom configuration lets you change those defaults or add new ones to match your brand. Everything lives in one file: tailwind.config.js.

The Config File

When you set up Tailwind, a config file is generated with this structure:

// tailwind.config.js
module.exports = {
  content: ['./src/**/*.{html,js,jsx,ts,tsx}'],
  theme: {
    extend: {},
  },
  plugins: [],
};

Each Key Explained

  • content — tells Tailwind which files to scan so unused classes get removed
  • theme — where you customize or add design values
  • theme.extend — adds new values without removing Tailwind's built-in defaults
  • plugins — adds extra functionality through official or third-party plugins

extend vs Override

This is the most important concept in Tailwind config. Understand this and everything else becomes simple.

// OVERRIDE — replaces all built-in colors with only red and blue
theme: {
  colors: {
    red: '#ef4444',
    blue: '#3b82f6',
  }
}

// EXTEND — keeps all built-in colors AND adds your custom brand color
theme: {
  extend: {
    colors: {
      brand: '#7c3aed',
    }
  }
}

Diagram: extend vs Override

Built-in Tailwind Colors:
[gray] [red] [blue] [green] [yellow] [purple] ... (100+ values)

After OVERRIDE with only red and blue:
[red] [blue]   ← all others gone!

After EXTEND with brand:
[gray] [red] [blue] [green] [yellow] [purple] ... [brand]
                                                      ↑ your new color added

Use extend almost always. Use direct override only if you want to completely replace a section of Tailwind's design system.

Custom Colors

Add your brand's colors so you can use them like any other Tailwind color.

theme: {
  extend: {
    colors: {
      brand: {
        50:  '#eff6ff',
        100: '#dbeafe',
        500: '#3b82f6',
        700: '#1d4ed8',
        900: '#1e3a8a',
      },
      tomato: '#ff6347',
    }
  }
}

Now you can write classes like bg-brand-500, text-brand-700, or bg-tomato directly in your HTML.

<button class="bg-brand-500 hover:bg-brand-700 text-white px-4 py-2 rounded">
  Brand Button
</button>

<p class="text-tomato font-semibold">Alert message</p>

Custom Font Family

Add a custom font family to use in your classes.

theme: {
  extend: {
    fontFamily: {
      sans: ['Inter', 'ui-sans-serif', 'system-ui'],
      heading: ['Poppins', 'sans-serif'],
      mono: ['Fira Code', 'monospace'],
    }
  }
}
<h1 class="font-heading text-3xl font-bold">Page Title</h1>
<p class="font-sans text-base">Body paragraph text here.</p>
<code class="font-mono text-sm">const x = 42;</code>

Custom Spacing

Tailwind spacing goes from 0 to 96 by default. Add values outside that range when needed.

theme: {
  extend: {
    spacing: {
      '128': '32rem',
      '144': '36rem',
      '18': '4.5rem',
    }
  }
}
<div class="w-128 h-128 bg-gray-200">Large Box</div>
<div class="mt-18">Custom top margin</div>

Custom Font Size

theme: {
  extend: {
    fontSize: {
      'xxs': '0.625rem',     // 10px
      '2xl-plus': '1.75rem', // 28px
      'display': ['4.5rem', { lineHeight: '1.1' }],
    }
  }
}
<p class="text-xxs text-gray-400">Fine print text</p>
<h1 class="text-display font-black">Hero Heading</h1>

Custom Border Radius

theme: {
  extend: {
    borderRadius: {
      '4xl': '2rem',
      'pill': '9999px',
    }
  }
}
<div class="rounded-4xl bg-blue-100 p-6">Rounded card</div>
<span class="rounded-pill bg-green-500 text-white px-4 py-1">Badge</span>

Custom Breakpoints

Tailwind's default breakpoints: sm (640px), md (768px), lg (1024px), xl (1280px), 2xl (1536px). Add your own when a project needs different screen sizes.

theme: {
  extend: {
    screens: {
      'xs': '480px',       // custom small
      '3xl': '1800px',     // custom very large
      'tablet': '960px',   // custom named breakpoint
    }
  }
}
<div class="text-sm xs:text-base tablet:text-lg 3xl:text-xl">
  Responsive text at custom breakpoints
</div>

Custom Box Shadow

theme: {
  extend: {
    boxShadow: {
      'soft': '0 2px 20px rgba(0,0,0,0.08)',
      'hard': '4px 4px 0px #000',
      'glow': '0 0 15px rgba(99, 102, 241, 0.5)',
    }
  }
}
<div class="shadow-soft rounded-xl bg-white p-6">Soft card</div>
<div class="shadow-glow rounded-lg bg-indigo-600 text-white px-6 py-3">Glow button</div>

Custom Animation and Keyframes

theme: {
  extend: {
    keyframes: {
      wiggle: {
        '0%, 100%': { transform: 'rotate(-5deg)' },
        '50%':      { transform: 'rotate(5deg)' },
      },
      fadeIn: {
        '0%':   { opacity: '0' },
        '100%': { opacity: '1' },
      }
    },
    animation: {
      wiggle: 'wiggle 0.5s ease-in-out infinite',
      fadeIn: 'fadeIn 0.3s ease-in',
    }
  }
}
<div class="animate-wiggle text-3xl">🔔</div>
<div class="animate-fadeIn">This fades in on load</div>

Full Example Config

// tailwind.config.js
module.exports = {
  darkMode: 'class',
  content: ['./src/**/*.{html,js,jsx,ts,tsx}'],
  theme: {
    extend: {
      colors: {
        brand: {
          500: '#7c3aed',
          700: '#5b21b6',
        },
      },
      fontFamily: {
        sans: ['Inter', 'sans-serif'],
      },
      spacing: {
        '128': '32rem',
      },
      screens: {
        'xs': '480px',
      },
      borderRadius: {
        'pill': '9999px',
      },
      animation: {
        fadeIn: 'fadeIn 0.3s ease-in',
      },
      keyframes: {
        fadeIn: {
          '0%': { opacity: '0' },
          '100%': { opacity: '1' },
        }
      }
    },
  },
  plugins: [],
};

Config Changes Take Effect After Rebuild

After editing tailwind.config.js, save the file. If you run Tailwind with a watch command, it rebuilds automatically. New classes are available right after the rebuild.

npx tailwindcss -i ./src/input.css -o ./dist/output.css --watch

Key Points

  • Use theme.extend to add custom values while keeping all Tailwind defaults
  • Use direct theme keys (without extend) only when you want to fully replace a category
  • Custom colors, fonts, spacing, and breakpoints all follow the same pattern
  • Custom animations require both keyframes and animation entries
  • Rebuild your CSS after every config change

Leave a Comment