出现抖动现象背后的原因
比如你可能会遇到这样的场景,就是有一个div块,当鼠标悬浮的时候,需要添加一个border(比如多个div块以卡片的形式排列起来)。你可能会考虑写成这样的CSS:
div:hover {border: 1px solid blue}
但是这样写会导致一个问题,就是div块之间比如说间距是3px,这时候加了一个border,间距可能会变成4px。div块之间间距突然拉大(比如说那种多个卡片场景),从视觉上来看就好像页面的div块间发生了抖动。你可能会考虑使用box-sizing: border-box
来解决这个问题,这个时候如果content里没有东西还好,如果有内容,突然增加的border也会导致内容发生一点抖动现象。
对于这个抖动问题的解决原则就是让各个块或者内容之间的距离始终保持不变,距离不变就不会发生抖动。如何让距离保持不变呢?可以先用transparent
这个特性来做一个占位。
一个简单场景
简单场景是之前没有border,悬浮或者点击之后添加border。可以写成这样:
div {border:1px solid transparent;}div:hover {border:1px solid red;}
更复杂的场景
现在考虑一个更复杂的场景,刚开始有一个边框是1px,你希望鼠标悬浮之后边框变成3px。比如类似于这样,要求边框是有圆角的:
这时候就没有办法通过transparent来解决这个问题了,因为边框是始终存在的,只是粗细发生了变化。这个问题的一个比较容易的解决方案是通过box-shadow
来构造多重边框,对于内部边框先transparent,然后鼠标悬浮时再显示。特别的在MDN文档中有这么一段内容:
If a border-radius is specified on the element with a box shadow, the box shadow takes on the same rounded corners.
所以,我们用box-shadow时并不需要担心圆角问题,它会继承过来。考虑使用inset,像这样:
如果想在之前的边框里面加一个边框,做成多重边框,可以写成这样:
box-shadow: inset 0 0 0 10px gold;
最后,你只需要将内边框提前设置好,并将颜色设置为transparent,当鼠标悬浮时将其设置为和外边框一样的颜色,就可以解决抖动问题了。
参考资料
[1] css 对div用hover设置border,出现抖动和div走位问题,解决方法
[2] box-shadow
[3] CSS3实现多重边框的方法总结