CSS 奇思妙想 | 巧妙的实现带圆角的三角形

开发 前端
本文介绍了几种在 CSS 中实现带圆角三角形的方式,虽然部分有些繁琐,但是也体现了 CSS ”有趣且折磨人“ 的一面,具体应用的时候,还是要思考一下,对是否使用上述方式进行取舍,有的时候,切图也许是更好的方案。

[[411591]]

之前在这篇文章中 -- 《老生常谈之 CSS 实现三角形》[1],介绍了 6 种使用 CSS 实现三角形的方式。

但是其中漏掉了一个非常重要的场景,如何使用纯 CSS 实现带圆角的三角形呢?,像是这样:

本文将介绍几种实现带圆角的三角形的实现方式。

法一. 全兼容的 SVG 大法

想要生成一个带圆角的三角形,代码量最少、最好的方式是使用 SVG 生成。

使用 SVG 的 多边形标签 <polygon> 生成一个三边形,使用 SVG 的 stroke-linejoin="round" 生成连接处的圆角。

代码量非常少,核心代码如下:

  1. <svg  width="250" height="250" viewBox="-50 -50 300 300"
  2.   <polygon class="triangle" stroke-linejoin="round" points="100,0 0,200 200,200"/> 
  3. </svg> 
  1. .triangle { 
  2.     fill: #0f0; 
  3.     stroke: #0f0; 
  4.     stroke-width: 10; 

实际图形如下:

这里,其实是借助了 SVG 多边形的 stroke-linejoin: round 属性生成的圆角,stroke-linejoin 是什么?它用来控制两条描边线段之间,有三个可选值:

  • miter 是默认值,表示用方形画笔在连接处形成尖角
  • round 表示用圆角连接,实现平滑效果
  • bevel 连接处会形成一个斜接

我们实际是通过一个带边框,且边框连接类型为 stroke-linejoin: round 的多边形生成圆角三角形的。

如果,我们把底色和边框色区分开,实际是这样的:

  1. .triangle { 
  2.     fill: #0f0; 
  3.     stroke: #000; 
  4.     stroke-width: 10; 

 

通过 stroke-width 控制圆角大小

那么如何控制圆角大小呢?也非常简单,通过控制 stroke-width 的大小,可以改变圆角的大小。

当然,要保持三角形大小一致,在增大/缩小 stroke-width 的同时,需要缩小/增大图形的 width/height:

完整的 DEMO 你可以戳这里:CodePen Demo -- 使用 SVG 实现带圆角的三角形[2]

法二. 图形拼接

不过,上文提到了,使用纯 CSS 实现带圆角的三角形,但是上述第一个方法其实是借助了 SVG。那么仅仅使用 CSS,有没有办法呢?

当然,发散思维,CSS 有意思的地方正在于此处,用一个图形,能够有非常多种巧妙的解决方案!

我们看看,一个圆角三角形,它其实可以被拆分成几个部分:

所以,其实我们只需要能够画出一个这样的带圆角的菱形,通过 3 个进行旋转叠加,就能得到圆角三角形:

绘制带圆角的菱形

那么,接下来我们的目标就变成了绘制一个带圆角的菱形,方法有很多,本文给出其中一种方式:

1.首先将一个正方形变成一个菱形,利用 transform 有一个固定的公式:

  1. <div></div> 
  1. div { 
  2.     width:  10em; 
  3.     height: 10em; 
  4.     transform: rotate(-60deg) skewX(-30deg) scale(1, 0.866); 

 

2.将其中一个角变成圆角:

  1. div { 
  2.     width:  10em; 
  3.     height: 10em; 
  4.     transform: rotate(-60deg) skewX(-30deg) scale(1, 0.866); 
  5.   + border-top-right-radius: 30%; 

 

至此,我们就顺利的得到一个带圆角的菱形了!

拼接 3 个带圆角的菱形

接下来就很简单了,我们只需要利用元素的另外两个伪元素,再生成 2 个带圆角的菱形,将一共 3 个图形旋转位移拼接起来即可!

完整的代码如下:

  1. <div></div> 
  1. div{ 
  2.     position: relative
  3.     background-color: orange; 
  4. div:before, 
  5. div:after { 
  6.     content: ''
  7.     position: absolute
  8.     background-color: inherit; 
  9. div, 
  10. div:before, 
  11. div:after { 
  12.     width:  10em; 
  13.     height: 10em; 
  14.     border-top-right-radius: 30%; 
  15. div { 
  16.     transform: rotate(-60deg) skewX(-30deg) scale(1,.866); 
  17. div:before { 
  18.     transform: rotate(-135deg) skewX(-45deg) scale(1.414, .707) translate(0,-50%); 
  19. div:after { 
  20.     transform: rotate(135deg) skewY(-45deg) scale(.707, 1.414) translate(50%); 

就可以得到一个圆角三角形了!效果如下:

完整的代码你可以戳这里:CodePen Demo -- A triangle with rounded[3]

法三. 图形拼接实现渐变色圆角三角形

完了吗?没有!

上述方案,虽然不算太复杂,但是有一点还不算太完美的。就是无法支持渐变色的圆角三角形。像是这样:

 

如果需要实现渐变色圆角三角形,还是有点复杂的。但真就还有人鼓捣出来了,下述方法参考至 -- How to make 3-corner-rounded triangle in CSS[4]

同样也是利用了多块进行拼接,但是这次我们的基础图形,会非常的复杂。

首先,我们需要实现这样一个容器外框,和上述的方法比较类似,可以理解为是一个圆角菱形(画出 border 方便理解):

  1. <div></div> 
  1. div { 
  2.     width: 200px; 
  3.     height: 200px; 
  4.     transform: rotate(30deg) skewY(30deg) scaleX(0.866); 
  5.     border: 1px solid #000; 
  6.     border-radius: 20%; 

接着,我们同样使用两个伪元素,实现两个稍显怪异的图形进行拼接,算是对 transform 的各种用法的合集:

  1. div::before, 
  2. div::after { 
  3.     content: ""
  4.     position: absolute
  5.     width: 200px; 
  6.     height: 200px; 
  7. div::before { 
  8.     border-radius: 20% 20% 20% 55%; 
  9.     transform: scaleX(1.155) skewY(-30deg) rotate(-30deg) translateY(-42.3%) skewX(30deg) scaleY(0.866) translateX(-24%); 
  10.     background: red; 
  11. div::after { 
  12.     border-radius: 20% 20% 55% 20%; 
  13.     background: blue; 
  14.     transform: scaleX(1.155) skewY(-30deg) rotate(-30deg) translateY(-42.3%) skewX(-30deg) scaleY(0.866) translateX(24%); 

为了方便理解,制作了一个简单的变换动画:

本质就是实现了这样一个图形:

最后,给父元素添加一个 overflow: hidden 并且去掉父元素的 border 即可得到一个圆角三角形:

由于这两个元素重叠空间的特殊结构,此时,给两个伪元素添加同一个渐变色,会完美的叠加在一起:

  1. div::before, 
  2. div::after, { 
  3.     background: linear-gradient(#0f0, #03a9f4); 

最终得到一个渐变圆角三角形:

上述各个图形的完整代码,你可以戳这里:CodePen Demo -- A triangle with rounded and gradient background[5]

最后

本文介绍了几种在 CSS 中实现带圆角三角形的方式,虽然部分有些繁琐,但是也体现了 CSS ”有趣且折磨人“ 的一面,具体应用的时候,还是要思考一下,对是否使用上述方式进行取舍,有的时候,切图也许是更好的方案。

参考资料

[1]《老生常谈之 CSS 实现三角形》:

https://juejin.cn/post/6950081305560219679

[2]CodePen Demo -- 使用 SVG 实现带圆角的三角形: https://codepen.io/Chokcoco/pen/eYWZvKo

[3]CodePen Demo -- A triangle with rounded:

https://codepen.io/Chokcoco/pen/vYmLVZr

[4]How to make 3-corner-rounded triangle in CSS:

https://stackoverflow.com/questions/14446677/how-to-make-3-corner-rounded-triangle-in-css

[5]CodePen Demo -- A triangle with rounded and gradient background:

https://codepen.io/Chokcoco/pen/LYyGRpV

[6]Github -- iCSS: https://github.com/chokcoco/iCSS

 

责任编辑:姜华 来源: iCSS前端趣闻
相关推荐

2022-03-16 14:27:49

CSS三角形前端

2016-10-20 13:36:28

WebRTC浏览器服务器

2021-10-19 10:09:21

三角形个数数组

2024-09-05 11:20:54

2024-02-20 18:30:53

CSS属性边框

2021-08-29 18:32:18

CSS

2021-04-15 06:02:50

CSS 三角形技巧

2023-04-17 09:01:01

WebGL绘制三角形

2023-11-01 07:51:15

WebGPU3D 图形

2020-12-09 08:34:24

css生成器设计师

2022-02-22 07:50:10

CSS前端CSS-doodle

2021-07-13 06:10:02

CSS 技巧background-

2018-03-02 15:54:37

三角形主机比特币

2022-09-14 15:17:26

ArkUI鸿蒙

2023-01-31 10:23:00

CSS倒影效果

2021-07-06 06:07:14

CSS 技巧背景

2023-05-06 07:23:57

2013-09-26 13:43:13

iOS开发OpenGL ES教程图元

2012-12-24 09:55:15

iOSUnity3D

2022-07-14 07:01:56

Eureka读锁线程
点赞
收藏

51CTO技术栈公众号