背景简介
大家好,我是石小石!最近开发中遇到这样一个需求:
hover卡片后,边框由原来的1px变成2px,且颜色由灰色变为蓝色。
hover改变样式,这太easy了!
.work-order-card {
padding: 8px 16px 16px 16px;
border-radius: 8px;
border: 1px solid #e1e5eb;
width: 296px;
transition: all 0.2s ease;
&:hover {
border: 2px solid #64A6F7;
transition: all 0.2s ease;
}
}
但实际做完后,我们会发现一个问题,样式不够丝滑:
hover后元素的内边距发生变化,中间区域尺寸被挤压,从而导致过渡动画很生硬!
这个问题在前端开发中应该比较常见,我就简单分享一下自己的解决方案吧。
如何解决
要想解决这个问题,本质就是让hover前后,中间核心区域的位置不随边框、边距的变化而变化。
场景一:边框从无到有
最简单的场景,就是一开始没有边框,后来有边框。
这种最容易处理,我们只需要给盒子设置和hover后同样粗细的边框,颜色设置透明即可。
.work-order-card {
padding: 8px 16px 16px 16px;
border-radius: 8px;
border: 2px solid transparent;
width: 296px;
transition: all 0.2s ease;
&:hover {
border: 2px solid #64A6F7;
transition: all 0.2s ease;
}
}
场景二:边框粗细发生变化
比较麻烦的场景,如文章一开始说的场景,hover后,边框从1px变成2px。这种情况,hover盒子的padding一定会变化(注意大盒子尺寸是固定的),必然会导致内部元素被挤压,位置改变。
动态padding
当然,聪明的你可能计算hover后的padding
.work-order-card {
padding: 8px 16px 16px 16px;
border-radius: 8px;
border: 1px solid #E1E5EB;
width: 296px;
&:hover {
padding: 7px 15px 15px 15px;
border: 2px solid #64A6F7;
}
}
不加过渡动画时,看着挺不错
但加上transition过渡效果,那就原形毕露!
.work-order-card {
padding: 8px 16px 16px 16px;
border-radius: 8px;
border: 1px solid #E1E5EB;
width: 296px;
transition: all 0.2s ease;
&:hover {
padding: 7px 15px 15px 15px;
border: 2px solid #64A6F7;
transition: all 0.2s ease;
}
}
不设置padding,居中核心内容
如果盒子的尺寸都能确定,最好的方式,还是使用flex布局,让中间的核心区域(下图红色部分)永远居中!这样,无论边框怎么变,中间的位置永远不变,自然就解决了元素被挤压的问题!
<div class="work-order-card">
<div class="center-box">
<!-- 子元素 -->
</div>
</div>
.work-order-card {
border-radius: 8px;
border: 1px solid #E1E5EB;
width: 296px;
height: 214px;
transition: all 0.2s ease;
&:hover {
border: 2px solid #64A6F7;
transition: all 0.2s ease;
}
.center-box{
width: 264px;
}
}
注意:这种实现方式,要求最外层的盒子宽高是固定的,内部盒子宽度也需要固定。
总结
针对hover某个元素,其边框变粗导致内部元素被挤压的问题,这篇文章提供了三个解决方案:
- 边框从无到有,改变原始边框透明度即可
边框hover尺寸变化:
- 如果不要求过渡效果,hover后可以计算padding
- 如果需要过渡效果,使用felx布局居中核心区域即可
如果大家有更好的方案,可以评论区分享一下。