首页
/ daisyUI Stack 组件完全指南:用 CSS Grid 让元素层层堆叠

daisyUI Stack 组件完全指南:用 CSS Grid 让元素层层堆叠

2026-09-08 11:42:07作者:房伟宁

Stack 是 daisyUI 中一个精巧的布局组件:它通过单个 stack 类,把多个子元素(图片、卡片、通知等)在同一个平面位置上叠放起来,形成“卡牌叠层”或“多图层”的视觉效果。本文以 Stack 官方文档/components/stack/+page.md>)为主体,结合 stack.css 源码与仓库内技能文档,讲解其类名体系、方向修饰符与对齐原理,并给出可直接复制的 6 类实战示例。读完你可以熟练地用 stackstack-topstack-start 等类名搭建层叠图册、堆叠卡片与通知列表。

组件定位:一个类,实现多元素层叠

Stack 组件的核心作用是“把一个元素放到另一个元素上面”(Puts the children elements on top of each other)。与 absolute 定位手动堆叠不同,Stack 完全基于 CSS Grid 隐式网格实现,无需任何 JS 与绝对定位坐标,容器的直接子元素会自动整齐地偏移错开,呈现微妙的立体叠层感。

依据组件页面的 frontmatter 元数据,Stack 提供以下类名:

类型 类名 作用 是否为默认
component stack 让子元素彼此叠放
modifier stack-bottom 将子元素向底部对齐 是(默认方向)
modifier stack-top 将子元素向顶部对齐
modifier stack-start 将子元素向起始侧(水平方向)对齐
modifier stack-end 将子元素向末尾侧(水平方向)对齐

提示:修饰符以 stack 前缀与组件类连接使用,例如 stack stack-top。frontmatter 中标注 stack-bottomdefault: true,也就是说不写任何修饰符时,默认行为即等价于底部对齐的堆叠,这与源码中 .stack.stack-bottom 共用同一组栅格规则完全一致。

叠放原理:从源码看 5 列 5 行栅格

要理解 Stack 为什么能产生“每张牌边缘可见”的效果,关键在于阅读组件真正的样式实现 stack.css

.stack {
  @layer daisyui.l1.l2.l3 {
    @apply inline-grid;
    grid-template-columns: 3px 4px 1fr 4px 3px;
    grid-template-rows: 3px 4px 1fr 4px 3px;
  }
}

容器被声明为 inline-grid,并划分成 5 列 × 5 行的轨道网格,轨道宽度为 3px 4px 1fr 4px 3px——即两侧留出 3px/4px 的偏移余量,中间 1fr 是真正的内容区域。子元素则通过 grid-column / grid-row 落到不同的轨道组合上,从而让每一层都相对上一层产生固定偏移。

在此基础上,CSS 还利用级联选择器对子元素做了统一的尺寸与层叠处理:

& > * {
  @apply h-full w-full;
}

所有直接子元素被强制铺满父级尺寸,这正是文档中“可以用 w-*h-* 设置容器宽高从而使所有子项同尺寸”这一规则的底层保障。容器尺寸由外部 Tailwind 工具类决定,内部每个 > * 自动撑满,因此它们天然等大。

关于层叠顺序,源码按 DOM 顺序分配了递增的可见权重:

  • 第 1 个子元素(:nth-child(1))得到 z-3
  • 第 2 个子元素(:nth-child(2))得到 z-2opacity-90
  • 第 3 个及以后的子元素(:nth-child(n + 2))得到 opacity-70

也就是说:排在最前面的 HTML 子元素显示在最上层(层级最高),后续子元素逐层下沉并略微变透明。第 3 层开始统一 70% 透明度、第 2 层 90% 透明度,因此下面的“牌”隐约透出,产生真实的厚度观感。要调整透明度,直接在对应子元素上追加 Tailwind 的 opacity-* 工具类覆盖即可。

四种对齐修饰符的栅格差异

