Every utility in Tailwind can be applied conditionally at different breakpoints. By default, unprefixed utilities apply to all screen sizes, while prefixed utilities only apply at the specified breakpoint and above.
<!-- Width of 16 on mobile, 32 on medium screens and up, 48 on large screens and up --><div class="w-16 md:w-32 lg:w-48"> <!-- Content --></div>
This means you typically design for mobile first, then layer on changes for larger screens:
<!-- Stack vertically on mobile, horizontal on medium screens --><div class="flex flex-col md:flex-row"> <div class="w-full md:w-1/2">Content 1</div> <div class="w-full md:w-1/2">Content 2</div></div>
<!-- Small text on mobile, larger on desktop --><h1 class="text-2xl md:text-4xl lg:text-5xl font-bold"> Responsive Heading</h1><p class="text-sm md:text-base lg:text-lg leading-relaxed"> Responsive body text with adjusted line height.</p>
<!-- Hide on mobile, show on desktop --><div class="hidden lg:block"> Desktop-only sidebar</div><!-- Show on mobile, hide on desktop --><button class="block lg:hidden"> Mobile menu toggle</button>
While mobile-first is recommended, you can also use max variants to target smaller screens:
<!-- Apply styles only below the md breakpoint --><div class="max-md:flex-col"> <!-- This is display: flex with flex-direction: column on screens smaller than 768px --></div>
The max variant generates media queries using width <:
variants.functional( 'max', (ruleNode, variant) => { if (variant.modifier) return null let value = resolvedBreakpoints.get(variant) if (value === null) return null ruleNode.nodes = [atRule('@media', `(width < ${value})`, ruleNode.nodes)] }, { compounds: Compounds.AtRules },)
Use max-* variants sparingly. They can create confusing overrides and make your CSS harder to maintain. Stick with mobile-first (min-* or unprefixed) whenever possible.
Breakpoints can be combined with other variants like hover, focus, and dark mode:
<!-- Hover effect only on desktop --><button class="lg:hover:scale-105 transition"> Hover me on desktop</button><!-- Different dark mode colors per breakpoint --><div class="bg-white dark:bg-gray-900 md:dark:bg-gray-800"> Content</div><!-- Focus styles per breakpoint --><input class="focus:ring-2 md:focus:ring-4" />
Tailwind also supports container queries using the @ variant:
<!-- Apply styles based on container width, not viewport --><div class="@container"> <div class="@lg:flex"> <!-- This flexes when the container (not viewport) is large --> </div></div>
Container queries use named containers with modifiers:
<div class="@container/main"> <div class="@lg/main:flex"> <!-- Styles apply based on the 'main' container's width --> </div></div>
From the source, container queries work similarly to regular breakpoints: