在实际应用中很多地方会用到一些小的形状图标及显示框等各种图形,而这时候如果使用图片不仅不能自适应内容还会在加载页面时增加图片请求从而降低页面性能,此时我们就可以用纯CSS的各种属性来解决这个问题了
CSS之border前言
由于我们下面介绍的方法大多数都要用到border这个样式属性,所以先介绍一下它,如果想对border进一步了解,可以翻看我前面的那篇博客。
最初border是用来给元素加边框的,随着CSS的发展和实际开发的需求,border被用在更多地方,比如用border的属性实现椭圆、梯形、心形等各种图形以及各种对话气泡上,在这里我们先看一下border的四个边属性1
2
3
4
5
6
7
8.border{
width: 0;
height: 0;
border-top: 50px solid red;
border-right: 50px dashed blue;
border-bottom: 50px solid yellow;
border-left: 50px solid green;
}
注:如果要实现没有下边框,也就是没有上图中的黄色部分,则应该把上面代码中的border-bottom的颜色yellow改为transparent而不是把border-bottom去掉,两种做法的区别见下图,第一个是改为transparent,第二个是直接去掉border-bottom属性
矩形
正方形
1 | .square{ |
长方形
1 | .square{ |
平行四边形
1 | .parallelogram{ |
注:transform是CSS3的属性,skew()为倾斜角度,括号中分别为沿X轴和Y轴两个值,用逗号分隔,当只有一个值时默认为沿X轴倾斜,允许负值(反方向),这里我就不贴图了,感兴趣的话可以拿上面那段代码改改试试
菱形
1 | .rhomb{ |
注:transform-origin规定旋转基点,rotate()旋转角度
梯形
梯形-向上
1 | .trapezoid-top{ |
如果直接看上面的代码不太明白,可以看下面的图例
这张图其实跟CSS之border前言中的图一样,只是这里的左右边框宽度跟上下边框宽度不一样,当然当这四种颜色相同时就是我们的2.1中长方形的样子了,对比这张图跟最终的效果图有什么不一样?对了,就是我们上面提到过的把borer-top属性去掉,那就成了下面这种样子
然后我们再把左右边框变成透明的就OK了
怎么样,是不是跟上面的效果图一样了。理解了这个,下面的梯形面向各个方向我们就不详细解释原理了
梯形-向下
1 | .trapezoid-bottom{ |
没错,就是把上面的代码中的bottom改成top即可
梯形-向左
1 | .trapezoid-left{ |
注:这里的height指定了外边框的长度,所以必须有,否则梯形就变成了三角形
梯形-向右
1 | .trapezoid-right{ |
圆角梯形
1 | .trapezoid-radius{ |
圆角梯形的实现原理跟其它的是不同的,圆角梯形是先实现圆角矩形,然后给矩形做3D变换,让它以底边框为基轴,向Z轴方向倾斜,视觉上就形成了圆角梯形
三角形
三角形-向上
1 | .triangle-top { |
这里border-color有三个值,第一个代表上边框颜色,第二个代表左右边框颜色,第三个代表下边框颜色,关于这些在我上一篇博客中有详细的描述,感兴趣的话可以看看。其实还有别的写法,比如下面这样1
2
3
4
5
6.triangle-top {
width: 0;
height: 0;
border: 50px solid transparent;
border-bottom: 50px solid yellowgreen;
}
这种写法可以实现等腰三角形而非等边三角形
三角形-向下
1 | .triangle-bottom { |
三角形-向左
1 | .triangle-left { |
三角形-向右
1 | .triangle-right { |
三角形-左上
1 | .triangle-ltop { |
三角形-右上
1 | .triangle-rtop { |
三角形-左下
1 | .triangle-lbottom { |
三角形-右下
1 | .triangle-rbottom { |
三角形-上下-对角
1 | .triangle-tbottom-diagonal { |
其实是向上的三角和向下的三角的总和,不信可以把border-top和border-bottom的颜色改成不一样的就会发现了
三角形-上下-覆盖
1 | .triangle-tbottom-cover { |
其实是原理跟上一个一样,上下三角形要覆盖所以用到了定位而且把上下三角形分给了当前元素和当前元素的伪元素:after
调整.triangle-tbottom-cover:after
的top
值即可得到六角形
三角形-上下-时间沙漏
1 | .triangle-tbottom-time { |
跟上一个类似,只是定位的距离做了一些改变
圆
1 | .semicircle { |
注:宽高要相等,否则就是椭圆了
同心圆
1 | .circle-circle { |
椭圆-水平
1 | .oval-horizontal { |
注:水平椭圆即宽度>高度;在本例中border-radius的取值,第一个值为宽度的一半即半长轴,第二个值为高度的一半即半短轴,但也可以直接写成border-radius:50%
即宽高都各取一半
椭圆-垂直
1 | .oval-vertical { |
注:水平椭圆即宽度<高度;在本例中border-radius的取值,第一个值为宽度的一半即半短轴,第二个值为高度的一半即半长轴,但也可以直接写成border-radius:50%
即宽高都各取一半
表图
1 | .chartColorful { |
其实这种写法跟1中CSS之border前言一样,只是在那个基础上增加了圆角弧度border-radius而已
半圆-上半圆
1 | .semicircle-top { |
border-radius
中取值的顺序为左上角 右上角 右下角 左下角,具体请看我的博客CSS之border详解
半圆-下半圆
1 | .semicircle-bottom { |
半圆-左半圆
1 | .semicircle-left { |
半圆-右半圆
1 | .semicircle-right { |
四分之一圆-上、下、左、右
1 | .quarterCircle { |
跟前面三角形对应的实现方法一样,只是在三角形的基础上加上border-radius:50%
即可,所以这里就不再重复写了,如果需要可以在评论去留言
四分之一圆-左上
1 | .quarterCircle-ltop { |
注:因为这里画的是四分之一圆,所以宽高即为半径,而border-radius的取值等于半径时即可成圆的弧度,所以这里border-radius取值为100%,当然也可以不用百分比表示,而用像素值50px,原理是一样的
当border-radius取值为50%时是如下形状
四分之一圆-右上
1 | .quarterCircle-rtop { |
四分之一圆-右下
1 | .quarterCircle-rbottom { |
四分之一圆-左下
1 | .quarterCircle-lbottom { |
四分之三圆-上开口
1 | .chart-top { |
四分之三圆-下开口
1 | .chart-bottom { |
四分之三圆-左开口
1 | .chart-left { |
四分之三圆-右开口
1 | .chart-right { |
书签
1 | .bookmark{ |
有两种方法,这种写法书签的高度是由border-top的宽度50px与border-bottom的宽度30px相加得到的,其实跟CSS之border前言中的第二张图原理是一样的1
2
3
4
5
6
7.bookmark2{
width: 0;
height: 100px;
border-left: 50px solid green;
border-right: 50px solid yellowgreen;
border-bottom: 35px solid transparent;
}
这种方法书签的高度是由height确定的,为了便于理解,这里把左右边框颜色做了区分
胶囊
1 | .capsule { |
这种方法书签的高度是由height确定的,为了便于理解,这里把左右边框颜色做了区分
注:border-radius的取值为高度的一半即可(胶囊其实就是两侧为半圆形,中间为矩形的图形,为实现两侧的半圆形让border-radius的值为高度的一半即半径即可),当宽高交换时即为垂直方向上的胶囊,此处不再列举
半胶囊
1 | .capsule-top { |
倾斜半胶囊
1 | .capsule-top-r45 { |
其实就是让半胶囊旋转倾斜一定角度
心形
心形其实是由半胶囊组成的1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38.heart {
position: relative;
}
.heart:before,
.heart:after {
width: 40px;
height: 60px;
position: absolute;
content: "";
left: 50px;
top: 0;
background: yellowgreen;
-moz-border-radius: 50px 50px 0 0;
border-radius: 50px 50px 0 0;
-webkit-transform: rotate(-45deg);
-moz-transform: rotate(-45deg);
-ms-transform: rotate(-45deg);
-o-transform: rotate(-45deg);
transform: rotate(-45deg);
-webkit-transform-origin: 0 100%;
-moz-transform-origin: 0 100%;
-ms-transform-origin: 0 100%;
-o-transform-origin: 0 100%;
transform-origin: 0 100%;
}
.heart:after {
left: 10px;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
-o-transform: rotate(45deg);
transform: rotate(45deg);
-webkit-transform-origin: 100% 100%;
-moz-transform-origin: 100% 100%;
-ms-transform-origin: 100% 100%;
-o-transform-origin: 100% 100%;
transform-origin: 100% 100%;
}
注:transform-origin
设置旋转元素的基点,第一个值为X轴方向向右,第二个值为Y轴方向向下,所以0 100%
为以左下角为基点旋转,100% 100%
为以右下角为基点旋转
当然也可以这么写1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27.heart{
position: relative;
-moz-transform: rotate(-45deg);
-ms-transform: rotate(-45deg);
-o-transform: rotate(-45deg);
-webkit-transform: rotate(-45deg);
transform: rotate(-45deg);
}
.heart::after{
content: '';
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
-o-transform: rotate(45deg);
-webkit-transform: rotate(45deg);
transform: rotate(90deg);
position: absolute;
top: 10px;
left: 10px;
}
.heart,.heart::after {
width: 40px;
height: 60px;
background: yellowgreen;
-moz-border-radius: 20px 20px 0 0;
-webkit-border-radius: 20px 20px 0 0;
border-radius: 20px 20px 0 0;
}
旋转心形
1 | .heart { |
其实就是在心形的基础上,让元素旋转一定的角度,即修改transform: rotate()
中的值,注旋转时要设置旋转的基点,设置旋转基点前要给元素规定宽高,否则会以整个文档中心为基点进行旋转
或者第二种画心形的方法中,直接修改.heart
的transform: rotate()
值即可
这里我就列举了一个例子,想要什么角度的心形,自行修改旋转角度即可得到,就不再一一列举出来了
多角形
五角星
1 | .star-five { |
其实就是两个等腰钝角三角形和一个等腰锐角三角形组合而成,这两个等腰钝角三角形都是由向上三角形(即只显示下边框)旋转各自的度数组成,然后再加上一个向上三角形就成了五角星,把这三个形状分为不同颜色,如下图就可以看出
红色和绿色为两个钝角等腰三角形,蓝色的是一个锐角等腰三角形
六角星
关于六角星,我们在六角星-上下-覆盖中已经提到过了,就是调整.triangle-tbottom-cover:after
的top
值即可得到六角星1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19.star-six {
width: 0;
height: 0;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 100px solid yellowgreen;
position: relative;
}
.star-six:after {
content: " ";
width: 0;
height: 0;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-top: 100px solid yellowgreen;
position: absolute;
top: 33px;
left: -50px;
}
八角星
1 | .star-eight { |
即两个正方形旋转一定,角度然后叠加在一起
十二角星
1 | .star-twelve{ |
很明显就是有3个正方形旋转一定角度,然后叠加而成的,后面的就以此类推了,都是由基础图形旋转叠加所得
多边形
五边形
1 | .pentagon { |
六边形
1 | .hexagon { |
上面这个例子是由两个三角形和一个矩形组成的,下面这个例子是由两个梯形组成的,它们得到的效果是相同的,都是上面这个图1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19.hexagon {
width: 0;
height: 50px;
border-top: 25px solid transparent;
border-right: 50px solid yellowgreen;
border-bottom: 25px solid transparent;
position: relative;
}
.hexagon:before {
content: "";
width: 0;
height: 50px;
position: absolute;
top: -25px;
left: 50px;
border-top: 25px solid transparent;
border-left: 50px solid yellowgreen;
border-bottom: 25px solid transparent;
}
有趣的是调整.hexagon:before
的top
和left
会得到不同的效果,例如当设置top
和left
均为0时会组成平行四边形
当设置top:-25px;left:0;
时,会组成下面的图形
八边形
1 | .octagon { |
由两个梯形和一个矩形组成,一次类推,其实多边形的实现都是由简单的三角形、矩形、梯形旋转堆叠而成的
鸡蛋
1 | .egg { |
注:border-radius
中前四个值是四个角在width
的基础上的圆角度值,/
之后的四个值是四个角在height
的基础上的圆角度值
钻石
1 | .diamond { |
很简单,跟多边形的原理一样,就是由一个梯形和一个三角形组成
无穷大
1 | .infinity { |
由两个分别右下角和左下角圆角弧度为0,其它角弧度均为50%的矩形旋转一定的角度组成而得,或许区别一下.infinity:before
和.infinity:after
的边框颜色,会看的更明显
八卦
1 | .gossip { |
从下面这张图可以看出,其实这个八卦图是由一个底边框为50%,其它边框为2px的圆和两个宽高均为12px且都18px边框包围的圆组成
总结:通过这么多图形,我们不难发现,其实很多看起来很复杂的形状都是由最初的简单的形状通过旋转组合而成的,在实现这些图形的过程中,我也有很多发现,很多时候不经意间的调整某个值,会发生意想不到的效果。这里仅仅列举了一部分,我相信肯定还有更多好玩的有趣的图形等待我们发现,你还有哪些图形,可以在评论区留言,大家一起讨论学习一下
最后,本篇文章是由二蛋的前端博客:http://yyeggs.com//CSS_border_graph/ 整理的,其中有很多都是我在整理的时候意外发现的,也有很多我自己的理解和解释,所以转载请注明,另外这里的部分代码整理于http://www.itivy.com/ivy/archive/2012/1/16/css-shape.html 也请同样注明