--- name: tailwindcss-responsive-darkmode description: Tailwind CSS responsive design and dark mode implementation patterns for 2025/2026 --- # 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
...
...
``` ### 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
``` ### 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
Item 1
Item 2
Item 3
Item 4
``` #### Responsive Typography ```html

Responsive Heading

Responsive paragraph text

``` #### Responsive Spacing ```html
Content with responsive padding
``` #### Responsive Navigation ```html ``` #### Show/Hide Based on Screen Size ```html
Mobile only
XS ``` ### 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
``` ### 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
Small screens only
Custom max-width
``` ## 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

Title

Content

``` ### Strategy: Selector (Manual Toggle) Control dark mode with a CSS class: ```css @import "tailwindcss"; @custom-variant dark (&:where(.dark, .dark *)); ``` ```html
Content
``` ### 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
Content
``` ### Dark Mode with Next.js (next-themes) ```bash npm install next-themes ``` ```jsx // app/providers.tsx 'use client'; import { ThemeProvider } from 'next-themes'; export function Providers({ children }) { return ( {children} ); } ``` ```jsx // app/layout.tsx import { Providers } from './providers'; export default function RootLayout({ children }) { return ( {children} ); } ``` ```jsx // components/ThemeToggle.tsx 'use client'; import { useTheme } from 'next-themes'; export function ThemeToggle() { const { theme, setTheme } = useTheme(); return ( ); } ``` ### Dark Mode Color Palette ```html

Primary text

Secondary text

Muted text

Page background
Card background
Elevated background
Bordered element
``` ### Dark Mode with CSS Variables ```css @theme { /* Light mode colors (default) */ --color-bg-primary: oklch(1 0 0); --color-bg-secondary: oklch(0.98 0 0); --color-text-primary: oklch(0.15 0 0); --color-text-secondary: oklch(0.4 0 0); } /* Dark mode overrides */ @media (prefers-color-scheme: dark) { :root { --color-bg-primary: oklch(0.15 0 0); --color-bg-secondary: oklch(0.2 0 0); --color-text-primary: oklch(0.95 0 0); --color-text-secondary: oklch(0.7 0 0); } } ``` ```html
Semantic colors
``` ### Typography Plugin Dark Mode ```html
``` ## Combining Responsive and Dark Mode ```html
``` ## Best Practices (2025/2026) ### 1. Start Mobile, Then Enhance ```html
``` ### 2. Touch-Friendly Interactive Elements WCAG 2.2 requires 24x24px minimum, but 44x44px is recommended: ```html Navigation Item
``` ### 3. Fluid Typography (Eliminates Breakpoint Jumps) ```css @theme { --text-fluid-base: clamp(1rem, 0.9rem + 0.5vw, 1.25rem); --text-fluid-lg: clamp(1.25rem, 1rem + 1.25vw, 2rem); --text-fluid-xl: clamp(1.5rem, 1rem + 2.5vw, 3rem); } ``` ```html

Smoothly Scaling Heading

Smoothly scaling body text.

``` ### 2. Use Semantic Dark Mode Colors ```css @theme { /* Instead of raw colors, use semantic names */ --color-surface: oklch(1 0 0); --color-surface-dark: oklch(0.15 0 0); --color-on-surface: oklch(0.1 0 0); --color-on-surface-dark: oklch(0.95 0 0); } ``` ### 3. Test All Breakpoints Use the debug-screens plugin during development: ```bash npm install -D @tailwindcss/debug-screens ``` ```css @plugin "@tailwindcss/debug-screens"; ``` ### 4. Reduce Repetition with Components ```css /* components.css */ @layer components { .card { @apply bg-white dark:bg-gray-800 rounded-lg p-6 shadow-sm; } .section { @apply py-12 md:py-16 lg:py-24; } } ``` ### 5. Consider Color Contrast Ensure sufficient contrast in both light and dark modes (WCAG 2.2): - **Normal text**: 4.5:1 contrast ratio minimum - **Large text (18pt+)**: 3:1 contrast ratio minimum - **Interactive elements**: 3:1 against adjacent colors ```html ``` ### 6. Reduced Motion Preference Respect users who prefer reduced motion: ```html
Respects motion preferences
``` ### 7. Performance-Optimized Responsive Images ```html Description Responsive image ``` ### 8. Safe Area Handling (Notched Devices) ```css @utility safe-area-pb { padding-bottom: env(safe-area-inset-bottom); } ``` ```html ```