响应式设计
概述
Tailwind 中的每个工具类都可以在不同的断点有条件地应用,这使得构建复杂的响应式界面变得轻而易举,而无需离开 HTML。
首先,确保已将 视口元标记 添加到文档的 <head> :
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
若要使工具类仅在特定断点生效,只需在工具类前添加断点前缀和 : 字符:
<!-- 默认宽度16,中屏32,大屏48 -->
<img class="w-16 md:w-32 lg:w-48" src="..." />
默认情况下,有五个断点,其灵感来自常见的设备分辨率:
| 断点前缀 | 最小宽度 | CSS |
|---|---|---|
sm | 40rem (640px) | @media (width >= 40rem) { ... } |
md | 48rem (768px) | @media (width >= 48rem) { ... } |
lg | 64rem (1024px) | @media (width >= 64rem) { ... } |
xl | 80rem (1280px) | @media (width >= 80rem) { ... } |
2xl | 96rem (1536px) | @media (width >= 96rem) { ... } |
这适用于 框架中的每个工具类,这意味着你可以在给定的断点更改几乎任何内容——甚至像字母间距或光标样式这样的东西。
这是一个简单的营销页面组件示例,它在小屏幕上使用堆叠布局,在大屏幕上使用并排布局:
Looking to take your team away on a retreat to enjoy awesome food and take in some sunshine? We have a list of places to do just that.
<div class="mx-auto max-w-md overflow-hidden rounded-xl bg-white shadow-md md:max-w-2xl">
<div class="md:flex">
<div class="md:shrink-0">
<img
class="h-48 w-full object-cover md:h-full md:w-48"
src="/img/building.jpg"
alt="Modern building architecture"
/>
</div>
<div class="p-8">
<div class="text-sm font-semibold tracking-wide text-indigo-500 uppercase">Company retreats</div>
<a href="#" class="mt-1 block text-lg leading-tight font-medium text-black hover:underline">
Incredible accommodation for your team
</a>
<p class="mt-2 text-gray-500">
Looking to take your team away on a retreat to enjoy awesome food and take in some sunshine? We have a list of
places to do just that.
</p>
</div>
</div>
</div>
以上示例的工作原理如下:
- 默认情况下,外部
div是display: block,但通过添加md:flex工具类,它在中等屏幕及更大屏幕上变为display: flex。 - 当父元素是 flex 容器时,我们需要确保图像永远不会缩小,因此我们添加了
md:shrink-0以防止在中等屏幕及更大屏幕上缩小。从技术上讲,我们也可以只使用shrink-0,因为它在较小的屏幕上不会做任何事情,但因为它只在中等屏幕上重要,所以在类名中明确这一点是个好主意。 - 在小屏幕上,图像默认情况下自动全宽。在中等屏幕及更大屏幕上,我们已将宽度限制为固定大小,并使用
md:h-full md:w-48确保图像全高。
在此示例中,我们只使用了一个断点,但你也可以轻松地使用 sm、lg、xl 或 2xl 响应式前缀在其他尺寸上自定义此组件。
移动优先
Tailwind 使用 移动优先 的断点系统,类似于你在 Bootstrap 等其他框架中可能习惯使用的系统。
这意味着未加前缀的工具类(如 uppercase)在所有屏幕尺寸上都有效,而加前缀的工具类(如 md:uppercase)仅在指定的断点及以上有效。
针对移动屏幕
这种方法最常让人感到惊讶的地方是,要为移动设备设置样式,你需要使用工具类的未加前缀的版本,而不是 sm: 前缀的版本。不要将 sm: 视为 “在小屏幕上”,而应将其视为 “在小断点处”。
sm:<!-- 这只会使文本在宽度为 640 像素及以上的屏幕上居中,而不会在小屏幕上居中 -->
<div class="sm:text-center"></div>
<!-- 这将在移动设备上使文本居中,并在宽度为 640 像素及以上的屏幕上使其左对齐 -->
<div class="text-center sm:text-left"></div>
因此,通常最好先实现设计的移动布局,然后叠加适用于 sm 屏幕的任何更改,然后是 md 屏幕,依此类推。
定位断点范围
默认情况下,由 md:flex 等规则应用的样式将在该断点生效,并在更大的断点上保持应用。
如果你希望仅在特定断点范围处于活动状态时才应用工具类,请将 md 等响应式变体与 max-* 变体堆叠,以将该样式限制在特定范围内:
<div class="md:max-xl:flex">
<!-- ... -->
</div>
Tailwind 为每个断点生成相应的 max-* 变体,因此开箱即用即可使用以下变体:
| 变体 | 媒体查询 |
|---|---|
max-sm | @media (width < 40rem) { ... } |
max-md | @media (width < 48rem) { ... } |
max-lg | @media (width < 64rem) { ... } |
max-xl | @media (width < 80rem) { ... } |
max-2xl | @media (width < 96rem) { ... } |
针对单个断点
要定位单个断点,请通过堆叠响应式变体(如 md)和下一个断点的 max-* 变体来定位该断点的范围:
<div class="md:max-lg:flex">
<!-- ... -->
</div>
阅读 定位断点范围 以了解更多信息。
使用自定义断点
自定义主题
使用 --breakpoint-* 主题变量自定义你的断点:
@import "../../../../../node_modules/.pnpm/tailwindcss@4.1.11/node_modules/tailwindcss/dist/lib.d.mts";
@theme {
--breakpoint-xs: 30rem;
--breakpoint-2xl: 100rem;
--breakpoint-3xl: 120rem;
}
这会将 2xl 断点更新为使用 100rem 而不是默认的 96rem,并创建可在你的标记中使用的新的 xs 和 3xl 断点:
<div class="grid xs:grid-cols-2 3xl:grid-cols-6">
<!-- ... -->
</div>
请注意,始终使用相同的单位定义断点非常重要,否则生成的工具类可能会以意外的顺序排序,导致断点类以意外的方式相互覆盖。
Tailwind 为默认断点使用 rem,因此如果你要向默认断点添加额外的断点,请确保也使用 rem。
在 主题文档 中了解更多关于自定义主题的信息。
删除默认断点
要删除默认断点,请将其值重置为 initial 关键字:
@import "tailwindcss";
@theme {
--breakpoint-2xl: initial;
}
你也可以使用 --breakpoint-*: initial 重置所有默认断点,然后从头开始定义所有断点:
@import "tailwindcss";
@theme {
--breakpoint-*: initial;
--breakpoint-tablet: 40rem;
--breakpoint-laptop: 64rem;
--breakpoint-desktop: 80rem;
}
在 主题文档 中了解更多关于删除默认主题值的信息。
使用任意值
若需临时使用不适合纳入主题的断点,可通过 min 或 max 变体配合任意值动态生成自定义断点。
<div class="max-[600px]:bg-sky-300 min-[320px]:text-center">
<!-- ... -->
</div>
任意值 文档中了解更多关于任意值支持的信息。
容器查询
什么是容器查询?
容器查询 是一种现代 CSS 功能,它允许你根据父元素的大小而不是整个视口的大小来设置元素的样式。它们让你构建的可移植性和可重用性更高的组件,因为它们可以根据该组件的实际可用空间进行更改。
基本示例
使用 @container 类将元素标记为容器,然后使用 @sm 和 @md 等变体根据容器的大小设置子元素的样式:
<div class="@container">
<div class="flex flex-col @md:flex-row">
<!-- ... -->
</div>
</div>
如同断点变体一样,Tailwind CSS 中的容器查询遵循 移动优先原则,在目标容器尺寸及以上生效。
最大宽度容器查询
使用 @max-sm 和 @max-md 等变体在特定容器尺寸以下应用样式:
<div class="@container">
<div class="flex flex-row @max-md:flex-col">
<!-- ... -->
</div>
</div>
容器查询范围
堆叠常规容器查询变体和最大宽度容器查询变体以定位特定范围:
<div class="@container">
<div class="flex flex-row @sm:@max-md:flex-col">
<!-- ... -->
</div>
</div>
命名容器
对于使用多个嵌套容器的复杂设计,你可以使用 @container/{name} 命名容器,并使用 @sm/{name} 和 @md/{name} 等变体定位特定容器:
<div class="@container/main">
<!-- ... -->
<div class="flex flex-row @sm/main:flex-col">
<!-- ... -->
</div>
</div>
这使得可以根据 远处的容器 的大小而不是仅仅最近的容器的大小来设置元素的样式。
使用自定义容器尺寸
使用 --container-* 主题变量自定义你的容器尺寸:
@import "tailwindcss";
@theme {
--container-8xl: 96rem;
}
这会添加一个新的 8xl 容器查询变体,可在你的 html 中使用:
<div class="@container">
<div class="flex flex-col @8xl:flex-row">
<!-- ... -->
</div>
</div>
在 主题文档 中了解更多关于自定义主题的信息。
使用任意值
对于你不想添加到主题中的一次性容器查询尺寸,可以使用 @min-[475px] 和 @max-[960px] 等变体:
<div class="@container">
<div class="flex flex-col @min-[475px]:flex-row">
<!-- ... -->
</div>
</div>
使用容器查询单元
在其他工具类中将 容器查询长度单位(如 cqw)用作任意值,以引用容器大小:
<div class="@container">
<div class="w-[50cqw]">
<!-- ... -->
</div>
</div>
容器尺寸参考
默认情况下,Tailwind 包含从 16rem (256px) 到 80rem (1280px) 的容器尺寸:
rem 相对单位:基于 HTML 根元素(<html>)的字体大小。默认情况下,1rem = 16px(因浏览器默认根字体大小为 16px)。
示例:若根字体设为 20px,则 1rem = 20px;若子元素设为 1.5rem,实际为 30px。如何修改 HTML 根元素()的字体大小:
- 直接设置固定值(不推荐)
/* 缺点:破坏用户浏览器默认字体设置(通常为 16px),可能导致可访问性问题 */
html {
font-size: 20px; /* 覆盖默认的 16px */
}
- 使用百分比(推荐技巧:62.5%)
html {
/* 覆盖用户默认字体大小(如用户设 20px 时 1rem=12.5px,文字反而缩小) */
font-size: 62.5%; /* 1rem = 10px(基于默认 16px 计算) */
}
/* 注意:需同步设置 body 字体大小,否则正文会过小(10px) */
body {
font-size: 1.6rem; /* 恢复为 16px 视觉大小 */
}
- 相对单位(最佳实践)
html {
/* font-size: 16px 设置无论用户如何修改系统设置,根字体始终强制为 16px,降低可读性 */
font-size: 100%; /* 保留用户默认设置(通常 16px)用户因视力问题设置系统默认字体为 20px → 页面根字体自动变为 20px → 所有 rem 单位按此缩放。 */
}
- 媒体查询适配响应式
html {
font-size: 100%; /* 基准值 */
}
/* 根据屏幕尺寸动态调整全局缩放比例 */
@media (min-width: 1200px) {
html {
font-size: 125%; /* 大屏放大:1rem = 20px */
}
}
| 变体 | 最小宽度 | CSS |
|---|---|---|
@3xs | 16rem (256px) | @container (width >= 16rem) { … } |
@2xs | 18rem (288px) | @container (width >= 18rem) { … } |
@xs | 20rem (320px) | @container (width >= 20rem) { … } |
@sm | 24rem (384px) | @container (width >= 24rem) { … } |
@md | 28rem (448px) | @container (width >= 28rem) { … } |
@lg | 32rem (512px) | @container (width >= 32rem) { … } |
@xl | 36rem (576px) | @container (width >= 36rem) { … } |
@2xl | 42rem (672px) | @container (width >= 42rem) { … } |
@3xl | 48rem (768px) | @container (width >= 48rem) { … } |
@4xl | 56rem (896px) | @container (width >= 56rem) { … } |
@5xl | 64rem (1024px) | @container (width >= 64rem) { … } |
@6xl | 72rem (1152px) | @container (width >= 72rem) { … } |
@7xl | 80rem (1280px) | @container (width >= 80rem) { … } |