乐趣区

关于css:30-个案例教你用纯-CSS-实现常见的几何图形

本文会介绍一些常见几何图形的 CSS 绘制计划,思路参考自 The shapes of CSS 一文以及网上的其它文章,局部中央会做适当的批改和补充。

1. 三角形

传统 border 实现

咱们晓得,如果设置一个盒子的宽高为 0,盒子就会变成一个点。此时再给上下左右四个 border 肯定的宽度和不同的色彩,那么单纯由 border 填充的盒子看起来是这样的:

但内容盒有宽高的时候,四个 border 的对接处就不是一个点,而是一个矩形(图中红色区域),这时候的 border 看起来就会和事实中的边框差不多:

因而,要绘制三角形,外围就是设置盒子的宽高为 0,让 border 体现为一个三角形:

.delta {
    width: 0px;
    height: 0px;
    border: 50px solid;
    border-color:  #43cea2 #185a9d #ff6b6b #83a4d4;
}

当然,也能够给盒子一个宽高,只不过这时候咱们就要将其设置为 IE 盒模型(box-sizing:border-box),以确保在始终保持盒子原尺寸的前提下,通过减少 border 的宽度使 border 向盒子外部聚拢:

.delta {
    width: 100px;
    height: 100px;
    box-sizing: border-box;
    border: 50px solid;
    border-color:  #43cea2 #185a9d #ff6b6b #83a4d4;
}

下面两种办法成果一样,接着依据理论状况暗藏其中三个三角形即可。咱们这里只想要显示底下的三角形,所以其它三角形通过通明色暗藏,顶部的三角形则设置 border 宽度为 0,防止占用空间。

HTML:

<div class="delta"></div>

CSS:

.delta {
    width: 0px;
    height: 0px;
    border: 50px solid transparent;
    border-bottom-color: #ff6b6b;
    border-top-width: 0px;
}

成果如下:

源代码:codepen1

突变实现

这种办法适宜绘制直角三角形。假如要绘制一个红色的直角三角形,其实能够把它看作是一个矩形的一半,矩形从通明色突变到红色:

div {
    width: 200px;
    height: 200px;
    background: linear-gradient(to right bottom,transparent 0%,transparent 50%,red 50%,red 100%);
}
svg 实现
<svg width="100" height="100">
  <polygon points="50,0 100,100 0,100" style="fill: red;"/>
</svg>
clip-path 实现
div {
    width: 100px; 
    height: 100px;
    background: red;
    clip-path: polygon(50% 0, 0 100%, 100% 100%);
}
transform 和 overflow 实现

假如要绘制这个三角形:

先试着把他的另一半补齐:

能够设想成这其实是由两个盒子高低重叠而成的,上面的是绿色盒子,下面的是蓝色盒子,这个蓝色盒子歪斜摆放,并且超出绿色盒子的局部被暗藏了。因而最后可能是相似这样的:

那么反过来想一下,假如咱们可能实现上图这个款式,接着设法把蓝色盒子超出绿色盒子的局部暗藏,并把绿色盒子设置为通明色,是不是就实现了最后的那个三角形了呢?

从布局上,咱们思考绿色盒子是绝对定位的父元素,蓝色盒子是子元素(用伪元素来做),并且在相对定位和 transform 的作用下,实现图中的成果。接下来咱们要解决几个问题:

  • 蓝色盒子和绿色盒子在宽高上的关系?从图中能够看出,蓝色盒子的边长根本等于绿色盒子的对角线长度。绿色盒子宽高都是 100px,因而对角线是 100√2 px,越等于 140px,因而蓝色盒子的边长就是 140px,也就是父盒子宽高的 140%。
  • 蓝色盒子的相对定位的 left 偏移多少?在相对定位的设置上,咱们能够让蓝色盒子并排放在绿色盒子右边,并且两者底边在同一条线上
  • 蓝色盒子旋转多少度?从图中的几何关系很容易看出,通过下面相对定位的设置之后,蓝色盒子应该再旋转 45 度能力达到图中地位。不过这里要留神, 蓝色盒子不是绕着本人的核心旋转的,而是绕着本人的右下角顶点旋转的 ,因而这里还得批改 transform-origin 的值

最初,还要把超出绿色盒子的局部暗藏,并且把绿色盒子的色彩设置为通明色。因而最终代码如下:

div {
    width: 100px; 
    height: 100px;
    background: transparent;
    position: relative;
    overflow: hidden;
}
div::after {
    content: '';
    width: 140%;
    height: 140%;
    background-color: #185a9d;
    position: absolute;
    left: -140%;
    bottom: 0;
    transform-origin: right bottom;
    transform: rotate(45deg) ;
}    

源代码:codepen2

字符实现
div::after {
    content:'\25b3'
    color:red
    font-size: 60px    
}

根本不实用,因为无奈设置背景色彩,也无奈设置三角形的形态。