stack-topstack-bottomstack-startstack-end 本质上是四套不同的栅格坐标方案,源码把它们放在 @layer daisyui.l1.l2 中,逐一改写子元素的 grid-column / grid-row

  • stack-bottom(默认):中间层落在 grid-column: 3 / 4grid-row: 3 / 6,让整叠元素沉向容器底部,第 1 层跨 1 / 61 / 4
  • stack-top:中间层对应 grid-row: 1 / 4,整叠元素从容器顶部开始向上层展开;
  • stack-start:中间层对应 grid-column: 1 / 4grid-row: 3 / 4,把“牌边”偏移引导到水平起始侧;
  • stack-end:中间层对应 grid-column: 3 / 6grid-row: 3 / 4,把“牌边”偏移引导到水平末尾侧。

可以简单记忆为:竖向修饰符(top/bottom)控制“牌堆露出的边在垂直方向的哪一端”,横向修饰符(start/end)控制“露出的边在水平方向的哪一侧”。

基础用法:三等分块与等尺寸规则

Stack 最基础的形态是三个色块叠放。以下代码移除了文档站点的类前缀占位符,可直接粘贴运行:

<div class="stack h-20 w-32">
  <div class="grid rounded-box bg-primary text-primary-content place-content-center">1</div>
  <div class="grid rounded-box bg-accent text-accent-content place-content-center">2</div>
  <div class="grid rounded-box bg-secondary text-secondary-content place-content-center">3</div>
</div>

这里有两个关键细节:

  1. 容器必须有确定尺寸h-20 w-32(或 size-28 这类工具类)定义了整个 Stack 的宽高,由 & > * { height: 100%; width: 100% } 传播给所有子元素,保证它们完全等大;
  2. 子元素负责自己的视觉样式。示例使用 bg-primarybg-accentbg-secondary 等 daisyUI 语义色,以及 Tailwind 的 grid place-content-center 让数字居中。

由于容器是 inline-grid,若不在外层使用 w-*/h-*,也可用页面布局类控制尺寸——但务必记住:stack 组件本身不负责尺寸,尺寸一律交给 Tailwind 工具类。这一点在技能文档 stack.md 的 Rules 中同样被强调:“Use the w-* and h-* classes to set the stack width and height. These classes make all the items the same size.”

实战一:层叠图片画廊

把三张相同宽高的图片叠放,能立刻营造出“一叠照片”的浏览感,适合做相册入口或轮播样式。只需给每张图片追加 rounded-box 圆角,让叠层边缘更精致:

<div class="stack w-48">
  <img alt="示例图片 1" src="your-image-1.webp" class="rounded-box" />
  <img alt="示例图片 2" src="your-image-2.webp" class="rounded-box" />
  <img alt="示例图片 3" src="your-image-3.webp" class="rounded-box" />
</div>

第 1 张图片默认浮在最上层(z-3),第 2、3 张按 90%/70% 透明度下沉,露出的左侧与底部边缘形成整齐的错位,无需任何定位代码。使用图片时请将 src 替换为实际部署的图片路径。

实战二:卡片与通知堆叠

Stack 与 daisyUI 的 card 组件组合非常自然。给每张卡片设置不同强度的阴影(shadow-mdshadowshadow-sm),叠层之间就能区分层次并浮现真实的“压着”关系:

<div class="stack">
  <div class="text-center shadow-md card bg-base-200">
    <div class="card-body">A</div>
  </div>
  <div class="text-center shadow card bg-base-200">
    <div class="card-body">B</div>
  </div>
  <div class="text-center shadow-sm card bg-base-200">
    <div class="card-body">C</div>
  </div>
</div>

更贴近真实产品的场景是“通知抽屉”风格:同一卡片反复堆叠 3 次,只在标题与正文上区分文案,模拟出多条未读消息层叠的视觉(示例中的 card-titlecard-body 完整结构):

<div class="stack">
  <div class="shadow-md bg-base-100 card">
    <div class="card-body">
      <h2 class="card-title">Notification 1</h2>
      <p>You have 3 unread messages. Tap here to see.</p>
    </div>
  </div>
  <div class="shadow-md bg-base-100 card">
    <div class="card-body">
      <h2 class="card-title">Notification 2</h2>
      <p>You have 3 unread messages. Tap here to see.</p>
    </div>
  </div>
  <div class="shadow-md bg-base-100 card">
    <div class="card-body">
      <h2 class="card-title">Notification 3</h2>
      <p>You have 3 unread messages. Tap here to see.</p>
    </div>
  </div>
