摘要
在网页设计中,给文字添加下划线、上划线这类装饰时,它们常常不自觉地延伸到文字首尾之外,导致视觉上像是错位了一样。以前想解决这个麻烦,要么用伪元素模拟,要么干脆放弃原生装饰的便利。现在CSS里的text-decoration-inset属性专门来收拾这个烂摊子,它能精准控制装饰线两端往里缩进多少,让线条稳稳当当贴住文字边缘。不只是对齐,还能用它玩出各种花里胡哨的动画效果,让下划线像流星一样划过去。
困扰多年的对齐强迫症终于有药了
做页面的时候,给链接或者重点文字加个下划线,看起来再正常不过的操作。但是吧,仔细盯着看就会发现,那条下划线总是比文字长出那么一截,往左边伸出去一点,右边也多出来一点。要是文字开头是个“N”,左边那截就杵在“N”左腿的前面,看着就跟没对齐似的。
这个毛病从网页诞生那会儿就跟着了,一直没个原生方法根治。以前大家怎么搞?要么直接把下划线藏了,用伪元素:after自己画一条背景。这么干倒是能对齐,但是原生的text-decoration-thickness控制粗细、text-underline-offset调节偏移距离这些香喷喷的功能可就全丢掉了,不划算。
现在text-decoration-inset来了,专治这种装饰线伸太长的毛病。它就像给装饰线两端装了个“收边条”,左右两边各缩进去多少,自己说了算。
给装饰线加收边
text-decoration-inset的写法特简单,给它两个长度值就行:第一个是左边缩进去多少,第二个是右边缩进去多少。
a {
text-decoration: underline;
text-decoration-inset: 0.076em 0.009em;
}左边缩进去0.076em,右边缩进去0.009em。为啥用em单位?因为这个单位跟着文字字号走,字号变了,缩进量也跟着变,省事。上面这个数值是专门调的,刚好让下划线左端贴着“N”字左腿的根部。要是第一个字母换成“W”,那这个数就得重新调,因为字母形状不一样。
这里面有个小坑,text-decoration-inset只认长度值,什么百分比、auto都不好使。所以调的时候只能拿em、px、rem这些硬数字去试。可以开个浏览器开发工具,一边改一边看,调到视觉上对齐为止。这个数一旦定下来,除非换字体或者换文字内容,基本不用再动。
让下划线玩出新花样
光对齐还不够,这玩意儿还能动起来。以前做下划线动画,要么靠transform缩放伪元素,要么用背景渐变。现在直接在原生下划线上就能搞。
先看个简单的,鼠标滑过时让缩进量变大:
a {
transition: 300ms;
text-decoration: underline;
text-decoration-inset: 0.046em 0.009em;
}
a:hover {
text-decoration-inset: calc(0.046em * 10) 0.009em;
}鼠标一上去,左边缩进直接乘以10,下划线“蹭”地一下就缩成一短条,看着挺带劲。不过这里要注意,calc里面的倍数得用数字,不能塞百分比进去。
再搞个猛的,做个流星划过的下划线效果:
a {
text-decoration: underline;
text-decoration-inset: 0.046em 0.009em;
}
a:hover {
animation: 1s shooting-star;
}
@keyframes shooting-star {
50% {
text-decoration-inset: 4.5em 0.009em;
text-decoration-color: transparent;
}
50.999% {
text-decoration-inset: 0.046em 4.5em;
}
}这个动画的思路是:动画走到一半的时候,左边缩进改成4.5em(这个数是元素的宽度),右边保持不变,同时让线条颜色变透明。紧接着在50.999%这个节点,瞬间把左边缩进调回原值,右边缩进改成4.5em。然后从50.999%到100%,左边缩进保持原值,右边缩进从4.5em慢慢变回0.009em。效果看起来就像一条线从左边扫到右边,再从右边滑回来。
4.5em这个数怎么来的?得量一下那个链接文字到底多宽。每个链接宽度不一样,动画里的缩进值就得跟着调。想省事可以用JavaScript动态算宽度再设置到CSS变量里,但要是元素宽度固定,直接写死也成。
上划线也能一起玩
不只是下划线,上划线、删除线同样能这么搞。比如搞个上下都有线的文字,两条线各自缩进,整整齐齐:
h1 {
text-decoration: overline underline;
text-decoration-thickness: 0.1em;
text-decoration-inset: 0.08em 0.02em;
}这里text-decoration-inset同时作用在上划线和下划线上,两头都缩进去,看起来就像给文字套了个框。
玩text-decoration-inset的时候,记得搭配text-underline-offset一起用。offset管的是线条离文字多远,inset管的是线条两头缩多少,俩配合起来才能调出最顺眼的样式。比如想让下划线离文字近一点,offset设成0.1em,同时把inset也调一下,让线条刚好藏在文字边缘下面,看着就像文字自带的阴影。
浏览器支持这块,目前Firefox 146+已经上了,其他浏览器还在路上。用的时候可以加个@supports做一下特性检测,不支持的浏览器回退到普通下划线,至少不会把页面搞崩。
