Claude
Skills
Sign in
Back

tailwindcss-responsive-darkmode

Included with Lifetime
$97 forever

Tailwind CSS responsive design and dark mode patterns (2025-2026). PROACTIVELY activate for: (1) dark mode setup (class-based vs media-query, dark: variant), (2) toggling dark mode at runtime (data-theme, html.dark), (3) prefers-color-scheme handling, (4) per-component dark variants, (5) responsive design with dark mode (combining sm:dark:bg-*), (6) system / light / dark / high-contrast theming, (7) CSS color-scheme property, (8) avoiding flash of unstyled content (FOUC) in dark mode, (9) dark-mode color tokens via @theme. Provides: dark-mode toggle implementation, FOUC prevention pattern, color-token templates, and system-preference detection.

Design

What this skill does


# Tailwind CSS Responsive Design & Dark Mode (2025/2026)

## Responsive Design

### Mobile-First Approach (Industry Standard 2025/2026)

Tailwind uses a mobile-first breakpoint system. With over 60% of global web traffic from mobile devices and Google's mobile-first indexing, this approach is essential.

**Key Principle**: Unprefixed utilities apply to ALL screen sizes. Breakpoint prefixes apply at that size AND ABOVE.

```html
<!-- CORRECT: Mobile-first (progressive enhancement) -->
<div class="text-sm md:text-base lg:text-lg">...</div>

<!-- INCORRECT: Desktop-first thinking -->
<div class="lg:text-lg md:text-base text-sm">...</div>
```

### Default Breakpoints

| Prefix | Min Width | Typical Devices | CSS Media Query |
|--------|-----------|-----------------|-----------------|
| (none) | 0px | All mobile phones | All sizes |
| `sm:` | 640px (40rem) | Large phones, small tablets | `@media (min-width: 640px)` |
| `md:` | 768px (48rem) | Tablets (portrait) | `@media (min-width: 768px)` |
| `lg:` | 1024px (64rem) | Tablets (landscape), laptops | `@media (min-width: 1024px)` |
| `xl:` | 1280px (80rem) | Desktops | `@media (min-width: 1280px)` |
| `2xl:` | 1536px (96rem) | Large desktops | `@media (min-width: 1536px)` |

### 2025/2026 Device Coverage

Common device sizes to test:
- **320px**: Older iPhones, smallest supported
- **375px**: Modern iPhone base (~17% of mobile)
- **390-430px**: Modern large phones (~35% of mobile)
- **768px**: iPad portrait
- **1024px**: iPad landscape, laptops
- **1280px**: Standard laptops/desktops
- **1440px**: Large desktops
- **1920px**: Full HD displays

### Custom Breakpoints

```css
@theme {
  /* Add custom breakpoints for specific content needs */
  --breakpoint-xs: 20rem;   /* 320px - very small devices */
  --breakpoint-3xl: 100rem; /* 1600px */
  --breakpoint-4xl: 120rem; /* 1920px - full HD */

  /* Override existing breakpoints based on YOUR content */
  --breakpoint-sm: 36rem;   /* 576px - when content needs space */
  --breakpoint-lg: 62rem;   /* 992px - common content width */
}
```

Usage:
```html
<div class="grid xs:grid-cols-2 3xl:grid-cols-6">
  <!-- Custom breakpoints work like built-in ones -->
</div>
```

### Content-Driven Breakpoints (2025 Best Practice)

Instead of targeting devices, let your content determine breakpoints:

```css
@theme {
  /* Based on content needs, not device specs */
  --breakpoint-prose: 65ch;  /* Optimal reading width */
  --breakpoint-content: 75rem; /* Main content max */
}
```

Test your design at various widths and add breakpoints where layout breaks.

### Responsive Examples

#### Responsive Grid

```html
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4">
  <div>Item 1</div>
  <div>Item 2</div>
  <div>Item 3</div>
  <div>Item 4</div>
</div>
```

#### Responsive Typography

```html
<h1 class="text-2xl sm:text-3xl md:text-4xl lg:text-5xl font-bold">
  Responsive Heading
</h1>

<p class="text-sm md:text-base lg:text-lg leading-relaxed">
  Responsive paragraph text
</p>
```

#### Responsive Spacing

```html
<section class="py-8 md:py-12 lg:py-16 px-4 md:px-8 lg:px-12">
  <div class="max-w-4xl mx-auto">
    Content with responsive padding
  </div>
</section>
```

#### Responsive Navigation

```html
<nav class="flex flex-col md:flex-row items-center justify-between">
  <div class="hidden md:flex gap-4">
    <!-- Desktop navigation -->
  </div>
  <button class="md:hidden">
    <!-- Mobile menu button -->
  </button>
</nav>
```

#### Show/Hide Based on Screen Size

