【免费下载链接】skeleton
Skeleton is an adaptive design system powered by Tailwind CSS.
本文以
@skeletonlabs/skeleton的 CHANGELOG.md 为骨架,逐条对照 packages/skeleton 下的源码实现,系统梳理 v5.0.0 带来的破坏性变更、新增 Tailwind 工具类、主题格式重构与迁移要点。读完本文,你将掌握 v5 主题文件的书写规范、btn/field尺寸变量的工作原理、Dialog/Disclosure/Mask/meter/Corner Shape 等新工具类的实际用法,并能据此将 4.x 项目顺利迁移到 5.x。
Skeleton 是一个基于 Tailwind CSS 构建的自适应设计系统(本项目即为该仓库,包名为@skeletonlabs/skeleton,见 package.json)。5.0.0 是其面向 Tailwind v4 生态的一次大规模重构版本,官方变更日志虽然条目精炼,但每一条背后都对应着实实在在的源码改动。本文不满足于"复述 changelog",而是把每一条变更"翻译"成可验证的代码事实,帮助你判断升级影响面并完成迁移。
一、版本概览:v5 演进路线与包的构成
1.1 从 next 预发布到正式版
从 CHANGELOG.md 可以还原 v5 的发布历程:5.0.0-next.0进入预发布(pre release),随后next.1引入新主题格式、next.5引入结构改进与 meter 组件、next.6扩展按钮与表单尺寸、next.7加入 Corner Shape 工具类、next.8移除card-hover,直至5.0.0汇总为正式版本。这种"先预发布、逐特性合并、再汇总"的模式意味着:如果你此前跟随 next 版本,迁移成本已逐步消化;如果你直接从 4.x 跳到 5.0,则需要一次性处理下面所有变更。
1.2 包结构:一个纯 CSS 的 Tailwind 插件包
v5 的@skeletonlabs/skeleton是一个纯样式包,不包含 JS 运行时逻辑。从 package.json 的exports字段可以看到它的消费方式:
- 入口
"."指向./src/index.css(import与style条件); - 子路径
./themes/*指向./src/themes/*.css,即每个主题都是独立可引用的 CSS 文件; - 其
peerDependencies声明tailwindcss: ^4.0.0,说明v5 只兼容 Tailwind v4。
入口文件 src/index.css 的导入顺序本身就是一份"架构地图":
@import './base/globals.css'; @import './base/theme.css'; @import './utilities/badges.css'; @import './utilities/buttons.css'; @import './utilities/cards.css'; @import './utilities/chips.css'; @import './utilities/corner-shapes.css'; @import './utilities/dialogs.css'; @import './utilities/disclosures.css'; @import './utilities/dividers.css'; @import './utilities/masks.css'; @import './utilities/placeholders.css'; @import './utilities/presets.css'; @import './utilities/tables.css'; @import './utilities/typography.css'; @import './utilities/form-core.css'; @import './utilities/form-groups.css'; @import './utilities/form-inputs.css'; @import './utilities/form-meter.css'; @import './utilities/form-progress.css'; @import './utilities/form-radios-checks.css'; @import './utilities/form-selects.css'; @import './utilities/form-textareas.css'; @import './variants/index.css'; @import './keyframes/progress-circular.css'; @import './keyframes/progress-linear.css';注意文件注释"The order of imports matters"——globals.css提供全局基础样式,theme.css定义默认主题令牌,之后才是各工具类。CHANGELOG 中"优化核心全局与主题属性"(#4396)、"重构全局样式、将占位符颜色重新分配进 Tailwind 组件"(#4370)等条目,都直接作用于这张导入表。
二、主题系统 v5 新格式(#4353)
2.1 新格式长什么样
CHANGELOG 最重要的一条 Major 变更:"Updated themes to new v5 format"。v5 主题文件从旧的变量集合升级为以[data-theme='xxx']选择器为作用域、覆盖统一令牌体系的 CSS 片段。以 themes/modern.css 为范例,一个 v5 主题的骨架是:
[data-theme='modern'] { /* 文本缩放系数 */ --text-scaling: 1.067; /* 字体与排版 */ --typo-base--font-family: ui-rounded, 'Hiragino Maru Gothic ProN', Quicksand, ...; --typo-heading--font-weight: bolder; --typo-anchor--color-light: var(--color-primary-500); --typo-anchor--color-dark: var(--color-primary-500); /* 圆角与边缘 */ --radius-base: 0.375rem; --radius-container: 0.75rem; --corner-shape-base: inherit; --corner-shape-container: inherit; /* 品牌与根背景 */ --color-brand-light: var(--color-primary-500); --color-root-bg-light: var(--color-surface-50); /* 全套色板(oklch 表示) */ --color-primary-50: oklch(88.26% 0.09 326.3deg); /* ... */ }2.2 底层机制:theme.css 的双层令牌
v5 主题格式之所以"新",核心在于 base/theme.css 重新设计了令牌体系,它同时服务两个目的:定义默认(单色)主题,并接收主题属性进行覆盖。
从源码看,这套体系分三层:
- 根属性(
@layer之外直接写在:root):注释明确说明这些是"Tailwind 主题系统不支持的派生令牌",例如全局文本缩放--text-scaling: 1、--corner-shape-base/container: inherit,以及一整套--typo-*排版令牌(base / heading / anchor 及其 hover/active/focus 状态)。 - 标准主题属性(
@theme块):Tailwind 主题系统支持的令牌,包括--spacing: 0.25rem、--radius-base: 0.25rem、全套--color-primary-50至--color-surface-950(以 oklch 无色相值即灰色表示),以及--spacing-elem-xs至--spacing-elem-9xl的元素尺寸令牌。 - 内联属性(
@theme inline块):由其他令牌计算派生,最值得注意的是light-dark()配对变量,例如--color-surface-200-800: light-dark(var(--color-surface-200), var(--color-surface-800)),一个变量在亮色/暗色模式下自动切换深浅;以及基于--text-scaling动态计算的--text-xs到--text-9xl全套字号(如--text-base: calc(1rem * var(--text-scaling)))。
这解释了为什么 CHANGELOG 会把"主题新格式"(#4353)与"核心全局与主题属性优化"(#4396)列为两条独立变更——前者是主题文件的书写约定,后者是对theme.css这套三层令牌体系的打磨。
2.3 消费方式
使用时通过子路径按需引入主题,例如:
/* 应用全局样式 */ @import '@skeletonlabs/skeleton'; /* 引入 Modern 主题 */ @import '@skeletonlabs/skeleton/themes/modern';然后给根元素挂上data-theme="modern"即可生效(主题文件的顶层选择器即[data-theme='modern'],见 themes/modern.css)。由于主题是纯 CSS 变量覆盖,你完全可以在运行时切换data-theme实现换肤,这与 v5 的light-dark()配对变量天然契合。
三、变量化尺寸(Variable Sizing):结构改进的核心(#4380)
3.1 从"写死尺寸"到"单一变量驱动"
CHANGELOG 中的另一条 Major 变更(#4380)是"Tailwind 与 Framework 组件的显著结构与设计改进,引入变量化尺寸(variable sizing)"。所谓变量化尺寸,从源码看就是用一个 CSS 自定义属性作为尺寸基准,其余尺寸全部由它推算。以 utilities/buttons.css 的btn工具类为例:
@utility btn { --btn-size: var(--text-base); /* 尺寸基准 */ border-radius: var(--radius-base); display: inline-flex; flex-direction: row; align-items: center; justify-content: center; gap: --spacing(2); font-size: var(--btn-size); /* 字号跟随基准 */ line-height: var(--btn-size); padding-block: calc((var(--btn-size) - --spacing(0.5)) / 2); padding-inline: calc((var(--btn-size) - --spacing(0.5)) / 2 + var(--spacing)); /* 内部 SVG 图标与基准等大 */ & > :where(svg) { width: var(--btn-size); height: var(--btn-size); } /* ... */ }同样的模式也出现在btn-icon(buttons.css,宽高为calc(var(--btn-size) * 2 - --spacing(0.5)))、input(form-inputs.css,--field-size: var(--text-base))以及disclosure(disclosures.css,--disclosure-size)中。改变一个基准变量,字号、内边距、图标尺寸会整体联动,这就是"变量化"的含义——它让组件在任意尺寸刻度下都保持比例协调。
3.2 尺寸刻度扩展至完整 Tailwind 类型刻度(#4390)
在变量化基础上,#4390 将按钮与表单字段的尺寸工具类从有限的几个扩展为覆盖 Tailwind 完整类型刻度xs到9xl:
- 按钮:
btn-xs、btn-sm、btn-base、btn-lg、btn-xl、btn-2xl…btn-9xl(buttons.css); - 图标按钮:
btn-icon-xs…btn-icon-9xl(buttons.css); - 表单字段:
field-xs…field-9xl(form-core.css)。
每个尺寸工具类本质上只做一件事——覆盖基准变量,例如:
@utility btn-xs { --btn-size: var(--text-xs); } @utility btn-9xl { --btn-size: var(--text-9xl); }配合 theme.css 的@theme inline中--text-xs … --text-9xl的定义,这些基准值还会随--text-scaling全局缩放,主题切换时整个组件的尺寸系统同步伸缩。
3.3 破坏性变更:btn-icon-fab被移除
#4390 同时移除btn-icon-fab,官方给出的替代方案是:使用btn-icon-3xl(配合rounded-full实现圆形)达到等效的 FAB 效果。这是本次升级中最常见的"改名"场景,迁移时只需全局替换类名:
<!-- 4.x --> <button class="btn-icon-fab">+</button> <!-- 5.0 --> <button class="btn-icon-3xl rounded-full">+</button>四、新增 Tailwind 组件:Dialog、Disclosure、Mask(#4389)
#4389 一次性新增了三个 Tailwind 组件,它们在 src/index.css 的导入表中都有对应文件,下面逐一结合源码说明用法。
4.1 Dialog(utilities/dialogs.css)
dialog工具类为原生<dialog>元素提供开箱即用的样式,其布局全部由 CSS 变量驱动:
@utility dialog { --dialog-top: 50%; --dialog-left: 50%; --dialog-translate: -50% -50%; --dialog-width: fit-content; --dialog-height: fit-content; --dialog-max-width: 640px; --dialog-radius: var(--radius-container); --dialog-backdrop: color-mix(in oklab, var(--color-surface-50-950) 75%, transparent); /* ... */ &[open] { display: flex; } &::backdrop { background-color: var(--dialog-backdrop); } }配套提供:
dialog-fullscreen:覆盖上述变量实现全屏(top/left 归零、translate 取消、宽高 100%、radius 0、backdrop 透明);animate-dialog:利用现代 CSS 的transition: display … allow-discrete, overlay … allow-discrete与@starting-style实现打开/关闭的淡入淡出动画(默认时长--anim-duration: 250ms)。
典型用法:
<dialog class="dialog animate-dialog"> <header>标题</header> <article>内容</article> <footer>操作区</footer> </dialog>dialog 内部对语义元素做了 flex 布局适配(header/footer不收缩、article弹性增长),从源码结构看,这是为了支持"头部-内容-底部"三段式对话框布局。
4.2 Disclosure(utilities/disclosures.css)
Disclosure 对应原生<details>/<summary>元素,v5 用三个工具类覆盖:
disclosure-group:垂直排列的容器,gap: --spacing(4);disclosure:作用于<details>,summary采用与btn相同的--disclosure-size变量化尺寸,hover 时应用preset-tonal-primary;内容区通过::details-content与interpolate-size: allow-keywords实现block-size: 0 → auto的平滑展开动画;disclosure-content:作用于内容包装层,提供与 summary 一致的留白。
<details class="disclosure" open> <summary>标题</summary> <div class="disclosure-content">展开的内容</div> </details>从实现看,展开动画依赖::details-content伪元素与interpolate-size属性,这是较新的浏览器能力,使用时应留意目标浏览器支持情况。
4.3 Mask(utilities/masks.css)
Mask 工具类通过内联 SVG 数据 URI 为任意元素裁剪形状,基础类mask负责通用设置(mask-size: contain; mask-repeat: no-repeat; mask-position: center),形状类直接设置mask-image。源码中共内置 13 种形状:
| 形状 | 类名 | 形状 | 类名 |
|---|---|---|---|
| 圆形 | mask-circle | 圆角方形 | mask-squircle |
| 上/下/左/右三角 | mask-triangle-up/down/right/left | 菱形 | mask-diamond |
| 五边形 | mask-pentagon | 六边形 | mask-hexagon |
| 立方体 | mask-cube | 八边形 | mask-octagon |
| 十边形 | mask-decagon | 星形 | mask-star |
| 心形 | mask-heart | 十字形 | mask-cross |
用法示例:
<img class="mask mask-circle w-24 h-24" src="avatar.png" alt="头像" /> <img class="mask mask-heart w-24 h-24" src="logo.png" alt="Logo" />五、新增 meter 组件(#4380 / form-meter.css)
meter 组件是本轮新增的表单组件,作用于原生<meter>元素。源码顶部有一段重要的浏览器一致性警告:Safari 会忽略此处提供的大部分样式。其设计要点:
- 通过
-webkit-appearance: none/-moz-appearance: none重置原生外观,width: 100%; height: --spacing(2); border-radius: var(--radius-base); - 利用 meter 的三种值状态映射到语义色:
optimum(最佳)→--color-success-500、suboptimum(次优)→--color-warning-500、even-less-good(更差)→--color-error-500; - 分别针对 WebKit(
::-webkit-meter-*系列伪元素)与 Firefox(::-moz-meter-bar及:-moz-meter-sub-optimum等伪类)实现。
<meter class="meter" min="0" max="100" low="30" high="70" optimum="90" value="85"></meter>从实现推断,三个状态颜色直接取自主题色板(success/warning/error),意味着 meter 的语义配色会随主题自动变化,无需额外配置。
六、Corner Shape 工具类与品牌色默认值(#4408)
6.1 Corner Shape 的完整矩阵
#4408 新增的 Corner Shape 工具类在 utilities/corner-shapes.css 中实现,它基于较新的 CSScorner-shape属性族(含corner-top-left-shape等单项属性)。可选形状值包括:round、bevel、notch、scoop、squircle、straight。
该文件按覆盖范围组织了完整的矩阵,命名规则为corner-shape-{范围}-{形状}:
- 全部角:
corner-shape-round、corner-shape-bevel、corner-shape-notch、corner-shape-scoop、corner-shape-squircle、corner-shape-straight; - 单边(t/r/b/l):如
corner-shape-t-bevel(顶边两角)、corner-shape-l-round; - 逻辑边(s/e):
corner-shape-s-*(inline-start)、corner-shape-e-*(inline-end); - 单角(tl/tr/br/bl/ss/se/ee/es):如
corner-shape-tl-squircle; - 主题变量:
corner-shape-base/corner-shape-container分别引用--corner-shape-base/--corner-shape-container; - 通配:
corner-shape-*允许任意值,--value('round', 'bevel', 'notch', 'scoop', 'squircle', 'straight', [*])会校验合法取值。
基础变量--corner-shape-base与--corner-shape-container定义在 theme.css 中(默认inherit),主题可通过覆盖这两个变量统一整站边角风格。
6.2 品牌色默认值的应用
同一条目还提到"apply brand color defaults across components, typography, and links"。从源码可验证的落点包括:
- theme.css 中
--color-brand-light: var(--color-primary-500)、--color-brand-dark: var(--color-primary-500)及对应 contrast 变量; - typography.css 中
blockquote的左边框使用light-dark(var(--color-brand-light), var(--color-brand-dark)); - 同一文件内
code的背景使用color-mix(in oklab, light-dark(var(--color-brand-light), var(--color-brand-dark)) 25%, transparent)。
这意味着链接、引用块、行内代码等元素默认即带品牌色,且随明暗模式自动切换。
七、Typography 工具类扩展(#4389)
#4389 在 typography 层面扩充了语义标签工具类。从 utilities/typography.css 看,v5 的排版工具类可分为几组:
- 标题:
h1–h6,各自定义字号(如h1为var(--text-4xl),md断点升为--text-5xl),并通过--typo-heading-*令牌继承主题排版属性,dark变体切换颜色; - 链接:
anchor使用--typo-anchor-*令牌,并为hover/active/focus/dark分别定义下划线样式; - 本次新增的语义元素:
abbr(粗体 + 点状下划线)、cite(斜体)、q(斜体)、sub/sup(--text-xs字号 + 垂直对齐)、time(粗体); - 其他既有元素:
blockquote、kbd(键帽样式)、pre、code(独立<code>在@layer base中,pre code内自动重置)、ins/del(带+/−前缀标记)、mark(tertiary 色高亮)。
这些工具类直接对应语义 HTML 标签,例如:
<p>支持 <abbr title="HyperText">HTML</abbr>、<q>引用</q>、<time datetime="2026-01-01">时间</time> 等标记。</p> <kbd>Ctrl</kbd> + <kbd>K</kbd>八、全局样式重构与占位符颜色再分配(#4370、#4396、#4367)
8.1 占位符颜色从"全局"迁移到"组件"
#4370 的"refined global styles, redistributed placeholder color to Tailwind components"可以从两个文件的对比中确认:
- base/globals.css 中,
--field-placeholder: var(--color-surface-700-300)被定义为设计令牌(@layer base的:root中),但不再直接作用于全局所有输入框; - 占位符的消费点转移到组件层:
input工具类的&::placeholder { color: var(--field-placeholder); }(form-inputs.css)。
另外,全局样式中*:disabled/.disabled统一为opacity: 0.5; cursor: not-allowed,并保持::selection、color-scheme、细滚动条等基础能力,这些都在 globals.css 的@layer base中。
8.2 移除按钮的cursor: pointer
#4367 是行为变更:按钮工具类不再设置cursor: pointer。对照 buttons.css 的完整定义,btn中确实没有cursor声明,而全局:disabled仍会显示cursor: not-allowed。这更符合原生语义(<button>默认就是系统光标),若你的产品需要手型光标,请自行在组件层补充cursor-pointer。
8.3 按钮 hover 的实现细节与历史修复
buttons.css 中的 hover 效果值得注意:
@variant not-disabled { @variant hover { filter: brightness(125%); @variant dark { filter: brightness(75%); } } }它只对非禁用状态生效,且用filter: brightness()而非重新指定背景色,因此任何主题下的btn都能得到一致的明暗反馈。这与 v4 时代的两次修复一脉相承:v4 曾"将btn的all过渡改为专用过渡属性"(#3773)并"禁用状态下禁用 hover 样式"(#3757)。可见not-disabled守卫是经过多轮打磨后保留的设计决策。
九、其他移除项与迁移检查清单
9.1 移除card-hover工具类(#4417)
这是 5.0.0 明确列出的破坏性变更之一。通过搜索仓库可以确认:card-hover仅在 CHANGELOG.md 中被提及,utilities/cards.css 中已不存在该工具类。如果你的 4.x 代码中使用了card-hover,需要自行用标准的hover:变体实现等效效果(例如hover:brightness-105或hover:shadow-lg),或改用框架组件的 hover 样式。
9.2 从 4.x 升级到 5.0 的检查清单
综合本文件内容,迁移时建议按以下顺序排查:
- Tailwind 版本前置:确保项目升级到 Tailwind v4(
peerDependencies要求^4.0.0); - 主题文件重写:将旧格式主题转换为
[data-theme='xxx']+ 令牌覆盖的新格式,参考 themes/modern.css; - 按钮尺寸改名:
btn-icon-fab→btn-icon-3xl rounded-full;同时检查是否可从新增的btn-xs…9xl/field-xs…9xl中获得更精细的尺寸控制; - 移除
card-hover:改用标准 Tailwind hover 变体; - 确认
cursor: pointer预期:如需手型光标,自行添加cursor-pointer; - 利用新组件替换自定义实现:原生
<dialog>+dialog/animate-dialog、<details>+disclosure*、<meter>+meter、任意形状裁剪mask-*、圆角形状corner-shape-*; - 回归暗色模式:v5 大量使用
light-dark()配对变量(如--color-surface-200-800)与@variant dark,升级后重点检查亮暗切换场景。
9.3 历史版本脉络(供升级参考)
CHANGELOG 向后追溯也能看到两条对理解 v5 至关重要的历史主线:
- v3 主线(Tailwind v4 与 Zag.js):3.0.0 宣布支持 Tailwind v4,所有 Skeleton 组件整合 Zag.js(带来破坏性组件 API 变更),并在 Tailwind 插件中加入新 CSS 动画;3.2.0 新增
skb(skeleton-base)变体。5.0 的组件体系正是在此基础上演进的。 - v4 主线(核心收敛):4.0.0 将框架包的
@source规则内置(用户无需手动添加)、把可选preset样式合并进 core、新增 progress-circular/linear(对应 keyframes/progress-circular.css 中的progress-circular-indeterminate动画等)。
对大多数用户而言,只需关注 4.x → 5.x 的差异;若你还在 3.x,则需先消化 Zag.js 组件 API 变更再考虑升级。
十、总结
Skeleton 5.0.0 不是一次小修小补,而是围绕 Tailwind v4 对整条"主题—工具类—组件"链路的重构:主题改为[data-theme]令牌覆盖格式并全面 oklch 化(#4353/#4396),组件尺寸改为单一 CSS 变量驱动并覆盖xs–9xl全刻度(#4380/#4390),新增 Dialog、Disclosure、Mask、meter、Corner Shape 五类 Tailwind 组件(#4389/#4408),同时移除card-hover与btn-icon-fab、调整按钮光标与 hover 语义(#4417/#4367)。升级时对照本文第九节的检查清单逐项处理,即可平稳过渡;新项目则可以直接基于 v5 的变量化尺寸与配对变量体系,用更少的类名获得更协调、更易换肤的界面。
如需深入每个工具类的完整源码,可继续阅读 packages/skeleton/src 下的base/、themes/、utilities/、variants/与keyframes/目录,本文引用的文件路径均可直接查看。
【免费下载链接】skeleton
Skeleton is an adaptive design system powered by Tailwind CSS.
相关推荐
gulp 5.0 版本演进全解析:从 CHANGELOG 读懂流式构建系统的重大变更与升级路径
gulp 5.0 版本演进全解析:从 CHANGELOG 读懂流式构建系统的重大变更与升级路径 导读 :本文以 gulp 官方仓库的 CHANGELOG.md
构建工具CLIio-ts 版本演进全解析:从 CHANGELOG 看 TypeScript 运行时类型系统的设计变迁
io ts 版本演进全解析:从 CHANGELOG 看 TypeScript 运行时类型系统的设计变迁 io ts 是 TypeScript 生态中用于 IO(
后端@tanstack/react-query 5.102 版本演进解读:从 CHANGELOG 看预取 API 重构、Suspense 修复与类型系统强化
@tanstack/react query 5.102 版本演进解读:从 CHANGELOG 看预取 API 重构、Suspense 修复与类型系统强化 本指南
前端缓存状态管理
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考