Tailwind CSS Responsive Design
18.4.1. Breakpoint Strategy
The default Tailwind CSS breakpoints must be used.
| Prefix | Minimum Width | Target Device |
|---|---|---|
sm: | 640px | Small tablet |
md: | 768px | Tablet |
lg: | 1024px | Small desktop |
xl: | 1280px | Desktop |
2xl: | 1536px | Large desktop |
- Default breakpoints must be used as a priority.
- Custom breakpoints should be added only when default values cannot accommodate the requirement.
ts
// tailwind.config.ts — Custom breakpoint addition example
export default {
theme: {
extend: {
screens: {
'3xl': '1920px',
},
},
},
} satisfies Config- Custom breakpoints must be added to
theme.extend.screens. - Direct modification of
theme.screens, which overwrites default breakpoints, is prohibited.
18.4.2. Mobile-First Principle
Default styles must be written for mobile screens. Breakpoint prefixes are used to extend styles for wider screens.
vue
<template>
<div class="px-4 py-6 sm:px-6 md:px-8 lg:px-12">
<h1 class="text-xl font-bold sm:text-2xl lg:text-3xl">
Page Title
</h1>
<p class="mt-2 text-sm text-gray-600 sm:text-base lg:text-lg">
Body description.
</p>
</div>
</template>- Classes without a prefix represent the mobile default.
- Breakpoints must be expanded in the order
sm:->md:->lg:->xl:->2xl:. max-*variants must not be used. The mobile-first approach must be applied consistently.
18.4.3. Responsive Utility Patterns
Responsive Grid
vue
<template>
<div class="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
<div
v-for="item in items"
:key="item.id"
class="rounded-lg border border-gray-200 p-4"
>
{{ item.title }}
</div>
</div>
</template>Responsive Typography
| Element | Mobile | sm | lg |
|---|---|---|---|
| Page title | text-xl | text-2xl | text-3xl |
| Section title | text-lg | text-xl | text-2xl |
| Body text | text-sm | text-base | text-base |
| Caption | text-xs | text-sm | text-sm |
Responsive Show/Hide
vue
<template>
<nav class="flex items-center justify-between px-4 py-3">
<!-- Mobile only: Hamburger menu -->
<button class="block md:hidden" @click="openMenu">
Menu
</button>
<!-- Desktop only: Full navigation -->
<ul class="hidden gap-6 md:flex">
<li v-for="link in links" :key="link.href">
<a :href="link.href" class="text-sm font-medium text-gray-700 hover:text-brand-600">
{{ link.label }}
</a>
</li>
</ul>
</nav>
</template>- Element visibility is controlled by switching between
hiddenandblock(orflex,grid) per breakpoint. - CSS-based hiding should be used instead of removing elements from the DOM with
v-ifto prevent layout shifts.
18.4.4. Container Configuration
The container class is customized in tailwind.config.ts.
ts
// tailwind.config.ts
export default {
theme: {
container: {
center: true,
padding: {
DEFAULT: '1rem',
sm: '1.5rem',
lg: '2rem',
xl: '2.5rem',
},
screens: {
sm: '640px',
md: '768px',
lg: '1024px',
xl: '1280px',
},
},
},
} satisfies Config| Item | Value | Description |
|---|---|---|
center | true | Automatically applies margin: 0 auto |
padding | Specified per breakpoint | Adjusts horizontal padding based on screen size |
screens | Up to xl: 1280px | Prevents unnecessary expansion beyond 2xl |
vue
<template>
<div class="container">
<main>
Page content area
</main>
</div>
</template>- The
containerclass must be used only in the top-level layout wrapper. - Nesting
containerclasses is prohibited. - The configured
containermust be used instead of manual combinations such asmax-w-screen-xl mx-auto px-4.