Tailwind CSS 这玩意儿,圈子里有人爱得深沉,有人一看那一长串类名就头大。不过很多人不知道,Tailwind 里藏了个叫 @apply 的功能,连框架作者 Adam Wathan 都公开说过“几乎别用它”。那这货到底是神器还是鸡肋?今儿个就来扒一扒,顺便整点硬核操作,看看咋样把 @apply 用得飞起。
聊正事之前先捋清楚:
@apply就是让你在 CSS 文件里“复制粘贴”Tailwind 的工具类。比方说写@apply p-4;,编译出来直接变成padding: 1rem;。光看这个确实有点傻,但配上自定义工具类,真香程度直接拉满。下面从实际场景出发,手把手带大伙儿把@apply玩出花。
@apply是啥
@apply 说白了就是 Tailwind 给 CSS 开的后门,允许在样式表里直接引用那些原子类。好比做菜时候提前调好一碗酱汁,炒菜时直接倒进去,不用每次重新放盐放糖。这玩意儿跟 Sass 的 @mixin 加 @include 简直一个模子刻出来的——先定义一段样式,然后在别处整段引用。
/* 定义一坨样式(用Tailwind的@utility) */
@utility 警告框 {
background-color: #fef3c7;
border-left: 4px solid #f59e0b;
padding: 1rem;
}
/* 别的地方直接用@apply吸过来 */
.alert {
@apply 警告框;
margin-bottom: 1rem;
}不过得留个心眼:@apply 只能用在 @utility 定义好的家伙上,或者直接用 Tailwind 自带的那些类(比如 flex、p-4)。千万别在 @apply 里写乱七八糟的嵌套,那玩意儿不认。
整点实战
很多新手一上来就想把所有的样式都塞进 @apply,结果搞得 CSS 文件比 HTML 还长。真正爽的姿势是:先造几个高频复用的布局工具类,然后在 HTML 里直接贴,或者用 @apply 吸到自己的类里。下面整个最常见的——垂直布局和水平布局来回切换。
步骤 1:定义两个基础工具类
在 CSS 文件里(确保 Tailwind 能扫到)写下:
@utility 横着排 {
display: flex;
flex-direction: row;
gap: 1rem;
}
@utility 竖着排 {
display: flex;
flex-direction: column;
gap: 1rem;
}步骤 2:直接在 HTML 里用响应式变体
<div class="竖着排 sm:横着排">
<div>卡片1</div>
<div>卡片2</div>
<div>卡片3</div>
</div>手机上看是上下摞一块儿,屏幕宽度超过 640px 就自动变成左右并排。那个 sm: 就是 Tailwind 的断点前缀,默认 640px 触发。这里有个小坑:自定义的 @utility 默认不会生成响应式变体,需要在配置文件里把 utilities 的变体打开,或者直接用 Tailwind 3+ 的任意变体写法,比如 sm:横着排 如果没反应,检查下 tailwind.config.js 里有没有 variants: { utilities: ['responsive'] }。
步骤 3:不想 HTML 里堆太多类?用 @apply 吸
.我的布局 {
@apply 竖着排;
}
@media (width >= 640px) {
.我的布局 {
@apply 横着排;
}
}然后 HTML 里只写 <div class="我的布局">... 就完事儿。这种做法特别适合那些打死也不想在 HTML 里看到工具类的老派 CSS 玩家。
更骚的网格
再整一个网格生成器,只用一行 @utility 搞定响应式栅格。这招用上了 CSS 变量,可玩性直接起飞。
步骤 1:定义网格工具类
@utility 网格简单 {
display: grid;
grid-template-columns: repeat(var(--列数), minmax(0, 1fr));
gap: var(--间距, 1rem);
}这里 --列数 和 --间距 都是自定义属性(CSS 变量)。minmax(0, 1fr) 是防止内容把格子撑爆的经典写法。
步骤 2:在 HTML 里动态调列数
<div class="网格简单" style="--列数: 3">
<div>条目1</div>
<div>条目2</div>
<div>条目3</div>
</div>但写内联 style 有点 low。Tailwind 允许用方括号语法直接塞任意值:
<div class="网格简单 [--列数:3]">
<div>1</div><div>2</div><div>3</div>
</div>步骤 3:搞成响应式——手机 1 列,平板 3 列
<div class="网格简单 [--列数:1] sm:[--列数:3] md:[--列数:4]">
<div>卡牌</div>
<div>卡牌</div>
<!-- 更多条目 -->
</div>sm: 是 ≥640px,md: 是 ≥768px。这么一写,HTML 里一眼就能看出布局怎么变,再也不用去 CSS 里翻媒体查询。
如果觉得方括号写法太“魔法”,老路子一样管用:
.响应式网格 {
@apply 网格简单;
--列数: 1;
}
@media (width >= 640px) {
.响应式网格 {
--列数: 3;
}
}<div class="响应式网格">...</div>| 场景 | 推荐姿势 | 理由 |
|---|---|---|
| 简单布局 | HTML直接贴工具类 | 改动不用切文件 |
| 复杂组件 | 用@apply包一层 | 复用方便,语义清晰 |
| 动态列数 | 任意属性[--列数:3] | 免写CSS,灵活到爆 |
实际操作中,建议先把常用的布局模式(水平、垂直、网格、堆叠)做成 @utility,存到一个公共 CSS 文件里。团队里谁要用,要么 HTML 里直接贴类名,要么在自己的 CSS 里 @apply 吸一下。千万别犯强迫症把所有样式都转成 @apply——那还不如回去写普通 CSS。记住一点:@apply 是拿来偷懒的,不是拿来炫技的。碰到需要传参数的情况,比如不同尺寸的头像,直接用 CSS 变量配合 @utility 就能搞定,不用死磕 Sass 那套 @mixin 带参数的写法。
