多多读书
779 字
4 分钟
CSS实现旋转渐变边框动效按钮
2023-09-24

今天做一个花哨的动效,这种动效经常会在一些产品或个人网站上见到。它的特点是边框带有渐变旋转的效果。虽然制作起来不算难,但需要使用一些 CSS 属性,这些属性在平常的开发中并不常用,但非常有效。下面我将一步一步地解释如何制作这个动效。

准备一个按钮#

<button>
  <span>我是个按钮</span>
</button>
button {
  position: relative;
  padding: 20px 40px;
  border: 0;
  border-radius: 999px;
  font-size: 24px;
  color: #fff;
  --bg: radial-gradient(40% 50% at center 100%, hsl(270 0% 72% / 0.05), transparent), radial-gradient(
      80% 100% at center 120%,
      hsl(260 0% 70% / 0.1),
      transparent
    ), hsl(260 0% 12%);
  background: radial-gradient(40% 50% at center 100%, hsl(270 0% 72% / 0.05), transparent), radial-gradient(
      80% 100% at center 120%,
      hsl(260 0% 70% / 0.1),
      transparent
    ), hsl(260 0% 12%);
  overflow: hidden;
}

渐变效果#

我把上层遮罩去掉,应该很多人都看得出实现原理了。

其实,就是一个锥形渐变加上旋转动画。CSS 锥形渐变(CSS conic gradient)是一种用于创建圆锥形渐变效果的 CSS 背景样式。它允许你在元素的背景上创建一个从中心点向外辐射的渐变效果,类似于放射性波纹或圆锥。

使用 CSS 锥形渐变,你可以定义一个或多个颜色断点,并指定它们在渐变中所占的位置。这些颜色断点将按照一定的角度从中心点开始辐射状分布,形成一个圆锥形的渐变效果。

一个简单的示例:

所以,要表示上面的部分锥形,可以这样写:

background: conic-gradient(from 0deg, transparent, hsl(0deg, 100%, 50%) 60deg, transparent 61deg);
  • from 0deg:这是渐变的起始角度,通过改变这个值可以不同的位置偏移。
  • hsl(0deg, 100%, 50%):这里使用 HSL 表示色值,因为可以通过色相(H)角度不同改变颜色值。

旋转动画#

上面已经提到通过改变角度实现位置偏移和颜色,所以要给角度先定义一个变量。自定义变量采用的是@property。为什么不用形如--*定义呢?因为--*是定义在 CSS 选择器里面,选择器本身及其嵌套选择器都可以使用和改变,但是@keyframes动画规则并不在任何嵌套选择器内,所以更改值并不会生效。

@property --rotation {
  syntax: '<angle>';
  inherits: true;
  initial-value: 0deg;
}

然后,用变量替代角度值并在@keyframes内更改。

button::before {
  content: '';
  position: absolute;
  inset: 0;
  background: conic-gradient(
    from var(--rotation),
    transparent,
    hsl(var(--rotation), 100%, 50%) 60deg,
    transparent 61deg
  );
  animation: spin 2s infinite linear;
}

@keyframes spin {
  0% {
    --rotation: 0deg;
  }

  100% {
    --rotation: 360deg;
  }
}

在上面代码中用到了inset属性,inset 为简写属性,对应于toprightbottomleft属性,inset: 0相当于left: 0; right: 0; top: 0; bottom: 0;

显示边框#

上面的效果已经基本成型了,要是它显示成边框的效果,还要把中间部分盖住。

button::after {
  content: '';
  position: absolute;
  inset: 3px;
  border-radius: 999px;
  background: var(--bg);
}

文字显示#

上面的多次使用了position: absolute;,会改变层级导致文字被遮挡,所以还需要提升文字层级。

span {
  position: relative;
  z-index: 2;
}
CSS实现旋转渐变边框动效按钮
https://fuwari.vercel.app/posts/20230924/
作者
我也困了
发布于
2023-09-24
许可协议
CC BY-NC-SA 4.0