</div>

此时使用 bg-base-100border border-base-content 这类语义色,可保证通知卡片在浅色/深色主题下都能正确显示。

实战三:用修饰符调整露出方向

叠层露出的“牌边”方向可通过修饰符自由切换。下面三组代码分别对应顶部对齐、起始侧对齐、末尾侧对齐的卡片叠层,其余结构与基础卡片堆叠完全一致:

<!-- 子元素向顶部对齐:stack-top -->
<div class="stack stack-top size-28">
  <div class="text-center border border-base-content card bg-base-100">
    <div class="card-body">A</div>
  </div>
  <div class="text-center border border-base-content card bg-base-100">
    <div class="card-body">B</div>
  </div>
  <div class="text-center border border-base-content card bg-base-100">
    <div class="card-body">C</div>
  </div>
</div>
<!-- 子元素向水平起始侧对齐:stack-start -->
<div class="stack stack-start size-28">
  <div class="text-center border border-base-content card bg-base-100">
    <div class="card-body">A</div>
  </div>
  <div class="text-center border border-base-content card bg-base-100">
    <div class="card-body">B</div>
  </div>
  <div class="text-center border border-base-content card bg-base-100">
    <div class="card-body">C</div>
  </div>
</div>
<!-- 子元素向水平末尾侧对齐:stack-end -->
<div class="stack stack-end size-28">
  <div class="text-center border border-base-content card bg-base-100">
    <div class="card-body">A</div>
  </div>
  <div class="text-center border border-base-content card bg-base-100">
    <div class="card-body">B</div>
  </div>
  <div class="text-center border border-base-content card bg-base-100">
    <div class="card-body">C</div>
  </div>
</div>

三者的共同点是都通过 size-28 统一了容器边长;差别仅在于 stack-top / stack-start / stack-end 修饰符驱动了源码中三套不同的 grid-row / grid-column 映射,因此每一叠卡片的“错位边缘”出现在不同方向。默认的 stack-bottom 则无需书写(与 stack 单独使用等价)。

文档站点的 $$ 占位符说明

在 Stack 官方页面/components/stack/+page.md>) 的代码块中,你会看到 $$stack$$card 这样的写法。$$ 并非 daisyUI 语法,而是文档站点为支持自定义类名前缀预留的占位符:站点在展示代码时,通过 actions.svelte.js 中的 prefixClassNames 指令把代码内的 $$ 实时替换为前缀 store 的当前值;而 PrefixEdit.svelte 提供了输入框,允许读者输入自定义前缀(例如 tw-)后让全部示例代码同步变为 tw-stack

daisyUI 组件本身默认不带前缀package.json 中 prefix 默认值为空)。因此:

  • 如果你未配置前缀:直接忽略 $$,类名写作 stackstack-top 即可,与本文示例一致;
  • 如果你通过 Tailwind 配置了全局前缀(对应 daisyUI 的 prefix 插件选项):把 $$ 替换成你的前缀字符串,文档中的所有示例代码即可原样使用。

小结与相关资源

Stack 用约 80 行 CSS 就完成了一个框架无关、零 JS 的层叠布局能力,其设计可归纳为三层:

  1. 容器层inline-grid + 五轨栅格产生错位余量;
  2. 方向层:四个修饰符分别改写子元素的栅格轨道,决定“露出边”的方向;
  3. 层叠层:按 DOM 顺序递增 z 值并施加 90%/70% 透明度,塑造厚度感。

想进一步探索,可以在仓库中查看以下位置:

若要快速把 Stack 接入你的项目,可参考仓库根目录的 README.mdpackages/daisyui/README.md 完成 Tailwind 插件安装,随后即可直接使用本文中的类名与示例。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.74 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
897
5.81 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
531
595
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
920
1.84 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.63 K
1.02 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.36 K
1.46 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.02 K
518
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
547
389