Loading...
Loading...
- 最后编辑:2025/10/20 06:46:48 -
Loading...
今天在完善博客显示效果的两个小问题时,偶然间发现了一个有点冷门但却比较实用的CSS属性:box-decoration-break。
今天在使用博客的时候,发现了一个比较细节,但是有点影响视觉效果的问题:

如图所示,当博客标题文本过长时,浏览器会自动将其裁断成多行文本,但由于代码逻辑的原因,下划线无法跟随文本一起被裁断,只能显示最底下的一行,这就导致这个标题并没有展示出一个超链接该有的样子,而且也不好看。
因此,我就开始着手解决这个问题,但没想到解决的过程却比我想象中的还要复杂得多。
最开始,我是使用::after伪类实现的这个下划线,因为border本身并不支持渐变色,所以我只能将渐变样式添加到伪类的背景色上,然后动态显示。但正如我在上一篇博客:关于CSS中某些无法插入伪类的HTML标签 中提到过的,伪类的本质是一个插在标签内的子元素,不属于标签本身的属性。因此,它不能随着父元素文本的裁断而自动发生变化。
所以我就开始寻找一个折中的方案,在不改变原有效果的前提下,给下划线添加多行显示的功能。
起初,在AI的推荐下,我试着采用text-decoration-color样式对下划线进行修改,抛弃::after伪类,直接将下划线作为文本标签本身的样式属性,并在不支持这种写法的浏览器上使用纯色代替:
.blog-title {
text-decoration: underline;
text-decoration-thickness: 2px;
text-underline-offset: 2px;
text-decoration-color: #0070f3;
@supports (background: linear-gradient(to right, red, blue) text) or
(text-decoration-color: linear-gradient(to right, red, blue)) {
text-decoration-color: linear-gradient(90deg, #ff6b6b, #4ecdc4);
}
}但很快,我就发现这个方案并不奏效,因为text-decoration-color本来就不支持linear-gradient属性,更别说渐变色了。
接下来,我试着采用background-image的方法模拟下划线,利用这个样式在文字下方绘制一条细的渐变条,然后再通过 background-size 和 background-position 精确控制位置:
.blog-title {
text-decoration: none;
background-image: linear-gradient(
to right,
var(--tw-gradient-from, #2563eb),
var(--tw-gradient-to, #a855f7)
);
background-repeat: repeat-x;
background-position: 0 100%;
background-size: 1px 2px;
color: inherit;
padding-bottom: 2px;
line-height: 1.5;
}结果还是不行,虽然渐变色的效果有了,但它还是不会自动换行,与之前的效果大差不差,因此被我抛弃了。
在这之后,我折腾了好几次,依旧无法解决这个问题。我在AI和MDN文档之间周周转转,试图寻找一个合适的解决方案,结果在一次偶然的尝试中,还真给我发现了一个方案:box-decoration-break。
box-decoration-break,从它的名字上看,顾名思义,就是指元素在发生断行时其样式的表现形式。
这里借用一段我在稀土掘金上找到的关于这个样式的通俗解释【原文链接】:
- box -- 盒,可以理解为元素盒模型
- decoration -- 装饰,理解为元素样式
- break -- 断行,参考
word-break,理解为断行时候的表现
这个样式的取值有两个:
还是使用稀土掘金上举得两个例子来直观的展示一下这两个属性的区别:
这是一段文本:

当它发生换行时,这是box-decoration-break:slice的效果:

而这是box-decoration-break:clone的效果:

由此可见,当内容发生换行时,slice属性会根据宽度,直接将它的边框截断,而clone属性则会在每一行重新渲染一次完整的边框。
当然了,不止边框,它的作用范围非常宽泛,支持修改很多属性:
所以很显然,这个属性天然的符合我的需求!
于是我快速的将它应用到了我的样式中,并使用border-image来绘制下划线:
.blog-title {
border-bottom: 3px solid transparent;
border-image: none;
box-decoration-break: clone;
transition: all .3s;
}
.blog-title:hover {
border-image: linear-gradient(
to right,
var(--tw-gradient-from, #2563eb),
var(--tw-gradient-to, #a855f7)
) 1;
box-decoration-break: clone;
transition: all .3s;
}然后我满怀期待的打开浏览器,却发现它并没有生效,下划线依旧只有一行。
这是怎么回事?为什么这个属性在我的页面上不生效呢?我明明再三确认过box-decoration-break能够作用在border-image上,但是如今为什么又不生效了呢?
最终,在MDN的官方文档中,我找到了答案:box-decoration-break只适用于内联元素,即该标签的display样式值应该为inline,否则样式就会无法生效。
而在我的页面中,博客标题.blog-title的父元素.blog-card被设置成了flex布局,那么作为它的子元素,.blog-title的display样式自然就会被隐式的设置为flex-item,而不是inline。
到此,问题的根源就已经水落石出了,我在.blog-title的外层包上了一圈div,那么这个div就会作为flex-item元素存在,而.blog-title则是它的内联元素,大功告成!
最后放一下完整的代码:
.blog-title {
cursor: pointer;
color: #3f3f3f;
display: inline;
border-bottom: 3px solid transparent;
border-image: none;
box-decoration-break: clone;
text-decoration: none;
line-height: 50px;
transition: all .3s;
}
.blog-title:hover {
border-image: linear-gradient(
to right,
var(--tw-gradient-from, #2563eb),
var(--tw-gradient-to, #a855f7)
接着打开浏览器验证一下效果:

完美!
不出意外的话,这个效果将会在网站下次更新后一起上线,不过我也不知道我会什么时候更新(bushi
2个月前
6天前