Tailwind CSS Responsive Design: Breakpoint System & Mobile-First Strategy

Breakpoint System

Tailwind provides 5 default breakpoints. You can use responsive prefixes to apply styles targeting different screen sizes.

Prefix Min Width CSS Media Query Typical Devices
sm: 640px @media (min-width: 640px) Phone landscape
md: 768px @media (min-width: 768px) Tablet
lg: 1024px @media (min-width: 1024px) Laptop
xl: 1280px @media (min-width: 1280px) Desktop monitor
2xl: 1536px @media (min-width: 1536px) Large monitor

Traditional CSS vs Tailwind The traditional approach requires writing multiple @media queries and maintaining styles across different files, whereas Tailwind uses prefixes like sm: and md: to declare responsive styles directly in the HTML.

Mobile-First Strategy

Tailwind adopts a Mobile-First strategy: unprefixed styles apply to the smallest screens by default, and larger breakpoint prefixes override smaller screen styles.

Example

HTML
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Mobile-First Strategy</title>
  <script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="min-h-screen bg-gray-100 p-4 md:p-8">
  <div class="max-w-6xl mx-auto space-y-8">
    <!-- Responsive text -->
    <div class="bg-white rounded-lg shadow p-6">
      <h3 class="font-semibold mb-4">Responsive Font Size</h3>
      <p class="text-sm md:text-base lg:text-lg xl:text-xl">
        Small screens use text-sm by default, medium screens text-base, large screens text-lg, and extra-large screens text-xl
      </p>
    </div>

    <!-- Responsive padding -->
    <div class="bg-blue-100 rounded-lg p-2 sm:p-4 md:p-6 lg:p-8">
      <p class="text-center text-blue-800">Responsive padding: p-2 → sm:p-4 → md:p-6 → lg:p-8</p>
    </div>

    <!-- Responsive show/hide -->
    <div class="bg-white rounded-lg shadow p-6">
      <h3 class="font-semibold mb-4">Responsive Show/Hide</h3>
      <div class="block md:hidden bg-red-100 p-4 rounded text-center text-red-700">
        Only visible on small screens (block md:hidden)
      </div>
      <div class="hidden md:block bg-green-100 p-4 rounded text-center text-green-700">
        Visible on medium screens and up (hidden md:block)
      </div>
    </div>
  </div>
</body>
</html>
▶ Try it Yourself
💡 Tip: Mobile-First means unprefixed styles are the baseline, and breakpoint prefixes are used for enhancement. For example, text-sm md:text-lg means 14px on small screens and 18px on medium screens and above.

Responsive Prefix in Practice

Responsive prefixes can be combined with any Tailwind class to achieve layout changes at different screen sizes.

Example

HTML
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Responsive Prefix in Practice</title>
  <script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="min-h-screen bg-gray-100 p-4 md:p-8">
  <div class="max-w-6xl mx-auto space-y-8">
    <!-- Responsive Flex layout -->
    <div class="bg-white rounded-lg shadow p-6">
      <h3 class="font-semibold mb-4">Responsive Flex Layout</h3>
      <div class="flex flex-col sm:flex-row gap-4">
        <div class="flex-1 bg-blue-100 p-4 rounded text-center">Item 1</div>
        <div class="flex-1 bg-blue-200 p-4 rounded text-center">Item 2</div>
        <div class="flex-1 bg-blue-300 p-4 rounded text-center">Item 3</div>
      </div>
      <p class="text-sm text-gray-500 mt-2">Stacked vertically on small screens (flex-col), horizontal on medium screens (sm:flex-row)</p>
    </div>

    <!-- Responsive Grid columns -->
    <div class="bg-white rounded-lg shadow p-6">
      <h3 class="font-semibold mb-4">Responsive Grid Columns</h3>
      <div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4">
        <div class="bg-green-100 p-4 rounded text-center">1</div>
        <div class="bg-green-200 p-4 rounded text-center">2</div>
        <div class="bg-green-300 p-4 rounded text-center">3</div>
        <div class="bg-green-400 p-4 rounded text-center">4</div>
        <div class="bg-green-500 p-4 rounded text-center text-white">5</div>
        <div class="bg-green-600 p-4 rounded text-center text-white">6</div>
        <div class="bg-green-700 p-4 rounded text-center text-white">7</div>
        <div class="bg-green-800 p-4 rounded text-center text-white">8</div>
      </div>
      <p class="text-sm text-gray-500 mt-2">grid-cols-1 → sm:grid-cols-2 → lg:grid-cols-3 → xl:grid-cols-4</p>
    </div>

    <!-- Responsive spacing -->
    <div class="bg-white rounded-lg shadow p-4 sm:p-6 md:p-8">
      <h3 class="font-semibold mb-2 sm:mb-4 md:mb-6">Responsive Spacing</h3>
      <div class="space-y-2 sm:space-y-4 md:space-y-6">
        <div class="bg-purple-100 p-4 rounded">Item A</div>
        <div class="bg-purple-200 p-4 rounded">Item B</div>
        <div class="bg-purple-300 p-4 rounded">Item C</div>
      </div>
    </div>
  </div>
