你所不知道的n种css边框实现方式

1,552 阅读4分钟

前言

我们在做前端开发的时候经常会碰到需要给元素加上边框效果的需求,尤其是在一些list,grid等的批量数据展示时候item的hover的时候。如下图是唯品会商品的hover态: image.png 强大的css有很多种方式可以实现实现这种边框效果。如:border,outline,boxshadow,伪元素border等。下面,我就给大家介绍一些我所知道的实现方式及其差别。

border

说到边框实现,大家可能第一反应就是通过border属性来实现。鉴于这是一种很常见的实现方式,我就直接说一下在实际开发过程中使用border实现边框肯能带来的弊端。上demo:

<html>
<head>
</head>
<body>
<div class="container">
  <img src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fwx3.sinaimg.cn%2Fmw690%2F005B96Eqly1gtu73qmbp4j60dw09qt9j02.jpg&refer=http%3A%2F%2Fwx3.sinaimg.cn&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1635486191&t=c6a8a64ce66fbb6ea61256e0a828380d"/>
</div>
</body>
</html>
.container {
  width: 500px;
  height: 350px;
}

img 
{
  width: 100%;
  height: 100%;
  border: 2px solid rgb(250,0,255);
}

效果如下: image.png 咋一看效果很正常,其实这里出现了一个问题,那就是border会占空间,也就是说各元素得给border腾出空间来。demo中的container的宽度是500px,而因为加了border,img的宽度达到了504px。如果container设置了overflow:hidden。那显示效果将会变成这样: image.png 这就是因为border占用空间导致整个图片的尺寸变大的问题。为了避免这个问题,我们修改一下img的盒模型:box-sizing: border-box;让img的border包括在其尺寸内: image.png 如上图,这时候右边和下面的border就不会被截掉了,但是图片的整体会被缩小。这种情况如果是在商品列表这种hover之后才显示边框的场景的话,会有一种hover上显示边框的同时图片突然缩小的效果,这种效果往往感官上会觉得不太和谐。

outline

下面来介绍一种不会占用空间的边框实现方式:outline。mdn上也有其与border的比较说明: image.png 我们把上面demo的border改成outline:

img 
{
/*   order: 2px solid rgb(250,0,255); */
  width: 100%;
  height: 100%;
  outline: 2px solid rgb(250,0,255);
}

效果如下: image.png 这时候我们把container的overflow设为hidden: image.png 发现边框不见了,说明,outline不占用空间的代价是以显示在元素外围为代价,如果父容器设置了overflow: hidden;边框就会不可见。或者如果有相邻的元素,那么ooutline就会与相邻的元素重叠: image.png

box-shadow

有个比较骚的方式是通过box-shadow来实现,只需要将偏移量和模糊半径都设成0就可以,如:box-shadow: 0 0 0 2px rgb(250 0 255);。这种方式实现起来的效果和outline差不多。缺点就是占用了阴影的设置,如果这个元素还需要在加阴影的话就没法实现了。

伪元素

下面介绍一种笔者认为副作用最小,最容易控制也是在复杂场景下笔者最推荐的实现方式。那就是通过在元素上盖上一个伪元素来实现。直接上代码:

<html>
<head>

</head>
<body>
<div class="container">
  <div class="img-wraper">
  <img src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fwx3.sinaimg.cn%2Fmw690%2F005B96Eqly1gtu73qmbp4j60dw09qt9j02.jpg&refer=http%3A%2F%2Fwx3.sinaimg.cn&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1635486191&t=c6a8a64ce66fbb6ea61256e0a828380d"/>
    </div>
</div>
  <div class="box2"></div>
</body>

</html>
.container {
  width: 500px;
  height: 350px;
}

img 
{
/*   border: 2px solid rgb(250,0,255); */
  width: 100%;
  height: 100%;
/*   outline: 2px solid rgb(250,0,255);
  box-shadow: 0 0 0 2px rgb(250,0,255); */
}
.img-wraper{
  width: 100%;
  height: 100%;
  position: relative;
}
.img-wraper:before {
  box-sizing: border-box;
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  border: 2px solid rgb(250,0,255);
}
.box2{
  width: 600px;
  height: 350px;
  background: green;
}

效果如下: image.png 可以看到这种方式实现的边框是盖在元素上面的,好处是它不会额外占用空间,同时他也不会挤压图片导致图片缩小。这样在父容器设置了overflow:hidden,或者有紧邻的元素的情况下也都不会有问题。这种方式在鼠标hover到元素之后才显示边框的场景下特别好用,出现和消失都会非常自然。

后记

以上就是本人在日常工作中常见的边框的实现方式及其各自的优劣。大家有更好的见解也欢迎在评论区留言交流哦~