多矩形重叠实现

HTML:

<div class="container">
  <div style="width: 1px"></div>
  <div style="width: 2px"></div>
  <div style="width: 3px"></div>
  <div style="width: 4px"></div>
  <div style="width: 5px"></div>
  <div style="width: 6px"></div>
</div>

CSS:

.container {
    display:flex;
    flex-direction: column;
    align-items: center;
    div {
        height:1px;
        background: red;
    }    
}

三角形能够看作是多个宽度递增、高度极小的矩形自上而下重叠在一起。这段代码绘制的图形靠近于正三角形,如果要绘制直角三角形,能够设置 align-items: start,让矩形统一往左边聚拢。

这个办法根本也不实用,首先它会减少多余的 dom 构造,其次是这样的图形存在锯齿,不够好看。—— 要缩小锯齿,咱们能够尝试持续压缩矩形的高度,但这样意味着须要应用更多的 dom 来绘制出等同高度的三角形。

2. 椭圆形

一般椭圆

椭圆的实现依附的是 border-radius,因而有必要搞懂 border-radius 的具体含意。

通常状况下,想要设置一个 div 的圆角,咱们可能会写出相似这样的代码:

border-radius: 12px

它实际上等价于上面的代码:

border-top-left-radius: 12px 12px
border-top-right-radius: 12px 12px
border-bottom-left-radius: 12px 12px
border-bottom-left-radius: 12px 12px

也就是说,咱们把 div 的左上角、右上角、左下角、右下角的某两个值都设置为 12px,那么这两个值是什么呢?它们其实指的是这四个角各自的程度半径和垂直半径。在这个例子中,咱们的四个圆角,实际上都是一个半径为 12px 的圆的 1/4 弧。

这样咱们也能了解圆的造成了。对于一个 100px * 100px 的 div,设置 border-radius:50%,就等于设置 div 四个角的程度半径为 div 宽的一半,垂直半径为 div 高的一半,这样造成的图形肯定会是一个圆形。

同理,对于一个 200px * 100px 的 div,设置 border-radius:50%,就等于设置四个角的程度半径为 div 宽的一半,垂直半径为 div 高的一半,这样造成的图形肯定会是一个椭圆形。

代码如下:

div {
  width: 200px; 
  height: 100px;
  background: #185a9d;
  border-radius: 50%;
}
非凡椭圆(鸡蛋形)

实现形式和一般椭圆相似。特点在于上半局部比下半局部要更加扁平,因而左上角和右上角圆角的垂直半径要更长,这里取整体高度的 60%,残余的 40% 作为左下角和右下角圆角的垂直半径。代码如下:

HTML:

<div class="shape"></div>

CSS:

.shape {
  width: 126px;
  height: 180px;
  background: #36d792;
  border-radius: 50% 50% 50% 50% / 60% 60% 40% 40%;
}

源代码:codepen3

3. 扇形

