乐趣区

关于前端:CSS-SVG-绘制写作网格线的3种方式

欢送关注我的公众号:前端侦探

最近有共事问我这样一个问题:须要绘制一个自适应文本的写作网格线,设计稿是这样的

其实就是一行行虚线,要求如下

  1. 虚线的纵向距离要追随行高自适应,确保文本在每一栏虚线上
  2. 虚线前面的背景是动静的,能够是纯色,能够是突变,也能够是图片

绘制这样的虚线,看似容易,其实暗藏玄机,上面一起看看有哪些实现形式吧

一、纯色背景下的虚线

首先来看这种简略状况,大能够通过两层突变笼罩的形式实现。

假如文本行高是2,先绘制程度方向的

body{background: linear-gradient(#666 1px,transparent 0) 0 -1px/100% 2em;
}

留神,这里的背景尺寸是100% 2em,高度追随文字行高,所以高度是2em,成果如下

而后,绘制纵向的实线,盖在下面,为了辨别,先用一个浅红色来代替

body{background: linear-gradient(to right, #ffdbdb 4px,transparent 0) 0 -4px/8px 100%,  /* 垂直 */
    linear-gradient(#666 1px,transparent 0) 0 -1px/100% 2em; /* 程度 */
}

这样就绘制了一个垂直平铺,距离为 4px 的虚线,成果如下

应该比拟好了解吧,就是两个方向上的突变叠加

而后,将这个红色改成和底色雷同的色彩就行了,比方这里是红色

body{background: linear-gradient(to right, #fff 4px,transparent 0) 0 -4px/8px 100%,  /* 垂直 */
    linear-gradient(#666 1px,transparent 0) 0 -1px/100% 2em; /* 程度 */
}

这样就实现了纯色下的虚线网格,成果如下

二、突变背景下的虚线

如果不是纯色,而是突变的呢?假如有一个这样的背景

如果间接用后面的形式,可能就变成了这样

红色间接把背地的突变背景也笼罩了。

那如何解决这个问题呢?

像这种叠加混合的状况个别都会想到混合模式,没错,这里也能够通过混合模式简略解决。要用混合模式,必须要让这两层背景处于不同的容器中,而后应用mix-blend-mode

html{background: linear-gradient(45deg, #f5ffc0, #fff);
}

body{
  font-size: 20px;
  background: linear-gradient(to right, #fff 4px,transparent 0) 0 -4px/8px 100%, linear-gradient(#666 1px,transparent 0) 0 -1px/100% 2em;
  mix-blend-mode: darken;
}

这里应用了混合模式中的darken,这种模式能够去除红色局部,保留其余,成果如下

残缺代码能够查看以下任意链接

  • CSS dot line mix-blend-mode (codepen.io)
  • CSS dot line mix-blend-mode (runjs.work)

三、通过锥形突变绘制

上面再介绍一个比拟硬核的绘制形式:锥形突变(conic-gradient)

为什么说比拟硬核呢?因为这种形式绘制进去的图形就是完完全全的虚线,也没有混合模式的诸多限度。

首先咱们从图形上剖析,找到最小的反复单元,如下

找到了,就是这个,其实就是这个位于左上角的矩形,那么,如何通过锥形突变来绘制呢?

留神: 有同学可能会奇怪,这样一个矩形线性突变不是能够很轻松的实现吗?的确能够,然而只能实现一个,无奈平铺

看着如同不沾边,上面带你一步步演变

首先是最原始的语法

div{background: conic-gradient(#666, transparent);
}

这是一个从通明到灰色的突变,成果如下

这才是锥形突变的样子!

而后,咱们能够将突变的分界线调整一下

div{background: conic-gradient(#666 90deg, transparent 0deg);
}

这样就变成了一个边界明显的正方形

而后扭转起始角度,通过 from 关键词

div{background: conic-gradient(from 270deg, #666 90deg, transparent 0deg);
}

这样起始角度就会从 270deg 的中央开始,如下

接着,扭转中心点的地位,默认是程度垂直居中的,咱们要改到左上角,须要用到 at 关键词

div{background: conic-gradient(from 270deg at 40px 10px, #666 90deg, transparent 0deg);
}

这里改成了左上角 40px,10px 的中央,如下

最初,扭转背景的尺寸,默认是宽高 100% 的,咱们要改成理论须要的大小

div{background: conic-gradient(from 270deg at 40px 10px, #666 90deg, transparent 0deg);
  background-size: 80px 90px;
}

这样就会主动平铺开展,如下

原理就是这样,实际上的虚线比拟小,应该是4px 1px,所以理论利用应该是这样

div{background: conic-gradient(from 270deg at 4px 1px, #666 90deg, transparent 0deg);
  background-size: 8px 2em;
}

成果如下

残缺代码能够查看以下任意链接

  • CSS dot-line conic-gradient (codepen.io)
  • CSS dot-line conic-gradient (runjs.work)

四、动静 SVG 背景绘制

最初再来介绍一个实现起来最容易的形式,就是“切图”。

然而,这种“切图”不同于个别的切图,因为这个尺寸是动静的,要追随文字的行高变动而变动,所以须要采取肯定的“伎俩”。

首先在绘图软件中绘制这样一个图形,例如上面是 figma 中绘制的

里面的宽高无所谓,轻易设置。能够失去这样一段SVG

<svg width="10" height="10" viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg">
  <rect width="10" height="10" fill="none"/>
  <rect width="5" height="1" fill="#D9D9D9"/>
</svg>

而后,咱们将这个 svg 转换成内联 CSS格局

举荐张鑫旭老师的在线转换工具:SVG 在线压缩合并工具

间接用到背景上

body{
  font-size: 20px;
  background: url("data:image/svg+xml,%3Csvg width='10'height='10'viewBox='0 0 10 10'fill='none'xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 0h10v10H0z'/%3E%3Cpath fill='%23D9D9D9'd='M0 0h5v1H0z'/%3E%3C/svg%3E") 0 0/10px 2em;
}

成果如下

为啥这里的虚线都错位了呢?

这也是 SVG不同于惯例图片的一点,在内部背景尺寸超过 viewbox 尺寸后,SVG 画布会整体缩放,然而具体的元素并不会,具体表现是这样的

那么,有没有方法在画布缩放的时候,外面的元素依然位于左上角呢?就像这样

当然也是能够的,只须要将 viewbox 改为 0 0 100% 100% 就行了,或者罗唆删除(默认就是 100%),SVG的宽高也要改成100%,如下

<svg width="100%" height="100%" fill="none" xmlns="http://www.w3.org/2000/svg">
  <rect width="10" height="10" fill="none"/>
  <rect width="5" height="1" fill="#D9D9D9"/>
</svg>

这样一来,不论背景尺寸如何变动,外部的虚线地位都不受影响,成果如下

残缺代码能够查看以下任意链接

  • svg dot-line (codepen.io)
  • svg dot-line (runjs.work)

除了下面这种形式,还能够换一种思路,让默认的虚线是居中的,这样在放大后也是居中的,如下

这样在不扭转 viewbox 的状况下也能实现雷同的成果,有趣味的小伙伴能够上来试一试

五、总结一下优缺点

以上共介绍了 3 种齐全不同的绘制虚线的形式,原理各不相同,也有各自的优缺点,上面总结一下

CSS 突变混合模式 的长处在于实现思路比较简单,很容易想到,纯色背景优先举荐,毛病是混合模式有一些局限性,比方在彩色背景下可能须要换一种模式了

CSS 锥形突变 的长处在于代码实现简略,不受结构限制,毛病是有点不好了解,还有就是兼容性略微差一些

SVG 自适应背景 的长处在于应用简略,根本等同于“切图”,毛病是须要把握 SVG 的个性,而且无奈间接通过 CSS 扭转色彩,只能换图

综合来讲,如果兼容性没有要求,首推第 2 种形式,其次是 SVG 形式,最初才是混合模式

这几种形式你学会了吗?最初,如果感觉还不错,对你有帮忙的话,欢送 点赞、珍藏、转发❤❤❤

欢送关注我的公众号:前端侦探

退出移动版