</body>
</html>
▶ Try it Yourself

Traditional CSS vs Tailwind The traditional approach requires writing multiple CSS blocks like @media (min-width: 768px) { .grid { grid-template-columns: repeat(2, 1fr); } }, whereas Tailwind accomplishes the same in a single line with grid-cols-1 md:grid-cols-2 lg:grid-cols-3.

Responsive Images

Responsive images ensure that images display correctly at different screen sizes, avoiding overflow or distortion.

Example

HTML
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Responsive Images</title>
  <script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="min-h-screen bg-gray-100 p-4 md:p-8">
  <div class="max-w-6xl mx-auto space-y-8">
    <!-- Responsive image width -->
    <div class="bg-white rounded-lg shadow p-6">
      <h3 class="font-semibold mb-4">Responsive Image Width</h3>
      <img src="https://picsum.photos/1200/400" alt="Responsive image"
           class="w-full md:w-3/4 lg:w-1/2 mx-auto rounded-lg">
      <p class="text-sm text-gray-500 mt-2 text-center">w-full → md:w-3/4 → lg:w-1/2</p>
    </div>

    <!-- Responsive image grid -->
    <div class="bg-white rounded-lg shadow p-6">
      <h3 class="font-semibold mb-4">Responsive Image Grid</h3>
      <div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-2 md:gap-4">
        <img src="https://picsum.photos/300/300?random=1" alt="Image 1" class="w-full aspect-square object-cover rounded-lg">
        <img src="https://picsum.photos/300/300?random=2" alt="Image 2" class="w-full aspect-square object-cover rounded-lg">
        <img src="https://picsum.photos/300/300?random=3" alt="Image 3" class="w-full aspect-square object-cover rounded-lg">
        <img src="https://picsum.photos/300/300?random=4" alt="Image 4" class="w-full aspect-square object-cover rounded-lg">
        <img src="https://picsum.photos/300/300?random=5" alt="Image 5" class="w-full aspect-square object-cover rounded-lg">
        <img src="https://picsum.photos/300/300?random=6" alt="Image 6" class="w-full aspect-square object-cover rounded-lg">
        <img src="https://picsum.photos/300/300?random=7" alt="Image 7" class="w-full aspect-square object-cover rounded-lg">
        <img src="https://picsum.photos/300/300?random=8" alt="Image 8" class="w-full aspect-square object-cover rounded-lg">
      </div>
    </div>
  </div>
</body>
</html>
▶ Try it Yourself
💡 Tip: Use w-full to ensure images don't overflow their parent container, combined with object-cover to maintain aspect ratio.

Responsive Tables

Responsive tables can scroll horizontally on small screens, preventing content from being squeezed.

Example