```html
<!-- Hidden on mobile, visible on desktop -->
<div class="hidden md:block">Desktop only</div>

<!-- Visible on mobile, hidden on desktop -->
<div class="block md:hidden">Mobile only</div>

<!-- Different content per breakpoint -->
<span class="sm:hidden">XS</span>
<span class="hidden sm:inline md:hidden">SM</span>
<span class="hidden md:inline lg:hidden">MD</span>
<span class="hidden lg:inline xl:hidden">LG</span>
<span class="hidden xl:inline 2xl:hidden">XL</span>
<span class="hidden 2xl:inline">2XL</span>
```

### Container Queries (v4) - 2025 Game-Changer

Container queries enable component-level responsiveness, independent of viewport size. This is essential for reusable components in 2025.

```css
@plugin "@tailwindcss/container-queries";
```

```html
<!-- Mark parent as a query container -->
<div class="@container">
  <div class="flex flex-col @md:flex-row @lg:gap-8">
    <!-- Responds to container size, not viewport -->
  </div>
</div>

<!-- Named containers for multiple contexts -->
<div class="@container/card">
  <div class="@lg/card:grid-cols-2 grid grid-cols-1">
    <!-- Responds specifically to 'card' container -->
  </div>
</div>
```

### Container Query Breakpoints

| Class | Min-width | Use Case |
|-------|-----------|----------|
| `@xs` | 20rem (320px) | Small widgets |
| `@sm` | 24rem (384px) | Compact cards |
| `@md` | 28rem (448px) | Standard cards |
| `@lg` | 32rem (512px) | Wide cards |
| `@xl` | 36rem (576px) | Full-width components |
| `@2xl` | 42rem (672px) | Large containers |
| `@3xl` | 48rem (768px) | Page sections |

### When to Use Container vs Viewport Queries

| Container Queries | Viewport Queries |
|-------------------|------------------|
| Reusable components | Page-level layouts |
| Cards in various contexts | Navigation bars |
| Sidebar widgets | Hero sections |
| CMS/embedded content | Full-width sections |

### Max-Width Breakpoints

Target screens below a certain size:

```html
<!-- Only on screens smaller than md (< 768px) -->
<div class="md:hidden">Small screens only</div>

<!-- Custom max-width media query -->
<div class="[@media(max-width:600px)]:text-sm">
  Custom max-width
</div>
```

## Dark Mode

### Strategy: Media (Default)

Dark mode follows the user's operating system preference using `prefers-color-scheme`:

```css
@import "tailwindcss";
/* No additional configuration needed */
```

```html
<div class="bg-white dark:bg-gray-900">
  <h1 class="text-gray-900 dark:text-white">Title</h1>
  <p class="text-gray-600 dark:text-gray-300">Content</p>
</div>
```

### Strategy: Selector (Manual Toggle)

Control dark mode with a CSS class:

```css
@import "tailwindcss";

@custom-variant dark (&:where(.dark, .dark *));
```

```html
<!-- Add .dark class to html or body to enable dark mode -->
<html class="dark">
  <body>
    <div class="bg-white dark:bg-gray-900">
      Content
    </div>
  </body>
</html>
```

### JavaScript Toggle

```javascript
// Simple toggle
function toggleDarkMode() {
  document.documentElement.classList.toggle('dark');
}

// With localStorage persistence
function initDarkMode() {
  const isDark = localStorage.getItem('darkMode') === 'true' ||
    (!localStorage.getItem('darkMode') &&
     window.matchMedia('(prefers-color-scheme: dark)').matches);

  document.documentElement.classList.toggle('dark', isDark);
}

function toggleDarkMode() {
  const isDark = document.documentElement.classList.toggle('dark');
  localStorage.setItem('darkMode', isDark);
}

// Initialize on page load
initDarkMode();
```

### Three-Way Toggle (Light/Dark/System)

```javascript
const themes = ['light', 'dark', 'system'];

function setTheme(theme) {
  localStorage.setItem('theme', theme);
  applyTheme();
}

function applyTheme() {
  const theme = localStorage.getItem('theme') || 'system';
  const isDark = theme === 'dark' ||
    (theme === 'system' && window.matchMedia('(prefers-color-scheme: dark)').matches);

  document.documentElement.classList.toggle('dark', isDark);
}

// Listen for system preference changes
window.matchMedia('(prefers-color-scheme: dark)')
  .addEventListener('change', () => {
    if (localStorage.getItem('theme') === 'system') {
      applyTheme();
    }
  });

applyTheme();
```

### Data Attribute Strategy

```css
@custom-variant dark (&:where([data-theme="dark"], [data-theme="dark"] *));
```

```html
<html data-theme="dark">
  <body>
    <div class="bg-white dark:bg-gray-900">Content</div>
  </body>
</html>
```

##

Related in Design