半圆

  • border-radius 实现:

    先画一个长度为宽度两倍的矩形,再给左上角和右上角设置圆角即可(圆角半径等于宽度)

    .shape {
      width: 200px;
      height:100px;
      background: #ff6b6b;
      border-radius:100px 100px 0 0;
    }
  • overflow:hidden 实现:

    让圆形的一半超出父元素并给父元素设置溢出暗藏

    .shape {
      width: 200px;
      height: 100px;  
      overflow: hidden;
      position: relative;
    }
    .shape::after {
      content:'';
      position: absolute;
      width: 200px;
      height: 200px;
      background: #ff6b6b;
      border-radius: 50%;
    }
  • 背景突变实现(看上去是半圆):

    能够将半圆看作是一个圆形从有色彩突变到通明色

    .shape {
      width: 200px;
      height:200px;
      border-radius: 50%;
      background-image: linear-gradient(to bottom,#ff6b6b 50%,transparent 50%) ;  
    }
  • border-left 实现(看上去是半圆):

    .shape {
      width: 200px;
      height: 100px;  
      border-top: 100px solid #ff6b6b;
      border-radius: 50%;
    }
1/4 圆

  • border-radius 实现:

    .shape {
      width: 120px;
      height: 120px;  
      background: #ff6b6b;
      border-top-left-radius: 100%;
    }
  • border 实现:

    相似于三角形的实现

    .shape {
      width: 0px;
      height: 0px;  
      border: 100px solid transparent;
      border-top-color: #ff6b6b;
      border-radius: 100px;
      transform: rotate(-45deg);
    }
  • overflow:hidden 实现

    .shape {
      width: 100px;
      height: 100px;  
      overflow: hidden;
      position: relative;
    }
    .shape::after {
      content:'';
      position: absolute;
      width: 200px;
      height: 200px;
      background: #ff6b6b;
      border-radius: 50%;
    }
任意扇形
  • 三角形 + 圆形 + 溢出暗藏 实现:

    利用之前 border 实现三角形的办法,咱们能够实现如下图所示、与圆心对准的的矩形。给圆形设置通明色和溢出暗藏,并且打消掉矩形不想显示的 border,就能失去扇形了。扇形的圆心角大小由 border-left-widthborder-right-width 独特管制,这两者越大,圆心角也就越大 —— 但最大也只能是 180 度。

    代码如下:

    HTML:

    <div class="shape"></div>

    CSS:

    .shape {
      width: 200px;
      height: 200px;
      border-radius: 50%;
      overflow: hidden;
      position: relative;
    }
    .shape::after {
      content:'';
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%,-50%);
      width: 0;
      height: 0;
      border-left: 200px solid transparent;
      border-right: 200px solid transparent;
      border-top: 100px solid #ff6b6b;
      border-bottom: 100px solid transparent;  
    }

    源代码:codepen4

  • 矩形 + 半圆 + 溢出暗藏 实现:

    设想一下有一个绿色矩形,上面有一个直径与矩形长度相等的红色半圆,让半圆绕着圆心旋转,在这个过程中,绿色区域外面是不是就有一个角度一直变动的扇形呢?如下图所示:

    因而,咱们只有把绿色矩形设置为通明色,同时加上溢出暗藏的成果,就能通过扭转半圆旋转的角度,在矩形外部造成一个扇形了。代码如下:

    HTML:

    <div class="shape"></div>

    CSS:

    .shape {
      width: 200px;
      height: 100px;
      position: relative;
      overflow: hidden;
    }
    .shape::after {
      content:'';
      position: absolute;
      width: 100%;
      height: 100%;
      top: 100%;
      background: #ff6b6b;
      border-radius: 0 0 50% 50% / 0 0 100% 100%;
      transform-origin: top center;
      transform: rotate(30deg); 
    }

    成果如下:

    源代码:codepen5

    不过有个问题:这种办法实现的扇形,圆心角不能超过 180 度,那么对于圆心角大于 180 度的扇形怎么实现呢?咱们改用两个半圆实现。

  • 两个半圆实现:

    一开始两个半圆是叠放在一起的,通过让下面的半圆绕着圆心旋转,就能够造成圆心角大于 180 度的扇形。如下图所示:

代码如下:

HTML:

<div class="shape"></div>

CSS:

.shape {
  width: 200px;
  height: 100px;
  background: #36d793;
  border-radius: 50% 50% 0 0 / 100% 100% 0 0;
  position: relative;
}
.shape::before{
  content:'';
  position: absolute;
  background: #36d793;
  width: 200px;
  height: 100px;
  border-radius: 50% 50% 0 0 / 100% 100% 0 0;
  transform-origin: bottom center;
  transform: rotate(30deg);
}

源代码:codepen6

4. 梯形

border 实现

后面说过,如果设置一个盒子宽高为 0,并给肯定的 border,那么这个盒子看起来是这样的:

在此基础上,如果给这个盒子一个宽度,会产生什么事呢?盒子就会变成这样:

实际上这也是合乎咱们的直觉的,能够设想成是四个三角形的交接点被横向拉长了,三角形也跟着变动。当初这个图形曾经蕴含梯形了,那么咱们接下来的事件就很简略了,只须要把没用到的分块设置成通明色即可,因而最终代码如下:

HTML:

<div class="shape"></div>

CSS:

.delta {
    width: 100px;
    height: 0px;
    border: 50px solid transparent;
    border-bottom-color: #ff6b6b;
}

最终成果如下:

源代码:codepen7

  • 梯形的大小:

    通过设置 div.delta 的宽度,能够同时批改梯形的高低底长度;通过设置 border-left-widthborder-right-width 能够批改底角大小,border 越宽,底角越小。另外还能够设置 border-bottom-width,从而管制梯形的高度。有时候,咱们可能心愿所有的变动都是在确保原 div 大小不变的状况下进行的,这时候能够给 div 设置 box-sizing:border-box

  • 梯形的方向:

    当初咱们的梯形是朝上或者朝下的,如果想要设置方向为朝左或者朝右,能够纵向拉长对接点,也即放弃 div 宽度为 0 的同时,给它肯定的高度。

  • 直角梯形:

    这里只以一个方向为例进行介绍。对于上面这张图:

    如果咱们把它的 border-left-width 进行压缩,那么红色梯形的顶角就会往左边拖动,趋近于九十度:

    当压缩到为 0 的时候,原先的等腰梯形就变成了如下图所示的直角梯形:

矩形 + 三角形实现

等腰梯形也能够看作是由一个矩形 + 两个直角三角形组成(其它梯形同理):

代码如下:

.shape {
    width: 200px;
    height: 120px;
    background-color: #36d792;
    position: relative;
}
.shape::before,.shape::after {
    content:'';
    position: absolute;
    width: 0;
    height: 0;
    border-top: 60px solid white;            
    border-bottom: 60px solid transparent;
}
.shape::before {
    border-left: 20px solid white;
    border-right: 20px solid transparent;
    left: 0;
}
.shape::after {
    border-left: 20px solid transparent;
    border-right: 20px solid white;
    right: 0;
}    

源代码:codepen8

5. 平行四边形

这个比较简单,间接通过 transform:skew() 对矩形做歪斜解决即可。代码如下:

.shape {
    width: 200px;
    height: 120px;
    background-color: #36d792;
    transform: skew(20deg);
}

6. 五角星

实际上,五角星能够看作是由三个三角形拼接而成的:

长度的设置:

  • 为了不便后续计算,这里设法让顶部三角形的腰长为 130px,底长为 100px。即:设置顶部三角形的 border-bottom-width 为 120px,,border-left-widthborder-right-width 都为 50px。
  • 上面两个三角形也都是等腰三角形,须要利用几何关系计算各边长度。显然,只有晓得等腰三角形的面积和底边,那么就能推算出它的高,而高其实就是 border-bottom-width。三角形各个边的边长为 130+50*2130+50*2(130+50)*2,依据海伦公式,能够由三边计算出一个三角形的面积,又因为底边已知,所以算出高为 143px,也即 border-bottom-width 为 143px,而 border-leftborder-right 的宽度则为三角形底边的一半,也就是 180px。这样,两个三角形都能绘制进去了。
  • 剩下的工作就是调整相对定位的偏移量以及两个三角形旋转的角度。因为计算的偏差问题,这里失去的并不是规范的五角星,但总体思路是这样。

最终代码如下:

.shape {
    width: 0;
    height: 0;
    border-left: 50px solid transparent;
    border-right: 50px solid transparent;
    border-bottom: 120px solid #36d792;
    position: relative;
}
.shape::before {
    content: '';
    position: absolute;
    width: 0;
    height: 0;
    border-left: 200px solid transparent;
    border-right: 200px solid transparent;
    border-bottom: 143px solid #36d792;    
    top: 106px;
    left: -192px;
    transform: rotate(36deg);        
}
.shape::after {
    content: '';
    position: absolute;
    width: 0;
    height: 0;
    border-left: 200px solid transparent;
    border-right: 200px solid transparent;
    border-bottom: 143px solid #36d792;    
    top: 106px;
    left: -206px;
    transform: rotate(-36deg);        
}

源代码:codepen9

7. 六角星

六角星用一个正三角形和一个倒三角形来做即可:

代码如下:

.shape {
    width: 0;
    height: 0;
    border: 50px solid transparent;
    border-bottom: 80px solid #36d792;
    position: relative;
}
.shape::after {
    content: '';
    position: absolute;
    width: 0;
    height: 0;
    border: 50px solid transparent;
    border-top: 80px solid #36d792;
    top: 30px;
    left: -50px;
}

源代码:codepen10

8. 八角星

用两个矩形来做即可,其中一个矩形绕核心旋转 45 度就能够造成八角星。代码如下:

HTML:

<div class="shape"></div>

CSS:

.shape {
  width:80px;
  height:80px;
  background: #36d792;
  position: relative;
}
.shape::after {
  content:'';
  position: absolute;
  width:80px;
  height:80px;
  background: #36d792;
  transform: rotate(45deg);
}

源代码:codepen11

9. 十二角星

十二角星的做法和八角星相似,只是多了一个矩形以及旋转的角度不同而已。代码如下:

HTML:

<div class="shape"></div>

CSS:

.shape {
  width:80px;
  height:80px;
  background: #36d792;
  position: relative;
}
.shape::before,.shape::after {
  content:'';
  position: absolute;
  width:80px;
  height:80px;
  background: #36d792;
}
.shape::before {transform: rotate(30deg);
}
.shape::after {transform: rotate(-30deg);
}

源代码:codepen12

10. 五边形

为了防止繁琐的运算,这里采纳口诀“九五顶五九,八五两边分”设置五边形的相干长度:

五边形看作是一个等腰三角形 + 等腰梯形即可,最终代码如下:

HTML:

<div class="shape"></div>

CSS:

.shape {
  width:0;
  height:0;
  border: 80px solid transparent;
  border-top-width: 0px;
  border-bottom: 59px solid #36d792;
  position: relative;
}
.shape::after {
  content:'';
  position: absolute;
  width:100px;
  height:0;
  border: 30px solid transparent;
  border-bottom-width:0px;
  border-top: 95px solid #36d792;
  left:-80px;
  top:59px;
}

源代码:codepen13

11. 六边形

六边形能够看作是由两个等腰三角形 + 一个矩形组成,也能够看作由两个等腰梯形组成,这里抉择第二种。代码如下:

HTML:

<div class="shape"></div>

CSS:

.shape {
  width:120px;
  height:0;
  border: 60px solid transparent;
  border-top-width: 0px;
  border-bottom: 104px solid #36d792;
  position: relative;
}
.shape::after {
  content:'';
  position: absolute;
  width:120px;
  height:0;
  border: 60px solid transparent;
  border-bottom-width:0px;
  border-top: 104px solid #36d792;
  left:-60px;
  top:104px;
}

源代码:[codepen14]()

12. 八边形

正八边形能够看作由两个等腰梯形 + 一个矩形组成,代码如下:

HTML:

<div class="shape"></div>

CSS:

.shape {
  width:102px;
  height:42px;
  background: #36d792;
  position: relative;
}
.shape::before,.shape::after {
  content:'';
  position: absolute;
  width:42px;
  height:0px;
  border: 30px solid transparent;
}
.shape::before {
  border-top-width:0px;
  border-bottom: 30px solid #36d792;
  top:-30px;
}
.shape::after {
  border-bottom-width:0px;
  border-top: 30px solid #36d792;
  top:42px;
}

源代码:codepen15

13. 菱形

一般菱形

一般菱形能够看作由两个三角形形成,代码如下:

HTML:

<div class="shape"></div>

CSS:

.shape {
  width:0px;
  height:0px;
  border: 40px solid transparent;
  border-top-width:0px;
  border-bottom: 70px solid #36d792;
  position: relative;
}
.shape::before {
  content:'';
  position: absolute;
  width:0px;
  height:0px;
  border: 40px solid transparent;
  border-bottom-width:0px;
  border-top: 70px solid #36d792;
  left:-40px;
  top:70px;
}

源代码:codepen16

非凡菱形(九十度角)

依然能够采纳下面的办法,但更简略的办法是绕核心旋转一个正方形。代码如下:

HTML:

<div class="shape"></div>

CSS:

body {margin:80px;}
.shape {
  width:100px;
  height:100px;
  background: #36d792;
  transform: rotate(45deg);
}

源代码:codepen17

14. 盾形

HTML:

<div class="shape"></div>

CSS:

.shape {
  width:0;
  height:0;
  border:50px solid transparent;
  border-top-width:0;
  border-bottom:20px solid #36d792;
  position: relative;
}
.shape::after {
  content:'';
  position:absolute;
  width:0;
  height:0;
  border:50px solid transparent;
  border-bottom-width:0;
  border-top: 70px solid #36d792;
  left:-50px;
  top: 20px;
}

源代码:codepen18

15. 钻石形

HTML:

<div class="shape"></div>

CSS:

.shape {
  width:35px;
  height:0;
  border:25px solid transparent;
  border-top-width:0;
  border-bottom:25px solid #36d792;
  position: relative;
}
.shape::after {
  content:'';
  position:absolute;
  width:0;
  height:0;
  border:42px solid transparent;
  border-bottom-width:0;
  border-top: 70px solid #36d792;
  left:-25px;
  top: 25px;
}

源代码:codepen19

16. 太极图

这是最终要实现的成果:

尽管它仿佛是由不规则的几何图形形成的,但实际上,咱们能够用规定的几何图形重叠造成太极图。简略地说,能够把它拆解成上面这样:

先用第三大节提到的背景突变实现一个黑白对半圆:

.taiji {
    width:200px;
    height:200px;
    border-radius:50%;
    background-image: linear-gradient(to right,black 50%,white 50%);
}

再实现两个黑白同心圆,其内圆半径和外环(外环能够用 border 来做)宽度依据几何关系求出即可,接着将同心圆别离定位到对半圆的最下面和最上面。

最终代码如下:

.taiji {
    width:200px;
    height:200px;
    border-radius:50%;
    background: linear-gradient(to right,black 50%,white 50%);
    position: relative;
}
.taiji::before,.taiji::after {
    content:'';
    position: absolute;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    left: -50%;
}
.taiji::before {
    background-color: white;
    border:40px solid black;
    top: 0;
}
.taiji::after {
    background-color: black;
    border:40px solid white;
    bottom: 0;
}

让太极图动起来:

当初,能够设置在鼠标移入的时候让太极图旋转起来:

.taiji {
       animation: rotate 1s linear infinite;    
    animation-play-state:paused;
}
.taiji:hover {animation-play-state:running;}
@keyframes rotate {
  0%{transform: rotate(0deg);
  }
  100%{transform: rotate(360deg);
  }
}

成果如下:

源代码:codepen20

17. 爱心

爱心能够看作是由两个这样的形态通过旋转后造成的:

设置左图的 transform-origin 为右下角顶点,让其绕点顺时针旋转 45 度,右图的 transform-origin 为左下角顶点,让其绕点逆时针旋转 45 度,即可造成爱心(旋转 45 度是因为爱心的底角是 90 度)。代码如下:

HTML:

<div class="heart"></div>

CSS:

.heart {position: relative;}
.heart::before,.heart::after {
  content:'';
  position: absolute;
  width:50px;
  height:80px;
  border-radius: 25px 25px 0 0;
  background: red;
}
.heart::before {
  transform-origin: right bottom;
  transform: rotate(45deg);
}
.heart::after {
  left:50px;
  transform-origin: left bottom;
  transform: rotate(-45deg);
}

源代码:codepen21

18. 无穷符号

无穷符号 能够看作是由上面两个图形通过旋转形成的:

先画出两个圆环,勾销第一个圆环右下角圆角,并将其逆时针旋转 45 度;勾销第二个圆环左下角圆角,并将其顺时针旋转 45 度。代码如下:

HTML:

<div class="shape"></div>

CSS:

.shape {position: relative;}
.shape::before,.shape::after {
  content:'';
  position: absolute;
  width: 60px;
  height: 60px;
  border: 20px solid #36d792;
}
.shape::before {
  border-radius: 50% 50% 0 50%;
  transform: rotate(-45deg);
}
.shape::after {
  border-radius: 50% 50% 50% 0;
  transform: rotate(45deg);
}

失去的图形是这样的:

能够看到,圆环局部重叠了,所以须要将 ::after 伪元素右移,那么应该偏移多少呢?这里须要略微计算一下。为了不便察看,咱们批改两个图形的色彩和层级,并作适当的标注,失去上面这个图形:

对照结尾的那张图能够看出,只有将 .shape::after 从 A 点右移到 B 点,就能造成一个 的形态。AB 边这段距离是由两条斜边组成的,并且斜边都位于一个等腰直角三角形中,因而只有别离算出两个三角形的直角边(a 和 b),就能算出斜边。从图中能够看出,a 是 30 + 20 = 50,对应的斜边为 50√2,约为 70;b 是 30,对应的斜边为 30√2,约为 42,所以 AB 边长为 112,即 .shape::after 应该右移 112 px。批改代码如下:

.shape::after {
  border-radius: 50% 50% 50% 0;
  left: 112px;
  transform: rotate(45deg);
}

这样,咱们就能失去一个 形态了。

源代码:codepen22

19. 吃豆人

吃豆人实际上是一个圆心角为 270 度的扇形,能够采纳之前绘制 1/4 圆的办法来实现。代码如下:

HTML:

<div class="shape"></div>

CSS:

.shape {
  width: 0;
  height: 0;
  border: 100px solid #f5d54d;
  border-right-color: transparent;
  border-radius: 100px;
  position: relative;
}
.shape::before,.shape::after {
  content:'';
  position: absolute;
  width: 24px;
  height: 24px;
  border-radius: 50%;
}
.shape::before {
  background: #000;
  top: -70px;
  left: 5px;
}
.shape::after {
  background: #f5d54d;
  top: -12px;
  left: 60px;
}

源代码:codepen23

20. 弯尾箭头

下图是一个常见的弯尾箭头图标:

这个图标能够看作由两个图形组成:一个是三角形,一个是弧线,弧线是通过 border + 圆角实现的。

先来绘制三角形:

HTML:

<div class="shape"></div>

CSS:

.shape {
    width: 0;
    height: 0;
    border: 20px solid transparent;
    border-left-color: #198bf6;
       position: relative;
    transform: rotate(40deg);
}

.shape 设置一个伪元素,将其 border-top 作为弧线,并设置圆角:

.shape::after {
    content: '';
    position: absolute;
    width: 40px;
    height: 40px;
    border-top: 10px solid #198bf6;
    border-radius-top-left: 100px;
}

蜿蜒水平,能够通过 widthborder-radius 进行调节。

当初咱们看到的就是这样的图形:

弧线是绝对于三角形顶点定位的,须要绝对于顶点左移 40+20 = 60px,再上移 10/2 = 5px:

.shape::after {
    left: -60px;
    top: -5px;
}

最初就能失去刚开始的那个图标了。

源代码:codepen24

21. 聊天气泡

类型 1:

这是一个相似微信的聊天气泡。察看到三角形局部是带有圆角的,所以咱们不采纳三角形 + 矩形的做法,而是用旋转的正方形 + 矩形来做 —— 即让正方形绝对矩形定位在两头后,旋转 45 度。代码如下:

HTML:

<div class="shape"></div>

CSS:

.shape {
  width: 200px;
  height: 100px;
  background: #21d86d;
  position: relative;
  border-radius: 10px;
}
.shape::after {
  content:'';
  position: absolute;
  width: 20px;
  height:20px;
  background: #21d86d;
  border-radius: 2px;
  top:50%;
  transform: translate(-35%,-50%) rotate(45deg);
}

源代码:codepen25

类型 2:

这种类型的气泡带有边框和背景色彩,咱们依然能够采纳下面的做法即可,但要留神去掉正方形的两个边框。代码如下:

HTML:

<div class="shape"></div>