HTML
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Responsive Tables</title>
  <script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="min-h-screen bg-gray-100 p-4 md:p-8">
  <div class="max-w-6xl mx-auto">
    <div class="bg-white rounded-lg shadow p-4 md:p-6">
      <h3 class="font-semibold mb-4">Responsive Table</h3>
      <div class="overflow-x-auto">
        <table class="w-full text-sm md:text-base">
          <thead>
            <tr class="bg-gray-100">
              <th class="p-2 md:p-3 text-left">ID</th>
              <th class="p-2 md:p-3 text-left">Name</th>
              <th class="p-2 md:p-3 text-left hidden sm:table-cell">Email</th>
              <th class="p-2 md:p-3 text-left hidden md:table-cell">Phone</th>
              <th class="p-2 md:p-3 text-left">Status</th>
            </tr>
          </thead>
          <tbody>
            <tr class="border-b">
              <td class="p-2 md:p-3">001</td>
              <td class="p-2 md:p-3">Alice</td>
              <td class="p-2 md:p-3 hidden sm:table-cell">alice@example.com</td>
              <td class="p-2 md:p-3 hidden md:table-cell">138-0000-0001</td>
              <td class="p-2 md:p-3"><span class="bg-green-100 text-green-700 px-2 py-1 rounded text-xs">Active</span></td>
            </tr>
            <tr class="border-b">
              <td class="p-2 md:p-3">002</td>
              <td class="p-2 md:p-3">Bob</td>
              <td class="p-2 md:p-3 hidden sm:table-cell">bob@example.com</td>
              <td class="p-2 md:p-3 hidden md:table-cell">138-0000-0002</td>
              <td class="p-2 md:p-3"><span class="bg-yellow-100 text-yellow-700 px-2 py-1 rounded text-xs">Pending</span></td>
            </tr>
            <tr class="border-b">
              <td class="p-2 md:p-3">003</td>
              <td class="p-2 md:p-3">Charlie</td>
              <td class="p-2 md:p-3 hidden sm:table-cell">charlie@example.com</td>
              <td class="p-2 md:p-3 hidden md:table-cell">138-0000-0003</td>
              <td class="p-2 md:p-3"><span class="bg-red-100 text-red-700 px-2 py-1 rounded text-xs">Disabled</span></td>
            </tr>
          </tbody>
        </table>
      </div>
      <p class="text-sm text-gray-500 mt-4">Some columns are hidden on small screens; the table scrolls horizontally</p>
    </div>
  </div>
</body>
</html>
▶ Try it Yourself

Traditional CSS vs Tailwind The traditional approach requires writing @media queries to control table column visibility, whereas Tailwind uses class names like hidden sm:table-cell to declare it directly.

Container Queries (@container)

Container queries apply styles based on the parent container's size rather than the viewport size. This is a new feature supported in Tailwind v4.

Example

