Tailwind CSS
03 / 03

Responsive, Dark Mode & Config

Responsive, Dark Mode & Config

Responsive Breakpoints

  • sm — 640px+

  • md — 768px+

  • lg — 1024px+

  • xl — 1280px+

  • 2xl — 1536px+

<!-- Mobile-first: base = mobile, add breakpoints for larger screens -->
<div class="text-sm md:text-base lg:text-lg">
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4">
<div class="hidden md:block">         <!-- hidden on mobile, visible md+ -->
<div class="block md:hidden">         <!-- visible on mobile, hidden md+ -->
<div class="p-4 md:p-8 lg:p-12">

<!-- Max-breakpoint modifier (Tailwind v3.2+) -->
<div class="md:max-lg:hidden">        <!-- hidden between md and lg -->

<!-- Container with responsive padding -->
<div class="container mx-auto px-4 sm:px-6 lg:px-8">

State Variants

<!-- Hover / Focus / Active -->
<button class="bg-blue-500 hover:bg-blue-600 active:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2">

<!-- Group hover (parent hover affects children) -->
<div class="group">
  <div class="bg-white group-hover:bg-blue-500">  <!-- changes on parent hover -->
  <p class="text-gray-600 group-hover:text-white">

<!-- Peer (sibling state) -->
<input class="peer" type="checkbox" />
<label class="peer-checked:text-blue-500">

<!-- Disabled -->
<button class="disabled:opacity-50 disabled:cursor-not-allowed">

<!-- Form states -->
<input class="border border-gray-300 focus:border-blue-500 focus:ring-1 focus:ring-blue-500 invalid:border-red-500">

<!-- First/last child -->
<li class="py-2 border-b last:border-b-0">
<li class="py-2 border-t first:border-t-0">

<!-- Odd/even rows -->
<tr class="odd:bg-white even:bg-gray-50">

Dark Mode

<!-- Dark mode classes -->
<div class="bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100">
<div class="border-gray-200 dark:border-gray-700">
<button class="bg-blue-500 dark:bg-blue-600 hover:bg-blue-600 dark:hover:bg-blue-700">
// tailwind.config.js — class-based dark mode (manual toggle)
module.exports = {
  darkMode: 'class',   // toggle by adding 'dark' class to <html>
  // darkMode: 'media', // follows OS preference
}

// Toggle dark mode
document.documentElement.classList.toggle('dark');

Customization (tailwind.config.js)

// tailwind.config.ts
import type { Config } from 'tailwindcss';

export default {
  content: ['./src/**/*.{js,ts,jsx,tsx,mdx}'],
  darkMode: 'class',
  theme: {
    // Override — replaces defaults entirely
    fontFamily: {
      sans: ['Inter', 'system-ui', 'sans-serif'],
    },
    extend: {
      // Extend — adds to defaults
      colors: {
        brand: {
          50: '#eff6ff',
          500: '#3b82f6',
          900: '#1e3a8a',
        },
      },
      spacing: {
        '18': '4.5rem',
        '128': '32rem',
      },
      borderRadius: {
        '4xl': '2rem',
      },
      animation: {
        'fade-in': 'fadeIn 0.2s ease-in-out',
      },
      keyframes: {
        fadeIn: {
          '0%': { opacity: '0' },
          '100%': { opacity: '1' },
        },
      },
      screens: {
        'xs': '475px',  // add custom breakpoint
      },
    },
  },
  plugins: [
    require('@tailwindcss/typography'),   // prose classes
    require('@tailwindcss/forms'),         // form reset
    require('@tailwindcss/line-clamp'),    // line-clamp (v3 built-in)
  ],
} satisfies Config;

Common Patterns

<!-- Card -->
<div class="rounded-xl border border-gray-200 bg-white p-6 shadow-sm dark:border-gray-700 dark:bg-gray-800">

<!-- Badge -->
<span class="inline-flex items-center rounded-full bg-blue-100 px-2.5 py-0.5 text-xs font-medium text-blue-800">

<!-- Button -->
<button class="inline-flex items-center gap-2 rounded-lg bg-blue-600 px-4 py-2 text-sm font-semibold text-white shadow-sm hover:bg-blue-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600 disabled:opacity-50">

<!-- Input -->
<input class="block w-full rounded-md border border-gray-300 px-3 py-2 text-sm placeholder-gray-400 shadow-sm focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700">

<!-- Divider -->
<div class="relative">
  <div class="absolute inset-0 flex items-center"><span class="w-full border-t"></span></div>
  <div class="relative flex justify-center text-sm"><span class="bg-white px-2 text-gray-500">or</span></div>
</div>

Keep your own version of these notes — editable, searchable, and organised by your stack.

Start free