CSS:

.shape {
  width: 200px;
  height: 100px;
  border-radius: 8px;
  background: #faf8f4;
  border: 1px solid #e6d9b3;
  position: relative;
}
.shape::after {
  content:'';
  position: absolute;
  top: 50%;
  transform: translate(-50%,-50%) rotate(45deg);
  width: 15px;
  height: 15px;
  background: #faf8f4;
  border: 1px solid #e6d9b3;
  border-style: none none solid solid
}

源代码:codepen26

类型 3:

这种是相似 QQ 的聊天气泡,这里蜿蜒的尾巴咱们用 20 大节介绍的办法来做即可。代码如下:

HTML:

<div class="shape"></div>

CSS:

.shape {
  width: 200px;
  height: 100px;
  background: #01a0ff;
  border-radius: 20px;
  position: relative;
}
.shape::after {
  content:'';
  position: absolute;
  left: -20px;
  width: 40px;
  height: 40px;
  border-bottom: 20px solid #01a0ff;
  border-bottom-left-radius: 100px;
}

源代码:codepen27

22. RSS 订阅

这是一个常见的 RSS feed 图标,圆角矩形和外部的红色圆点都是容易实现的。那么两段红色圆弧应该怎么实现呢?咱们可能很容易想到,两段红色圆弧都别离是一个 1/4 红色圆形的边框,所以能够用上面的形式来做:

但这种形式无疑是很麻烦的,事实上,咱们用 CSS3 的 box-shadow 内暗影来做会更加简略:

/ x 偏移量 | y 偏移量 | 暗影含糊半径 | 暗影扩散半径 | 暗影色彩 | 内暗影 /
box-shadow: 2px 2px 2px 1px rgba(0, 0, 0, 0.2) inset;

能够先在圆角矩形内画一个 1/4 圆,而后利用内暗影往圆里放三段相间的弧线(红色弧线、红色弧线和红色弧线),x 偏移量和 y 偏移量管制弧线的坐标,暗影扩散半径管制弧线的宽度。这种形式显然比第一种要简略得多。

最终代码如下:

HTML:

<div class="shape"></div>

CSS:

.shape {
  width: 165px;
  height: 165px;
  padding: 35px;
  border-radius: 30px;
  background-color: #ff4802;
  position: relative;
}
.shape::before {
  content:'';
  position: absolute;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background-color: #fff;
  bottom: 40px;
}
.shape::after {
  content:'';
  position: absolute;
  width: 165px;
  height: 165px;
  border-top-right-radius: 165px;
  box-shadow:
    -14px 14px 0 14px #fff inset,
    -28px 28px 0 28px #ff4802 inset,
    -42px 42px 0 42px #fff inset;    
}

源代码:codepen28

23. 徽章缎带

徽章缎带能够看作是由一个圆形 + 两个三角形通过如下变换失去的:

HTML:

<div class="shape"></div>

CSS:

.shape {
  position: relative;
  background: #00a1fb;
  height: 100px;
  width: 100px;
  border-radius: 50%;
}
.shape::before,.shape::after {
  content: '';
  position: absolute;
  border: 40px solid transparent;
  border-bottom: 70px solid #00a1fb;
  border-top: none;
  top: 70px; 
}
.shape::before {
  left: -10px;
  transform: rotate(-140deg);
}
.shape::after {
  right: -10px;
  transform: rotate(140deg);
}

源代码:codepen29

24. TV 电视机

TV 电视机能够看作是由上面两个图形叠加在一起形成的:

两个图形的做法相似,都是给矩形设置一个程度半径和垂直半径相差很大的圆角。代码如下:

HTML:

<div class="shape"></div>

CSS:

.shape {
  position: relative;
  width: 200px;
  height: 150px;
  margin: 20px 0;
  background: #00a1fb;
  border-radius: 50% / 10%;
}
.shape::after {
  content:'';
  position: absolute;
  background-color: #00a1fb;
  top: 10%;
  bottom: 10%;
  left: -5%;
  right: -5%;
  border-radius: 5% / 50%;
}

源代码:codepen30

25. 放大镜

放大镜的实现也很简略。原文的做法是将放大镜的把手定位到右侧再进行旋转,其实咱们能够间接将把手定位到正下方,而后去旋转 .shape 而不是 .shape::after,这样就能够不便地管制把手的朝向。

HTML:

<div class="shape"></div>

CSS:

.shape {
  width: 80px;
  height: 80px;
  border: 20px solid #01a0fe;
  border-radius: 50%;
  position: relative;
  transform: rotate(-45deg);
}
.shape::after {
  content:'';
  position: absolute;
  left: 50%;
  top: 90px;
  transform: translateX(-50%);
  width: 18px;
  height: 65px;
  background: #01a0fe;
}

源代码:codepen31

26. Facebook

