网页下划线老跑偏,这该死的对齐问题到底咋整?

1,866字
8–12 分钟
in

摘要提到下划线装饰,大家做网页时肯定遇到过。默认的下划线总爱超出文字两端,看着就像戴了个不合身的领带,歪歪扭扭的。尤其对设计细节抠得比较细的人来说,这简直逼死强迫症。以前想对齐,要么用::after伪元素手搓一个,但那样又得自己控制粗细和位置,特别折腾。现在CSS新出的text-decoration-inset属性,专门用来收拾这个烂摊子,它能从左右两端把下划线往里收,让装饰线和文字边缘严丝合缝。在火狐浏览器146及以上版本已经能用,这玩意儿不仅能让下划线对齐,还能玩出各种骚气的动画效果。

目录

对齐神器是个啥

text-decoration-inset这哥们儿,以前叫text-decoration-trim,看名字就知道它是干啥的——专门修剪文本装饰线两端多余的部分。以前那条横线是从盒子最左边画到最右边,现在通过这个属性,能精准控制从两端往里缩多少。语法也很直接,可以分别设置左边缩进和右边缩进,中间用空格隔开。值必须是长度单位,比如像素、em啥的。用em单位的好处是跟着字体大小走,缩放完全自适应,不用反复调。

基础对齐咋操作

想让下划线和文字边缘完美贴贴,得先搞清这个缩进怎么算。比如一个“N”字母开头的单词,左边那个竖杠就是对齐基准线。在代码里设置text-decoration-inset: 0.076em 0.009em;,左边缩进0.076倍字体大小,右边缩进0.009倍,效果就出来了。这个数值得根据字体手动试,换一种字体可能就得重新调。

.fancy-link {
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 4px;
  text-decoration-inset: 0.076em 0.009em;
}

不过得注意,要是开头字母换成“W”,两边就不是对称的了,这个方案更适合内容固定的场景,比如按钮文字、导航菜单这些写死的文案。要是动态内容,缩进可能就对不齐,属于那种“提前知道敌人长啥样就能精准打击”的玩法。

搞点动画整活

静态对齐只是开胃菜,text-decoration-inset真正好玩的是能配合transitionanimation做动画。之前想实现下划线滑动效果,得用伪元素折腾半天,现在原生就能搞定。比如鼠标悬停时,让下划线左右两边同时往外扩,产生一种“膨胀”的视觉效果。

a {
  transition: 300ms;
  text-decoration-inset: 0.046em 0.009em;
}
a:hover {
  text-decoration-inset: calc(0.046em * 10) calc(0.009em * 10);
}

这个例子里,悬停时左边缩进变成原来的10倍,右边也放大,下划线就像突然撑开了一样。要注意calc()里乘的数得是纯数字,单位得统一,不然浏览器会懵。

流星划过效果

再玩点花的,搞个流星划过下划线的动画。原理是在动画中让左边缩进先飞到最右边,等跑到一半多的时候,瞬间把右边缩进也扔到左边去,造成一种“线头从这边跑到那边”的假象。关键点在于宽度得用固定长度,比如元素宽度是4.5em,就把缩进值设成这个数,让装饰线刚好从一端滑到另一端。

a {
  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;
  }
}

动画跑到一半时,左边缩进拉到最右,下划线颜色还变透明;到50.999%这一帧,右边缩进猛拉到左边,产生一种“折返跑”的既视感。这种细节动画放在链接或者按钮上,交互感直接拉满。

组合技玩法

这属性不光是单打独斗,跟text-decoration-thickness(控制线条粗细)和text-underline-offset(控制偏移距离)组队,能搞出更多花样。比如做个上划线加下划线的双重装饰,左右两边都对齐,再配上不同粗细,设计感就出来了。但有个小坑,text-decoration-inset目前只在火狐146+版本生效,其他浏览器得等等,做项目时得想好降级方案。不过对于追求细节的前端玩家,这已经足够香了,原生能解决的绝不手写伪类。