神奇的CSS之clip-path

360 阅读2分钟

介绍

clip-path 属性创造一个剪切区域,内容在该区域是可见的,而该区域之外是隐藏,举个栗子:

image-20220729172459028

矩形内的可见区域仅为蓝色圆圈,其他地方都是不可见的。

clip-path的值

矩形(inset)

用法:inset(20px 50px 10px 0 round 50px)20px 50px 10px 0 四个值分别为上右下左四条边到元素边界的距离,round 50px 是可选的,用来定义圆角,

image-20220729173204698

圆(circle)

用法:clip-path: circle(100px at 100px 100px),at 前的 100px 代表半径,后面的 100px 100px 代表圆心坐标。

image-20220729173520618

椭圆(ellipse)

用法:clip-path: ellipse(100px 80px at center),at 前的 100px 80px代表椭圆的 x 轴 y 轴长度,后面的 center 代表圆心。

image-20220729173813826

多边形(polygon)

用法:polygon(5% 5%, 95% 5%, 95% 95%, 5% 95%),polygon参数代表着一个个点,clip-path 通过这些点连成的路径进行裁切:

image-20220729181411964

路径(svg)

clip-path 还允许我们使用 svg 路径来剪辑特定区域,可以使用内联 svg 或者直接利用 path():

<svg>
  <clipPath id="love" clipPathUnits="objectBoundingBox">
    <path d="M10,30 A20,20,0,0,1,50,30 A20,20,0,0,1,90,30 Q90,60,50,90 Q10,60,10,30 Z"></path>
  </clipPath>
</svg>
<style>
.clip {
  clip-path: path("M10,30 A20,20,0,0,1,50,30 A20,20,0,0,1,90,30 Q90,60,50,90 Q10,60,10,30 Z");
  /* clip-path: url("#love"); */
}
</style>

image-20220729183924267

案例

边框线条特效

随便写段文字然后用 after 给它套上边框:

div {
  position: relative;
  background-color: #686de0;
  padding: 5px 20px;
  color: #fff;
  border-radius: 5px;
}

div::after {
  display: block;
  content: '';
  position: absolute;
  top: -5px;
  bottom: -5px;
  left: -5px;
  right: -5px;
  border: 2px solid #686de0;
}

image-20220729185404491

接下来可以用上面介绍过的 clip-path: inset(bottom, right, top, left) 来实现效果,先随便写个看看效果:clip-path: inset(0 95% 0 0)

image-20220729185943828

我们要做的动画是线框 top -> right -> bottom -> left,分别对应 0% 25% 50% 75%:

div::after {
  animation: flow 3s infinite linear;
}

@keyframes flow {
  0%, 100% {
    clip-path: inset(0 0 95% 0);
  }
  25% {
    clip-path: inset(0 95% 0 0);
  }
  50% {
    clip-path: inset(95% 0 0 0);
  }
  75% {
    clip-path: inset(0 0 0 95%);
  }
}

GIF 2022-7-29 19-08-33

除了 after 外还有个 before,我们可以做个双流动的特性,加上延迟防止重合即可:

div::before {
  animation: flow 3s infinite -1.5s linear;
}

为了不让颜色太单调了,我们使用 filter: hue-rotate() 和渐变色来改善下:

GIF 2022-7-29 19-20-36

完整代码:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>clip-path</title>
  <style>
    #app {
      display: flex;
      justify-content: center;
      align-items: center;
      width: 600px;
      height: 400px;
      background-color: #f1f2f6;
    }

    div {
      position: relative;
      background-color: #686de0;
      padding: 5px 20px;
      color: #fff;
      border-radius: 5px;
    }

    div::before,
    div::after {
      display: block;
      content: '';
      position: absolute;
      top: -5px;
      bottom: -5px;
      left: -5px;
      right: -5px;
      border: 2px solid;
      border-image: linear-gradient(135deg, #f02fc2, #6094ea) 1;
    }

    div::before {
      animation: flow 3s infinite -1.5s linear;
    }

    div::after {
      animation: flow 3s infinite linear;
    }

    @keyframes flow {
      0%,
      100% {
        clip-path: inset(0 0 95% 0);
        filter: hue-rotate(0);
      }
      25% {
        clip-path: inset(0 95% 0 0);
      }
      50% {
        clip-path: inset(95% 0 0 0);
        filter: hue-rotate(360deg);
      }
      75% {
        clip-path: inset(0 0 0 95%);
      }
    }
  </style>
</head>
<body>
  <main id="app">
    <div>Hello World!</div>
  </main>
</body>
</html>

参考

Understanding Clip Path in CSS - Ahmad Shadeed (ishadeed.com)

clip-path的神奇妙用 - 掘金 (juejin.cn)