先附上另一大佬的链接https://segmentfault.com/a/1190000038911131,本文在该基础上做些调整,并详细讲讲background的用法
从ui拿到的需求是这样的,这张图的阴影效果不明显,但实际上从ui给的慕客上能看到同时有内外阴影

border: 2px solid #00b1ff;
box-shadow: 0px 0px 4px 0px #296fff, 0px 0px 8px 0px #00b1ff inset; 

请添加图片描述
本来一开始计划是使用切图,后来实在太多了,项目打包后的体积也越来越大,使用切图的效率越来越低,一咬牙一狠心,准备用css模拟出来;

分析 :

  1. 首先利用background实现无边框的无阴影的切角背景
  2. 用两张不同尺寸不同颜色的切角背景模拟出边框
  3. 给叠加的图形补充外阴影
  4. 补充内阴影

由于上图的效果不明显,用border:10px,边框颜色#5bdcfa,填充色#011032 做示例

1.实现用于边框的切角背景

在这里插入图片描述

    width: 200px;
    height: 100px;
    background: linear-gradient(135deg, transparent calc(10px + 4 * 0.414px), #5bdcfa 0) top left,
    linear-gradient(-135deg, transparent calc(10px + 4 * 0.414px), #5bdcfa 0) top right,
    linear-gradient(-45deg, transparent calc(10px + 4 * 0.414px), #5bdcfa 0) bottom right,
    linear-gradient(45deg, transparent calc(10px + 4 * 0.414px), #5bdcfa 0) bottom left;
    background-size: 50% 50%;
    background-repeat: no-repeat;

分析上面的代码,最重要的就是background里的四个渐变
以第一个渐变为例分析,实际是background-image与background-position的简写
因为background-size指定了每一个background-image的大小为div的50%,四个渐变刚好填满左上,左下,右上,右下四个位置
再来看渐变的参数,渐变的第一个参数135deg,指定了渐变方向;第二个参数 transparent 10px,指定透明与透明距离,第三个参数 #011032 0,指定填充颜色

2.两层切角背景模拟边框

在这里插入图片描述
在这里插入图片描述
利用伪类元素,用同样的方式制作一张尺寸小一些的切角背景,贴于边框背景上方,实现边框效果
有个细节需注意,两个切角背景尺寸不同,若切角大小相同,模拟出来切角边是实际边框尺寸的 2 \sqrt{2} 2
故切角背景应多切 2 − 1 \sqrt{2} - 1 2 1,约为0.414倍的边框尺寸进行补偿,示例中的边框尺寸为4px,故应补偿 4 ∗ 0.414 = 1.656 4 * 0.414 = 1.656 40.414=1.656px
第一张图是未进行补偿的情况,切角处的边框尺寸明显偏大

  .angle {
    width: 200px;
    height: 100px;
    background: linear-gradient(135deg, transparent calc(10px + 1.656px), #5bdcfa 0) top left,
    linear-gradient(-135deg, transparent calc(10px + 1.656px), #5bdcfa 0) top right,
    linear-gradient(-45deg, transparent calc(10px + 1.656px), #5bdcfa 0) bottom right,
    linear-gradient(45deg, transparent calc(10px + 1.656px), #5bdcfa 0) bottom left;
    background-size: 50% 50%;
    background-repeat: no-repeat;
    position: relative;
  }
  .angle:after {
    width: calc(200px - 2 * 4px);
    height: calc(100px - 2 * 4px);
    content: '';
    display: block;
    background: linear-gradient(135deg, transparent 10px, #011032 0) top left,
    linear-gradient(-135deg, transparent 10px, #011032 0) top right,
    linear-gradient(-45deg, transparent 10px, #011032 0) bottom right,
    linear-gradient(45deg, transparent 10px , #011032 0) bottom left;
    background-size: 50% 50%;
    background-repeat: no-repeat;
    position: absolute;
    left:4px;
    top:4px;
  }

3.补充外阴影

在这里插入图片描述
先看直接使用box-shadow的情况,如上图所示,阴影直接作用于div盒子上,而不是作用于背景上,露陷
解决办法是使用css的filte属性的drop-shadow属性 ,效果如下
在这里插入图片描述

filter:drop-shadow(0 0 12px rgba(149, 224, 242, 0.45))

4.补充内阴影

内阴影就要复杂多了,因为drop-show不支持内阴影,一个折中的办法是使用clip-path切掉box-shadow的内阴影,这里就不展开叙述了,可以点击顶部分享的链接查看,里面有详细的描述

完整demo

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Document</title>
</head>
<style lang="scss">
  html,
  body {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: black;
  }

  .angle {
    width: 200px;
    height: 100px;
    background: linear-gradient(135deg, transparent calc(10px + 4 * 0.414px), #5bdcfa 0) top left,
    linear-gradient(-135deg, transparent calc(10px + 4 * 0.414px), #5bdcfa 0) top right,
    linear-gradient(-45deg, transparent calc(10px + 4 * 0.414px), #5bdcfa 0) bottom right,
    linear-gradient(45deg, transparent calc(10px + 4 * 0.414px), #5bdcfa 0) bottom left;
    background-size: 50% 50%;
    background-repeat: no-repeat;
    position: relative;
    filter:drop-shadow(0 0 12px rgba(149, 224, 242, 0.45))
  }
  .angle:after {
    width: calc(200px - 2 * 4px);
    height: calc(100px - 2 * 4px);
    content: '';
    display: block;
    background: linear-gradient(135deg, transparent 10px, #011032 0) top left,
    linear-gradient(-135deg, transparent 10px, #011032 0) top right,
    linear-gradient(-45deg, transparent 10px, #011032 0) bottom right,
    linear-gradient(45deg, transparent 10px , #011032 0) bottom left;
    background-size: 50% 50%;
    background-repeat: no-repeat;
    position: absolute;
    left:4px;
    top:4px;
  }
</style>
<body>
<div class="angle">
</div>
</body>
</html>

留个问题,如何实现只有边框,无填充的效果?
上述方案中,一定需要填充色的遮挡才能实现边框,一旦无填充色,立马就露馅了。
其实可以采取和实现切角同样的方式,通过背景填充来实现,有人感兴趣我再更新

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