乐趣区

关于css:SVG-绘制自适应的菱形

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

最近在某思看到这样一个问题:须要绘制一个自适应尺寸的菱形,并且还有边框,个别在流程图中很常见,成果如下

如果没有边框的话,用 CSS clip-path 也能很不便的裁剪出一个菱形,然而边框不太好解决(通常用嵌套一层的形式或者投影来模仿,然而成果不太好),这里介绍一个 SVG 形式,充分利用缩放个性来实现这样一个成果

一、SVG 从何而来

SVG 通常都不须要手写代码(除大量根本形态以外),个别都能够用设计软件生成(SVG 在设计之初就是给机器看的,十分不利于人工浏览)。比方,我这里是用 Figma 绘制的(一个多边形就搞定),轻易什么尺寸都行

而后就失去了这样一段 SVG

<svg width="167" height="90" viewBox="0 0 167 90" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2.10786 45L83.5 1.13597L164.892 45L83.5 88.864L2.10786 45Z" fill="#FFECC7" fill-opacity="0.6" stroke="#FFB200" stroke-width="2"/>
</svg>

在浏览器中成果如下

二、SVG 的缩放个性

当初 SVG 有一个默认尺寸,如果手动扭转 SVG 的默认尺寸,如下

是不是有点相似于 object-fit:contain 的成果?如果想整个铺满,强制拉伸该怎么做呢?这里须要用到 SVG 的缩放属性 preserveAspectRatio,示意当 SVG 的理论尺寸和 viewBox 尺寸不统一时的缩放规定,有点相似于 object-fitobject-position 组合。这里的取值十分多,默认值是xMidYMid,示意强制等比缩放,并且居中对齐。

有趣味的能够参考这篇文章:了解 SVG viewport,viewBox,preserveAspectRatio 缩放,案例十分具体

这里咱们不须要等比缩放,能够间接设置为none

<svg preserveAspectRatio="none">
...
</svg>

成果如下

三、SVG 的描边缩放

在设置不等比缩放后,其实描边还有一点小问题,不同尺寸下,描边的粗细不同,如下

有没有方法让描边不会追随 SVG 尺寸缩放呢?当然也是有的!SVG 中有一个属性 vector-effect 能够管制描边不缩放,永远放弃默认设置的尺寸,有趣味的能够参考这篇文章 CSS vector-effect 与 SVG stroke 描边缩放,这里只须要在 path增加属性 vector-effect="non-scaling-stroke" 就行了,示意描边不追随缩放,如下

<svg preserveAspectRatio="none">
    <path vector-effect="non-scaling-stroke">...</path>
</svg>

这样就实现了一个自适应尺寸的菱形了,描边也不会缩放,残缺 SVG 代码如下

<svg width="100%" height="100%" preserveAspectRatio="none" viewBox="0 0 167 90" fill="none" xmlns="http://www.w3.org/2000/svg">
  <path vector-effect="non-scaling-stroke" d="M2.10786 45L83.5 1.13597L164.892 45L83.5 88.864L2.10786 45Z" fill="#FFECC7" fill-opacity="0.6" stroke="#FFB200" stroke-width="2"/>
</svg>

四、SVG 内联 base64

通常状况下,这样一个图形用作背景图更为适合(SVG 代码放在页面上不太好看)。让人诧异的是,将 SVG 转换成 base64 后,以上个性依然是存在的。这里应用张鑫旭老师的 SVG 在线压缩合并工具,如下

转换后,将这段 base64 间接用作背景就行

div{background: url('data:image/svg+xml;base64,PHN2ZyBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJub25lIiB2aWV3Qm94PSIwIDAgMTY3IDkwIiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIHZlY3Rvci1lZmZlY3Q9Im5vbi1zY2FsaW5nLXN0cm9rZSIgZD0iTTIuMTA4IDQ1TDgzLjUgMS4xMzYgMTY0Ljg5MiA0NSA4My41IDg4Ljg2NCAyLjEwOCA0NXoiIGZpbGw9IiNGRkVDQzciIGZpbGwtb3BhY2l0eT0iLjYiIHN0cm9rZT0iI0ZGQjIwMCIgc3Ryb2tlLXdpZHRoPSIyIi8+PC9zdmc+')
}

这样就失去了一个自适应的菱形背景了

当然,转换成 base64 后就不能实时批改色彩了,须要整体替换

残缺代码能够拜访 SVG diamond

五、总结一下

从这个例子就能够看出 SVG 的人造劣势了,特地是描边的缩放个性,如果用 CSS 来绘制预计要遇到不少麻烦。这里总结一下实现要点:

  1. SVG 个别通过设计软件绘制导出就行,不须要手写
  2. SVG 默认是放弃原比例缩放的,能够通过 preserveAspectRatio 批改缩放规定
  3. SVG 描边的粗细默认会追随整体尺寸缩放,能够通过 vector-effect 设置放弃原始大小
  4. SVG 在转成 base64 后依然具备以上个性,更适宜用作背景图片

SVG 始终在图形绘制上更具劣势,特地是这类几何图形,缩放、自适应更加灵便,如果 CSS 实现有艰难,无妨考虑一下 SVG。最初,如果感觉还不错,对你有帮忙的话,欢送点赞、珍藏、转发❤❤❤

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

退出移动版