HomeCSS Tailwind
Chapter 3

03 — Responsive Design & Breakpoints

Tailwind Breakpoints

Breakpoint   | Prefix | Min Width | Typical Device
-------------|--------|-----------|----------------
xs           | (none) | 0px       | Small mobile
sm           | sm:    | 640px     | Large mobile
md           | md:    | 768px     | Tablet
lg           | lg:    | 1024px    | Small desktop
xl           | xl:    | 1280px    | Large desktop
2xl          | 2xl:   | 1536px    | Huge screens

Mobile-first approach: Start with base styles, add sm:, md:, etc. for larger screens.


Responsive Examples

Grid Layout

<!-- 1 column mobile, 2 tablet, 4 desktop -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
  <div class="bg-slate-100 p-4">Item 1</div>
  <div class="bg-slate-100 p-4">Item 2</div>
  <div class="bg-slate-100 p-4">Item 3</div>
  <div class="bg-slate-100 p-4">Item 4</div>
</div>

Flexbox

<!-- Stack on mobile, row on desktop -->
<div class="flex flex-col md:flex-row gap-4">
  <div class="flex-1">Sidebar</div>
  <div class="flex-3">Main content</div>
</div>

Spacing

<!-- Small padding mobile, larger on desktop -->
<div class="p-4 md:p-6 lg:p-8">
  Content
</div>
 
<!-- Margin top: 2rem on mobile, 4rem on desktop -->
<div class="mt-8 md:mt-16">
  Section
</div>

Typography

<!-- Text size increases with screen -->
<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">
  Responsive paragraph text
</p>

Container Queries (Modern)

<!-- Component that responds to its container, not viewport -->
<div class="@container">
  <div class="flex flex-col @md:flex-row">
    <div class="@md:w-1/3">Sidebar</div>
    <div class="@md:w-2/3">Content</div>
  </div>
</div>

Note: Container queries need @container class on parent


Common Responsive Patterns

1. Mobile-First Navigation

<!-- Mobile: hamburger menu -->
<!-- Desktop: horizontal nav -->
<nav class="flex flex-col md:flex-row">
  <div class="md:hidden">
    <!-- Mobile menu button -->
    <button></button>
  </div>
  
  <div class="hidden md:flex md:gap-4">
    <a href="/">Home</a>
    <a href="/about">About</a>
    <a href="/contact">Contact</a>
  </div>
</nav>

2. Sidebar Layout

<div class="flex flex-col lg:flex-row min-h-screen">
  <!-- Sidebar: hidden on mobile, shown on desktop -->
  <aside class="hidden lg:block lg:w-64 bg-slate-800 text-white">
    Sidebar
  </aside>
  
  <!-- Main content: full width on mobile -->
  <main class="flex-1 p-4">
    Main content
  </main>
</div>

3. Card Grid

<!-- Auto-fit cards, min 300px wide -->
<div class="grid grid-cols-[repeat(auto-fit,minmax(300px,1fr))] gap-4">
  <div class="bg-white p-6 rounded-lg shadow">Card 1</div>
  <div class="bg-white p-6 rounded-lg shadow">Card 2</div>
  <div class="bg-white p-6 rounded-lg shadow">Card 3</div>
</div>

4. Hero Section

<section class="flex flex-col lg:flex-row items-center justify-between py-12">
  <div class="lg:w-1/2 mb-8 lg:mb-0">
    <h1 class="text-4xl lg:text-6xl font-bold mb-4">
      Hero Title
    </h1>
    <p class="text-lg lg:text-xl text-slate-600">
      Hero description text
    </p>
  </div>
  <div class="lg:w-1/2">
    <img src="/hero.png" alt="Hero" class="w-full rounded-lg">
  </div>
</section>

Responsive Images

<!-- Full width on mobile, constrained on desktop -->
<img src="/image.jpg" alt="Description" 
     class="w-full md:max-w-lg lg:max-w-2xl mx-auto rounded-lg">
 
<!-- Art direction: different images per breakpoint -->
<picture>
  <source media="(min-width: 1024px)" srcset="image-large.jpg">
  <source media="(min-width: 768px)" srcset="image-medium.jpg">
  <img src="image-small.jpg" alt="Description" class="w-full">
</picture>

Hiding/Showing Elements

<!-- Hide on mobile, show on tablet+ -->
<div class="hidden md:block">Desktop only</div>
 
<!-- Show on mobile, hide on desktop -->
<div class="block md:hidden">Mobile only</div>
 
<!-- Hide on specific breakpoints -->
<div class="hidden lg:hidden">Hidden on large screens</div>
<div class="hidden sm:md:block">Hidden on small, shown on medium+</div>

Responsive Typography (Fluid)

/* In your CSS (not Tailwind utility) */
.responsive-text {
  font-size: clamp(1rem, 2.5vw, 2rem);
  /* min: 1rem, preferred: 2.5vw, max: 2rem */
}
<p class="responsive-text">Fluid text size</p>

Touch Targets (Mobile)

<!-- Minimum 44×44px touch targets on mobile -->
<button class="min-w-[44px] min-h-[44px] p-4">
  Click me
</button>
 
<!-- Spacing for fingers -->
<div class="space-y-4 md:space-y-6">
  <button class="w-full py-3">Button 1</button>
  <button class="w-full py-3">Button 2</button>
</div>

Viewport Units

<!-- Full viewport height -->
<div class="h-screen">Full height</div>
 
<!-- Full viewport width -->
<div class="w-screen">Full width</div>
 
<!-- Custom viewport units -->
<div class="min-h-[100dvh]">Dynamic viewport height (mobile)</div>

Testing Responsive Design

# Chrome DevTools
# - Toggle device toolbar (Ctrl+Shift+M)
# - Test common device sizes
# - Check touch interactions
 
# Tailwind CLI (if using)
npx tailwindcss -i ./src/input.css -o ./dist/output.css --watch

Key Takeaways

  • Mobile-first: Base styles for mobile, sm:, md:, lg: prefixes for larger screens
  • 6 breakpoints: sm(640px), md(768px), lg(1024px), xl(1280px), 2xl(1536px)
  • Flex/Grid: Use responsive prefixes for layout changes
  • Touch targets: Minimum 44×44px on mobile
  • Hide/Show: hidden + responsive prefixes for conditional display
  • Container queries: @container for component-level responsiveness
  • Test: Always test on real devices and multiple screen sizes