目录
1.1 语法三兄弟:list-style-type、list-style-image、list-style-position
三、边框:从 border 到 border-image 再到 mask-border
一、列表样式:不止 disc
、circle
、square
1.1 语法三兄弟:list-style-type
、list-style-image
、list-style-position
最基础的写法依旧经典:
ul {
list-style: square inside;
}
type
控制符号;image
用图片替代符号;position
决定符号是在内容流之内 (inside
) 还是之外 (outside
)。
但 2025 年,我们有了更优雅的打开方式。
1.2 @counter-style
:自定义计数器系统
CSS Counter Style 规范早已落地 Chromium 与 Firefox。你可以像定义字体那样定义一整套计数符号:
@counter-style circled-alpha {
system: alphabetic;
symbols: Ⓐ Ⓑ Ⓒ Ⓓ Ⓔ Ⓕ Ⓖ Ⓗ Ⓘ Ⓙ;
suffix: ' ';
}
ol.awesome {
list-style: circled-alpha;
}
更进一步,还可以用 additive-symbols
、pad
、negative
、range
等属性做出复杂的法律条款、财务编号格式。
1.3 可访问性陷阱与解决方案
陷阱:
list-style: none
会让屏幕阅读器直接跳过列表语义。方案:保留语义,隐藏视觉符号:
ul.clean {
list-style: none;
/* 保留语义 */
}
ul.clean li::before {
content: ''; /* 不渲染任何符号 */
speak: never; /* 语音阅读器静音 */
}
1.4 高清屏下的 list-style-image
使用位图作为符号时,Retina 屏会发虚。2025 年的主流做法是:
使用
image-set()
提供多倍图;或者直接用 SVG 矢量图标:
ul.svg-marker {
list-style-image: image-set(
url('marker-1x.png') 1x,
url('marker-2x.png') 2x
);
/* 或者 */
list-style-image: url('marker.svg');
}
二、雪碧图:HTTP/2 时代的残响与新声
2.1 经典原理与时代背景
雪碧图的核心是 减少 HTTP 请求。在 HTTP/1.1 时代,浏览器并发连接有限,合并资源收益巨大:
优点:请求少、无闪烁、图片预加载;
缺点:维护难、定位繁琐、缓存颗粒度粗。
2.2 HTTP/2 多路复用:请求不再昂贵
2025 年,主流 CDN 与浏览器已全面启用 HTTP/2/3:
多路复用 让 100 张小图与 1 张大图耗时几乎相同;
头部压缩 消除了小文件冗余;
缓存失效 问题被放大:改 1 像素导致整图重下。
因此,纯 PNG 雪碧图正在退场。
2.3 SVG Sprite:向量时代的继任者
如果你仍需“合并”图标,SVG Symbol Sprite 是当前最优解:
<!-- sprite.svg -->
<svg xmlns="http://www.w3.org/2000/svg" style="display:none">
<symbol id="search" viewBox="0 0 32 32">
<path d="M20.2 18.4l6.3 6.3-1.8 1.8-6.3-6.3a12 12 0 11..."/>
</symbol>
</svg>
<svg class="icon"><use href="sprite.svg#search"></use></svg>
优势:
一条 HTTP 请求,gzip 压缩后仅数 KB;
矢量无限缩放,完美适配 Retina;
可通过
currentColor
随主题变色。
2.4 构建工具链升级
Vite 5 / Webpack 6 已内置 SVG Spritemap 插件,一行配置即可自动合并;
对 PNG 雪碧图,社区出现 自动化原子化 方案:将雪碧图拆回独立文件,配合 HTTP/2 Push 或
preload
,实现“按需并行”。
三、边框:从 border
到 border-image
再到 mask-border
3.1 基础属性回顾
div {
border: 1px solid #000;
border-radius: 8px;
}
可拆分为
border-width
、border-style
、border-color
;border-radius
支持 斜杠语法 分别控制 X/Y 轴:
border-radius: 10px / 20px; /* 椭圆角 */
3.2 outline
与 border
的六大差异
维度 | border | outline |
---|---|---|
是否占空间 | Y | N |
能否单独设置 4 条边 | Y | N |
能否圆角 | Y | N(Firefox 私有 -moz-outline-radius 除外) |
是否随焦点自动出现 | N | Y |
是否触发点击事件 | Y | N |
偏移控制 | N | outline-offset |
button:focus-visible {
outline: 2px solid royalblue;
outline-offset: 2px;
}
3.3 border-image
:把边框当画布
借助九宫格切图,你可以把一张 PNG 拉伸成任意边框:
.fancy {
border: 20px solid transparent;
border-image: url(frame.png) 30 fill / 30px / 10px round;
}
30
为切片值,fill
允许填充中心;/ 30px
设置边框厚度,/ 10px
定义外凸量;round
让角图案智能平铺。
3.4 渐变 & 遮罩边框
2025 年,所有现代浏览器已支持 border-image
直接接受渐变:
.gradient-border {
border: 5px solid;
border-image: linear-gradient(45deg, #f66, #fc0) 1;
}
更进一步,CSS Masking Level 4 草案带来 mask-border
:
.mask-border {
border-width: 30px;
mask-border: url(mask.png) 30 repeat;
}
它允许用一张透明模板定义边框的可见区域,轻松做出邮票锯齿、火焰边缘等效果。
3.5 边框与性能:重绘与重排
修改
border
会触发 重排(影响盒模型);修改
outline
仅触发 重绘(不占地);在滚动监听中,用
outline
做高亮可减少帧率抖动。
四、实战:一个“订单进度条”案例串烧三大主题
4.1 需求
横向步骤条:共 4 步;
当前步骤高亮,已完成的打勾;
移动端适配,图标高清;
圆角渐变边框,hover 时发光。
4.2 结构
<ol class="steps">
<li class="step done">提交订单</li>
<li class="step done">付款</li>
<li class="step active">发货</li>
<li class="step">收货</li>
</ol>
4.3 样式
@counter-style step-counter {
system: numeric;
symbols: '1' '2' '3' '4';
suffix: '. ';
prefix: 'Step ';
}
ol.steps {
display: flex;
gap: 1rem;
counter-reset: step 0;
list-style: step-counter inside;
}
.step {
flex: 1;
padding: 1rem;
border: 2px solid transparent;
border-radius: 12px;
background: linear-gradient(#fff, #fff) padding-box,
linear-gradient(135deg, #09f, #90f) border-box;
transition: outline-offset .2s;
}
.step.done::marker {
content: '✔ ';
color: seagreen;
}
.step.active {
outline: 2px dashed #ff6;
outline-offset: 4px;
}
@media (max-width: 600px) {
ol.steps {
flex-direction: column;
}
}
4.4 图标方案
使用 SVG Sprite 引入对勾图标,高清无损;
对老浏览器,
<picture>
提供 PNG 回退。
五、结语
列表样式 借助
@counter-style
成为设计系统的新拼图;雪碧图 在 HTTP/2 的浪潮里蜕变,把舞台交给 SVG;
边框 则凭借渐变、遮罩、逻辑属性,成为创意与性能的交汇点。