HTML
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Container Queries</title>
  <script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="min-h-screen bg-gray-100 p-4 md:p-8">
  <div class="max-w-6xl mx-auto space-y-8">
    <!-- Container query basics -->
    <div class="bg-white rounded-lg shadow p-6">
      <h3 class="font-semibold mb-4">Container Query Basics</h3>
      <div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
        <!-- Small container -->
        <div class="@container bg-gray-50 rounded-lg p-4 border-2 border-dashed border-gray-300">
          <div class="flex flex-col @md:flex-row gap-4">
            <img src="https://picsum.photos/150/150" alt="Avatar" class="w-20 h-20 @md:w-24 @md:h-24 rounded-full object-cover">
            <div>
              <h4 class="font-semibold @md:text-lg">Username</h4>
              <p class="text-gray-600 text-sm @md:text-base">This is a container query example. The layout changes based on the parent container's width.</p>
            </div>
          </div>
          <p class="text-xs text-gray-400 mt-2">Small container: vertical layout</p>
        </div>

        <!-- Large container -->
        <div class="@container bg-gray-50 rounded-lg p-4 border-2 border-dashed border-gray-300">
          <div class="flex flex-col @md:flex-row gap-4">
            <img src="https://picsum.photos/150/150" alt="Avatar" class="w-20 h-20 @md:w-24 @md:h-24 rounded-full object-cover">
            <div class="flex-1">
              <h4 class="font-semibold @md:text-lg">Username</h4>
              <p class="text-gray-600 text-sm @md:text-base">Container queries use the @container class and prefixes like @md: to apply styles based on the parent container's size.</p>
              <div class="hidden @lg:flex gap-2 mt-2">
                <span class="bg-blue-100 text-blue-700 px-2 py-1 rounded text-xs">Tag 1</span>
                <span class="bg-green-100 text-green-700 px-2 py-1 rounded text-xs">Tag 2</span>
              </div>
            </div>
          </div>
          <p class="text-xs text-gray-400 mt-2">Large container: horizontal layout with extra tags</p>
        </div>
      </div>
    </div>

    <!-- Container query cards -->
    <div class="bg-white rounded-lg shadow p-6">
      <h3 class="font-semibold mb-4">Container Query Cards</h3>
      <div class="grid grid-cols-1 md:grid-cols-3 gap-6">
        <div class="@container bg-gray-50 rounded-lg overflow-hidden border">
          <img src="https://picsum.photos/400/200?random=10" alt="Card image" class="w-full h-32 @sm:h-48 object-cover">
          <div class="p-4">
            <h4 class="font-semibold @sm:text-lg">Card Title</h4>
            <p class="text-gray-600 text-sm @sm:text-base mt-2">Container queries let components respond to their own container size rather than the viewport size.</p>
            <button class="hidden @sm:block mt-4 bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700">Learn More</button>
          </div>
        </div>
        <div class="@container bg-gray-50 rounded-lg overflow-hidden border">
          <img src="https://picsum.photos/400/200?random=11" alt="Card image" class="w-full h-32 @sm:h-48 object-cover">
          <div class="p-4">
            <h4 class="font-semibold @sm:text-lg">Card Title</h4>
            <p class="text-gray-600 text-sm @sm:text-base mt-2">This allows components to respond correctly across different layouts, making them more flexible.</p>
            <button class="hidden @sm:block mt-4 bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700">Learn More</button>
          </div>
        </div>
        <div class="@container bg-gray-50 rounded-lg overflow-hidden border">
          <img src="https://picsum.photos/400/200?random=12" alt="Card image" class="w-full h-32 @sm:h-48 object-cover">
          <div class="p-4">
            <h4 class="font-semibold @sm:text-lg">Card Title</h4>
            <p class="text-gray-600 text-sm @sm:text-base mt-2">Use the @container class to mark containers, and prefixes like @sm: and @md: to apply styles.</p>
            <button class="hidden @sm:block mt-4 bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700">Learn More</button>
          </div>
        </div>
      </div>
    </div>
  </div>
</body>
</html>
▶ Try it Yourself

Traditional CSS vs Tailwind Traditional container queries require writing @container (min-width: 400px) { ... } media queries, whereas Tailwind uses the @container class and prefixes like @sm: and @md: to declare them directly.

💡 Tip: Container query breakpoint prefixes use @xs: (20rem), @sm: (24rem), @md: (28rem), @lg: (32rem), @xl: (36rem), @2xl: (42rem).

❓ FAQ

Q Does the order of responsive prefixes matter?
A Yes. Tailwind follows a Mobile-First strategy, so breakpoint prefixes take effect from small to large. For example, with text-sm md:text-base lg:text-lg, larger breakpoints override smaller breakpoint styles.
Q How do I hide an element at a specific screen size?
A Use a combination of hidden and block. For example, hidden md:block hides on small screens and shows on medium screens; block md:hidden shows on small screens and hides on medium screens.
Q What's the difference between container queries and media queries?
A Media queries (sm:, md:, etc.) respond to viewport width; container queries (@container, @sm:, etc.) respond to parent container width. Container queries are better suited for reusable components that need responsive behavior across different layouts.
Q How do I customize breakpoints?
A In Tailwind v4, use the @theme directive to customize breakpoints. For example, @theme { --breakpoint-tablet: 768px; } then use the tablet: prefix.

📖 Summary

📝 Exercises

  1. ⭐ Create a responsive navbar: use a hamburger menu on small screens (block md:hidden), and show full navigation on medium screens (hidden md:flex)

  2. ⭐⭐ Create a responsive product card grid: 1 column on small screens (grid-cols-1), 2 columns on medium screens (md:grid-cols-2), 4 columns on large screens (lg:grid-cols-4), with cards that scale up on hover (hover:scale-105)

  3. ⭐⭐⭐ Create a responsive dashboard layout: use container queries for a sidebar component that collapses to icons in narrow containers (@lg: shows text) and expands to show full menu text in wide containers

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