Facebook 的图标由三个元素形成:蓝色方块、横线和弧线。横线是个等腰梯形,用后面介绍的办法来做即可;弧线能够看作是圆角矩形的一部分,那怎么能力做到只在蓝色方块中显示这一部分呢?咱们能够先画好一个蓝底白边的圆角矩形,只把它的一部分定位到蓝色方块中,再给蓝色方块设置溢出暗藏。如下图所示:

为了让红色字母 f 在还没接触蓝色方块右边缘的时候就产生溢出暗藏的成果,这里要给蓝色方块加上蓝色边框。

代码如下:

HTML:

<div class="shape"></div>

CSS:

.shape {
    width: 100px;
    height: 110px;
    background-color: #3b589c;
    border-radius: 6px;
    border: 15px solid #3b589c;
    border-bottom: none;
    position: relative;
    overflow: hidden;
}
.shape::before {
    content: '';
    position: absolute;
    width: 100px;
    height: 100px;
    background-color: #3b589c;
    border: 20px solid #fff;
    border-radius: 27px;
    left: 56px;
}
.shape::after {
    content: '';
    position: absolute;
    top: 37px;
    left: 37px;
    width: 58px;
    height: 0;
    border-right: 4px solid transparent;    
    border-top: 20px solid #fff;        
}

源代码:codepen32

27. 月亮

月亮其实能够看作是由两个半径雷同的圆不齐全重叠后造成的:

那么理论实现中真的须要画两个圆吗?其实不须要,底下的圆用 CSS3 的 box-shadow 来做会更不便。

/ x 偏移量 | y 偏移量 | 暗影含糊半径 | 暗影扩散半径 | 暗影色彩 /
box-shadow: 2px 2px 2px 1px rgba(0, 0, 0, 0.2);

咱们能够先画好一个圆,再给它设置暗影。x 偏移量和 y 偏移量独特管制月亮的形态和角度:

因为不须要含糊成果,所以含糊半径设置为 0;扩散半径能够管制月亮大小,若设置为 0 则示意与另一个圆大小雷同;最初的暗影色彩属性则是管制月亮的色彩。

最终代码如下:

HTML:

<div class="shape"></div>

CSS:

.shape {
  width:100px;
  height: 100px;
  border-radius: 50%;
  box-shadow: 40px 0px 0 0 #f4bd2e;
}

源代码:codepen33

28. 批示箭头

批示箭头能够有两种做法:

原文采纳的是左图的做法,用一个矩形 + 两个三角形来实现,但咱们无奈确定批示箭头所处背景的色彩,所以无奈确定第一个三角形应该采纳什么色彩;如果采纳右图的做法,则无需思考背景色彩的问题,实现起来也更加简略(两个矩形 + skew 来实现即可)。

HTML:

<div class="shape"></div>

CSS:

.shape {position: relative;}
.shape::before,.shape::after {
  content:'';
  position: absolute;
  width: 200px;
  height: 20px;
  background: #00a1fb;
}
.shape::before {transform: skew(45deg);
}
.shape::after {transform: skew(-45deg);
  top:20px;
}

源代码:codepen34

29. 锁

HTML:

<div class="shape"></div>

CSS:

body {margin: 100px;}
.shape {
  width: 140px;
  height: 100px;
  background: #01a0ff;
  border-radius: 15px;
  position: relative;
}
.shape::before {
  content:'';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%,-50%);
  width: 20px;
  height: 40px;
  border-radius: 10px;
  background: #fff;  
}
.shape::after {
  content:'';
  position: absolute;
  top: -63px;
  left: 50%;
  transform: translateX(-50%);
  width: 60px;
  height: 45px;
  border-radius: 48px 48px 0 0 / 48px 48px 0 0;
  border: 18px solid #01a0ff;
  border-bottom: none;  
}

源代码:codepen35

30. 书签 / 旗号

这是一个常见的书签 / 旗号图标,用矩形 + 三角形实现即可。代码如下:

HTML:

<div class="flag">
    <div class="text"> 驳回 </div>
</div>

CSS:

.flag {
    width: 56px;
    background-color: #009961;
    border-top-left-radius: 4px;
    border-top-right-radius: 4px;
}
.text {
    position: relative;
    padding: 9px 6px;
    text-align: center;
    color: white;
}
.text::after {
    content:'';
    position: absolute;
    left: 0;
    top: 36px;
    border-width: 16px 28px;
    border-color: #009961;
    border-style: solid;
    border-bottom: 16px solid transparent;
}

须要留神,矩形 .text::after 是长方形而不是正方形,这须要通过 border-width 进行相干设置:因为整体宽度是须要和父盒子保持一致的,因而左右两个 border 的宽度都应该是整体宽度的一半。最初再通过相对定位进行微调,就能失去上图的成果了。

源代码:codepen36

参考:

The shapes of CSS

三角形的 N 种画法与浏览器的凋谢世界

退出移动版