一条CSS渐变,真能玩出花?从棋盘格到彩虹的实战技巧

3,409字
14–22 分钟
in

还在以为CSS渐变只能用来做背景过渡?那可太out了。一条渐变函数,不管是线性、锥形还是重复锥形,搭配几个参数就能整出棋盘格、网格线、虚线、彩虹、悬停下划线,甚至各种形状和边框装饰。下面直接上干货,把每个骚操作的完整流程掰开揉碎讲清楚。

目录

棋盘格

repeating-conic-gradient()开刀,两行代码搞定经典黑白棋盘。

.board {
  background: repeating-conic-gradient(#000 0 25%, #fff 0 50%) 
              0 / 100px 100px;
}

背后的逻辑:锥形渐变从0度开始,黑色占0到25%区域,白色占25%到50%,然后重复这个模式。background-size设成100px见方,每个小方格就是50px见方。想把格子调大?改100px数值就行。换颜色直接替换#000#fff

如果做成三角形图案,只需要改颜色断点位置。比如黑色0到12.5%,白色12.5%到25%,重复后每个正方形被对角线切分成两个三角形。

.triangle-pattern {
  background: repeating-conic-gradient(#000 0 12.5%, #fff 0 25%) 
              0 / 100px 100px;
}

操作时注意断点数值是整数倍关系,否则图案会错位。比如25%的一半是12.5%,50%的一半是25%,保持这种倍数关系才能严丝合缝。

网格线

conic-gradient()画一套可调行列数、线宽、单元格尺寸的网格。

.grid {
  --rows: 3;      /* 行数 */
  --cols: 5;      /* 列数 */
  --cell: 80px;   /* 单元格边长 */
  --thick: 2px;   /* 线宽 */

  width: calc(var(--cols) * var(--cell) + var(--thick));
  height: calc(var(--rows) * var(--cell) + var(--thick));
  background: conic-gradient(from 90deg at var(--thick) var(--thick), 
                #0000 25%, #000 0) 0 0 / var(--cell) var(--cell);
}

整个流程分三步走。第一步,定义四个CSS变量,方便后期修改。第二步,conic-gradient从90度方向开始,在(var(--thick), var(--thick))这个点切出四分之一象限,把25%到100%区域涂黑,其余透明。第三步,用background-size设成var(--cell) var(--cell),让这个图案重复平铺。每个重复单元会产出一条竖线和一条横线。

为什么宽高要加var(--thick)?如果不加,最右边和最下边会缺线。因为图案重复到最后一次时,线条刚好落在边界上,加上线宽就能多挤出一份重复,把缺失的线补齐。

如果想让列数自适应容器宽度,可以去掉--cols,改用round()函数。

.responsive-grid {
  --rows: 3;
  --cell: 80px;
  --thick: 2px;

  width: calc(round(down, 100%, var(--cell)) + var(--thick));
  height: calc(var(--rows) * var(--cell) + var(--thick));
  background: conic-gradient(from 90deg at var(--thick) var(--thick), 
                #0000 25%, #000 0) 0 0 / var(--cell) var(--cell);
}

round(down, 100%, var(--cell))会把容器宽度向下取整到--cell的整数倍,再补上线宽,网格就能完美撑满。

彩虹渐变

以往做彩虹要写一堆色标,现在CSS颜色插值新语法一条线搞定。

.rainbow {
  background: linear-gradient(90deg in hsl longer hue, red 0 100%);
}

拆解一下:in hsl告诉浏览器在HSL色彩空间做插值;longer hue表示色相走长路径绕一圈;起点和终点都是红色。因为色相是个圆环,从红色出发沿长路径绕一圈再回来,中间会经过黄、绿、蓝、紫等所有颜色。如果把linear-gradient换成conic-gradient,就能得到一个完整的色轮。

.color-wheel {
  background: conic-gradient(in hsl longer hue, red 0 100%);
}

实际使用时注意浏览器兼容性,新版Chrome、Safari、Firefox都已经支持。如果发现没效果,检查一下是不是写漏了in hsl或者longer hue

悬停效果

单条渐变做滑动下划线,比伪元素写法更轻量。

.slide-underline {
  background: linear-gradient(#1095c1 0 0) no-repeat
              var(--p, 0) 100% / var(--p, 0) 0.1em;
  transition: 0.4s, background-position 0s;
}

.slide-underline:hover {
  --p: 100%;
}

核心技巧:linear-gradient(#1095c1 0 0)生成一条纯色渐变条;no-repeat禁止重复;var(--p, 0) 100%控制背景位置,X轴由变量--p决定,Y轴固定在底部;var(--p, 0) 0.1em控制背景尺寸,宽度跟随--p变化,高度固定0.1em。鼠标悬停时把--p改成100%,下划线从左到右滑出。transition里把background-position过渡时间设为0s,防止位置变化产生位移动画,只让尺寸变化产生滑动感。

同样的原理还能做出从中间向两边展开、从下往上翻转等各种花式下划线,只要调整background-positionbackground-size的组合就行。

CSS形状

一条渐变切出锯齿边框、内凹圆角、闪烁星星和加号图标。以加号为例:

.plus {
  width: 50px;
  height: 50px;
  background: conic-gradient(from 90deg at 50% 50%, 
                #000 0% 25%, #fff 0% 50%, 
                #000 0% 75%, #fff 0% 100%);
}

conic-gradient从90度开始,在中心点(50% 50%)切分四个象限。黑色占0-25%和50-75%,白色占25-50%和75-100%。四个象限黑白交替,中心交叉点自然形成一个加号形状。调整宽高可以改变加号粗细,调整颜色可以换风格。

锯齿边框的实现稍微复杂些,需要结合background-sizelinear-gradient多次重复,但核心还是单条渐变做三角形堆叠。内凹圆角则用radial-gradient在四个角画透明圆,其余背景色填充。

边框魔法

border-image只能用一个渐变源,正好用来秀操作。比如做渐变叠加层:

.gradient-overlay {
  border: 30px solid transparent;
  border-image: linear-gradient(45deg, #f09, #00f) 1;
}

border-image会把渐变应用到边框区域,1表示把渐变分成九个区域(类似九宫格),然后拉伸填满边框。配合border: solid transparent可以做出各种异形边框。全宽背景效果稍微调整一下:

.full-width-bg {
  border-image: conic-gradient(from 90deg at 20% 50%, 
                #f0f, #0ff, #f0f) 1 fill;
}

加了fill关键字后,渐变不仅填边框,还会填满元素内部区域,相当于用一条渐变同时搞定背景和边框装饰。

标题分割线也常见:

.divider {
  border-image: repeating-linear-gradient(45deg, 
                #333 0 10px, #ccc 0 20px) 1;
  border-width: 0 0 4px 0;
}

只保留下边框,然后把重复线性渐变塞进border-image,虚线分割线就出来了,粗细和颜色随便调。

操作时务必注意border-image的切片规则,默认会把渐变按四角切分,1表示把每条边分成一份,适合简单图案。复杂图案需要调slices值,新手建议先用1试效果。