简体中文
浏览器支持
这套组件不靠 JS 补丁解决样式和浮层问题,而是直接用了浏览器自带的现代能力。好处是代码小、无障碍好、没有额外依赖;代价是有一条底线:太老的浏览器上会掉东西。
先把底线说清楚:
| 浏览器 | 最低版本 |
|---|---|
| Chrome、Edge | 123 |
| Safari(含 iOS) | 17.5 |
| Firefox | 120 |
这个底线是 light-dark() 定的,因为几乎每个颜色变量都写成 light-dark(浅色, 深色)。比它老的浏览器看不懂这个函数,会把整条声明丢掉,页面就只剩黑白和无色状态。
我们实际用到的特性
下面每一条都在 packages/core/styles 里真实出现过,不是照抄原版清单。
| 特性 | 用在哪 | Chrome | Safari | Firefox |
|---|---|---|---|---|
light-dark() | 所有主题颜色变量 | 123 | 17.5 | 120 |
@layer 分层 | 每份样式表的第一行,声明 astryx.* 五层顺序 | 99 | 15.4 | 97 |
:has() | 表单状态、列表、聊天、Tab 的父子联动样式 | 105 | 15.4 | 121 |
color-mix() | 计算悬停底色、滑杆、代码块等的过渡色 | 111 | 16.2 | 113 |
@property | 注册按压动画用的自定义属性,让它能做数字动画 | 85 | 16.4 | 128 |
| Popover API | 下拉菜单、提示、命令面板、Toast 视口:用原生 popover 和 popovertarget | 114 | 17 | 125 |
<dialog> + showModal() | 对话框、底部抽屉、大图查看 | 37 | 15.4 | 98 |
@starting-style | 浮层、抽屉、Toast 的入场动画起点 | 117 | 17.5 | 129 |
容器查询 @container | 分页、步骤条、聊天的窄宽自适应 | 105 | 16 | 110 |
text-wrap: balance / pretty | 标题平衡换行、正文避免孤字 | 114 | 17.5 | 121 |
:dir() | 滑杆等少数地方的方向判断 | 120 | 16.4 | 49 |
| 逻辑属性 | 内外边距、圆角、定位大量用 padding-inline-start 这类写法 | 87 | 14.1 | 66 |
@property 和 @starting-style 属于「没有也不崩」:缺了它们,按压动画和入场动画直接不播,界面照常能用。真正决定底线的是 light-dark()。
版本号按 MDN 和 caniuse 的记录写成,写这份文档时的数据;拿不准就去 caniuse 搜一下特性名。
低于底线会怎样
- 颜色全丢。
light-dark()认不出来,--astryx-color-*拿不到值,文字可能变成默认的黑色。 - 浮层还在,但可能不贴着触发器。 原生 popover 不支持时,菜单和提示还能打开,位置靠 CSS 兜底,不会那么准。
- 对话框可能打不开。
<dialog>的showModal()没有时,对话框组件没有降级路径。 - 动画不播。 入场、按压这类动效消失,内容照样显示。
没有一条会让页面白屏。但视觉按预期走不了,所以老浏览器不算支持。
想支持更老的浏览器怎么办
我们没有提供老浏览器专用的回退包,也没有内置 polyfill。可行的做法有三种。
1. 用户群很老,就守住底线。 内部工具通常能推浏览器升级,这是最省事的路径。
2. 用 @supports 探测,自己补一份颜色。 可以在应用入口检查 light-dark() 在不在,不在就给变量写死浅色值:
css
@supports not (color: light-dark(#fff, #000)) {
:root {
--astryx-color-text-primary: #000000;
--astryx-color-background-surface: #ffffff;
}
}这只补回颜色,浮层定位和动画不会因此变好。
3. 需要老浏览器上也完整可用,就得自己改。 包括引入 popover 和 @starting-style 的降级写法,或者在项目里重写相关组件的浮层实现。这类改造不在组件库的范围内。
我们已经替你处理的兼容细节
- iOS 输入框自动放大。 iOS 上输入框字号小于 16px 时,聚焦会自动放大页面。所有输入类组件在触摸设备上都把字号顶到至少
1rem,靠@supports (-webkit-touch-callout: none)只在 iOS 上生效。 - 减少动效。 全局有一条
prefers-reduced-motion: reduce规则,把入场和退场的位移、缩放、透明度变化压成「没有」,各组件也有自己的关闭规则。系统开了「减弱动态效果」,动画就不播。 - 滚动条。 滚动条样式集中在
scrollbars.css,靠overlayscrollbars这个运行时依赖实现,配色用color-mix()从文字色混出来,所以深色模式也能跟着走。
自己验一遍
在浏览器控制台里粘这段,能查到你手上这台浏览器缺哪几项:
js
const checks = {
'light-dark()': CSS.supports('color', 'light-dark(#fff, #000)'),
'@layer': CSS.supports('at-rule', '@layer a, b;'),
':has()': CSS.supports('selector(:has(*))'),
'color-mix()': CSS.supports('color', 'color-mix(in oklab, red, blue)'),
'Popover API': typeof HTMLElement.prototype.showPopover === 'function',
'@container': CSS.supports('container-type', 'inline-size'),
}
console.table(checks)有一项是 false,就对照上面的表格看这一项影响什么。light-dark() 是 false 时,页面颜色基本不可用。