CSS三角形的落实原理及使用

酷酷的 CSS3 三角形运用

2016/08/04 · CSS · 2
评论 ·
CSS3,
三角形

原文出处: keepfool   

图片 1

如何用CSS画三角形,CSS画三角形

很多时候页面都需要一个或者多个小型三角形!多数人直接用PS扣个图片

下面用CSS简单画几个最终效果如下图

图片 2

    <div class="border-all-color"></div>
    <div class="border-left-color"></div>
    <div class="border-top-color"></div>
    <div class="border-right-color"></div>
    <div class="border-bottom-color"></div>

.border-all-color {
    margin: 20px auto;
    width: 0;
    height: 0;
    border-top: 40px solid coral;
    border-right: 40px solid lightblue;
    border-bottom: 40px solid lightgreen;
    border-left: 40px solid mediumpurple;
}

.border-left-color,
.border-top-color,
.border-right-color,
.border-bottom-color{
    width: 0;
    height: 0;
    margin: 10px auto;
    border: 20px solid transparent;
}

.border-left-color{
    border-left-color: #9370DB;
}
.border-top-color{
    border-top-color: #FF7F50;
}
.border-right-color{
    border-right-color: #ADD8E6;
}
.border-bottom-color{
     border-top-color: #90EE90;
 }

 

很多时候页面都需要一个或者多个小型三角形!多数人直接用PS扣个图片
下面用CSS简单画几个最终效果如下…

概述

在早期的前端Web设计开发年代,完成一些页面元素时,我们必须要有专业的PS美工爸爸,由PS美工爸爸来切图,做一些圆角、阴影、锯齿或者一些小图标。

在CSS3出现后,借助一些具有魔力的CSS3属性,使得这些元素大多都可以由开发人员自己来完成。在开始阅读这篇文章前,我们先喊个口号:不想当艺术家的程序员不是好设计师!

本文的Demo和源代码已放到GitHub,如果您觉得本篇内容不错,请点个赞,或在GitHub上加个星星!

Triangle
Demo 
|  Page
Demo 
|  GitHub Source

之前在懒懒分会上分享的一点关于border画小图的内容, 完整的ppt在(链接挂了).

图例

我们先来看一副设计图

图片 3

这幅图复杂的元素不多,布局也较为简单,我们大致分析一下,需要PS美工爸爸帮忙做的只有一件事情,就是将上半部分的蓝色背景图给抠出来。
除此之外,出现在这幅设计图的一些特殊形状和小图标,都可以通过CSS3来实现。
我们将这些特殊形状和小图标分为两类:

1. 可以用Icon Font实现的

图片 4图片 5

Icon
Font是将一些图标作成字体文件,在CSS中指定font-face和font-family,然后为每个图标指定相应的class。
在网页中使用Icon
Font就像使用普通的文字一样,比如font-size属性可以设定图标的大小,设定color属性可以设定图标的颜色。
更多内容,请参考阿里巴巴矢量图标管理网站:。

2. 不能用IconFont实现的

图片 6

为什么这些图形不用IconFont实现呢?因为通常Icon
Font提供的都是一些正方形的矢量图标,也就是长等于宽的图标。
本篇要讲的就是如何通过CSS3来实现这4个图形。

原理

三角形

不知大家注意到了没有,这4个图形都包含了一个特殊的元素——三角形。
这4个图形,都是由三角形、长方形,或者是一个被啃掉了一口的长方形组成的。

CSS3是如何实现三角形的呢?——答案是通过边框,也就是border属性。

css盒模型

图片 7

一个盒子包括: margin+border+padding+content
– 上下左右边框交界处出呈现平滑的斜线. 利用这个特点,
通过设置不同的上下左右边框宽度或者颜色可以得到小三角, 小梯形等.

– 调整宽度大小可以调节三角形形状.

长方形边框

HTML的块级元素都是长方形的,比如我们设定了以下样式:

JavaScript

<style> .simple-retangle { margin: 50px auto; width: 200px;
height: 200px; border: 40px solid salmon; } </style> <div
class=”simple-retangle”></div>

1
2
3
4
5
6
7
8
9
<style>
    .simple-retangle {
        margin: 50px auto;
        width: 200px;
        height: 200px;
        border: 40px solid salmon;
    }
</style>
<div class="simple-retangle"></div>

如大家所认知的,这只是一个简单的长方形,这个长方形在画面中是这样显式的:

图片 8

这个长方形太单调了,再给它点颜色看看,咱们来个彩色边框吧。

JavaScript

<style> .colored-border-retangle { margin: 50px auto; width:
200px; height: 200px; border-top: 40px solid coral; border-right: 40px
solid lightblue; border-bottom: 40px solid lightgreen; border-left: 40px
solid mediumpurple; } </style> <div
class=”colored-border-retangle”></div>

1
2
3
4
5
6
7
8
9
10
11
12
<style>
    .colored-border-retangle {
        margin: 50px auto;
        width: 200px;
        height: 200px;
        border-top: 40px solid coral;
        border-right: 40px solid lightblue;
        border-bottom: 40px solid lightgreen;
        border-left: 40px solid mediumpurple;
    }
</style>
<div class="colored-border-retangle"></div>

在画面中,每个边框都变成一个梯形了。

图片 9

为什么它会变成梯形呢?

图片 10

请注意长方形的4个角,以左上角为例,它到底是属于左边框还是上边框呢?
左上角,既属于左边框,又属于上边框,角落的归属成了一个问题,浏览器为了不让边框打架,就让二位各分一半吧。
于是乎左上角就被一分为二,变成了两个三角形,三角形靠近哪个边框,就显示那个边框的颜色。

示例1

一般情况下, 我们设置盒子的宽高度, 及上下左右边框, 会呈现如下图

图片 11

#test1 {
    height:20px;
    width:20px;
    border-color:#FF9600 #3366ff #12ad2a #f0eb7a;
    border-style:solid;
    border-width:20px;
}

三角形的实现

再看看文章开头的4个图案,你是不是又发现了这样一个规律?每个三角形都是“小家碧玉”的,它们没有内容
既然如此,我们把上面这个彩色边框的矩形内容拿掉,看看会发生什么。

JavaScript

<style> .colored-border-empty-retangle { margin: 50px auto;
border-top: 40px solid coral; border-right: 40px solid lightblue;
border-bottom: 40px solid lightgreen; border-left: 40px solid
mediumpurple; } </style> <div
class=”colored-border-empty-retangle”></div>

1
2
3
4
5
6
7
8
9
10
<style>
    .colored-border-empty-retangle {
        margin: 50px auto;
        border-top: 40px solid coral;
        border-right: 40px solid lightblue;
        border-bottom: 40px solid lightgreen;
        border-left: 40px solid mediumpurple;
    }
</style>
<div class="colored-border-empty-retangle"></div>

呜,cool!左边和右边都是三角形了 耶!

图片 12

为什么上边和下边还是梯形呢?这是因为块级元素默认会在页面上水平平铺。 理解这一点,让上边和下边也变成三角形就简单了,将元素的width属性设为0:

JavaScript

<style> .colored-border-empty-retangle { margin: 50px auto; width:
0; height: 0; border-top: 40px solid coral; border-right: 40px solid
lightblue; border-bottom: 40px solid lightgreen; border-left: 40px solid
mediumpurple; } </style> <div
class=”colored-border-empty-retangle”></div>

1
2
3
4
5
6
7
8
9
10
11
12
<style>
    .colored-border-empty-retangle {
        margin: 50px auto;
        width: 0;
        height: 0;
        border-top: 40px solid coral;
        border-right: 40px solid lightblue;
        border-bottom: 40px solid lightgreen;
        border-left: 40px solid mediumpurple;
    }
</style>
<div class="colored-border-empty-retangle"></div>

现在上下左右4个边框都是三角形了。

图片 13

假设我们不要4个三角形,也不要让它们凑一块,我们就只要1个三角形,该如何做呢?
将其他3个边框的颜色设为透明色:

JavaScript

<style> .triangle-top, .triangle-right, .triangle-bottom,
.triangle-left { margin: 20px auto; width: 0; height: 0; border: 100px
solid transparent; } .triangle-top { border-top-color: coral; }
.triangle-right { border-right-color: lightblue; } .triangle-bottom {
border-bottom-color: lightgreen; } .triangle-left { border-left-color:
mediumpurple; } </style> <div
class=”triangle-top”></div> <div
class=”triangle-right”></div> <div
class=”triangle-bottom”></div> <div
class=”triangle-left”></div>

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
<style>
    .triangle-top,
    .triangle-right,
    .triangle-bottom,
    .triangle-left {
        margin: 20px auto;
        width: 0;
        height: 0;
        border: 100px solid transparent;
    }
    
    .triangle-top {
        border-top-color: coral;
    }
    
    .triangle-right {
        border-right-color: lightblue;
    }
    
    .triangle-bottom {
        border-bottom-color: lightgreen;
    }
    
    .triangle-left {
        border-left-color: mediumpurple;
    }
</style>
<div class="triangle-top"></div>
<div class="triangle-right"></div>
<div class="triangle-bottom"></div>
<div class="triangle-left"></div>

图片 14

示例2

在上面基础上, 我们把宽高度都设为0时, 会呈现上述的边界斜线.

图片 15

#test2 {
    height:0;
    width:0;
    overflow: hidden; /* 这里设置overflow, font-size, line-height */
    font-size: 0;     /*是因为, 虽然宽高度为0, 但在IE6下会具有默认的 */
    line-height: 0;  /* 字体大小和行高, 导致盒子呈现被撑开的长矩形 */
    border-color:#FF9600 #3366ff #12ad2a #f0eb7a;
    border-style:solid;
    border-width:20px;
}

这时, 其实我们已经看到有上下左右四个三角形了..如果, 我们把4种颜色,
只保留一种颜色, 余下3种颜色设置为透明(或者设置为和背景色相同的颜色),
那不就出现一个小三角了么

图案实现

知道了三角形的实现方法,那么下面4个图案实现起来就小Case了。

图片 16

这4个图案分别是:旗帜,向右的双实心箭头,气泡和丝带。

View
Demo

为了便于这几种图案的演示,我们先设定以下基础共通的样式

CSS

* { font-family: simhei, sans-serif; box-sizing: border-box; } html {
font-size: 62.5%; } body { background-color: lightblue; } div { margin:
20px auto; }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
* {
    font-family: simhei, sans-serif;
    box-sizing: border-box;
}
 
html {
    font-size: 62.5%;
}
 
body {
    background-color: lightblue;
}
 
div {
    margin: 20px auto;
}

示例3

只保留上面的橙色, 看看

图片 17

#test3 {
    height:0;
    width:0;
    overflow: hidden;
    font-size: 0;
    line-height: 0;
    border-color:#FF9600 transparent transparent transparent;
    border-style:solid;
    border-width:20px;
}

可是, IE6下不支持透明啊~~~, 会出现下图的样子

图片 18

找到一个在IE6下边框透明的文章中找到解决办法, 如下例

实现旗帜

旗帜图案是下半部分被啃掉了一口的长方形,这一口是个三角形。

图片 19
根据以上知识,我们很自然地就能想到实现方法,将border-bottom的颜色设置为透明的。

CSS

.flag { width: 0; height: 0; border: 2rem solid #FF6600;
border-top-width: 4rem; border-bottom-color: transparent;
border-bottom-width: 2rem; }

1
2
3
4
5
6
7
8
.flag {
    width: 0;
    height: 0;
    border: 2rem solid #FF6600;
    border-top-width: 4rem;
    border-bottom-color: transparent;
    border-bottom-width: 2rem;
}

示例4

IE6下, 设置余下三条边的border-style为dashed,,,即可达到透明的效果~
具体原因可以见参考资料3

图片 20

#test4 {
    height:0;
    width:0;
    overflow: hidden;
    font-size: 0;
    line-height: 0;
    border-color:#FF9600 transparent transparent transparent;
    border-style:solid dashed dashed dashed;
    border-width:20px;
}

当然, 在IE6下, 不设置透明, 将其颜色设置为背景色, 使其看不出来也是可以的.

实现双实心箭头

双实心箭头则是由两个三角形组成的

图片 21

为了减少页面的HTML元素,我们可以只提供一个元素实现第1个三角形,然后借助CSS3的伪类实现第2个三角形。
第1个三角形使用了相对定位,第2个三角形使用了绝对定位,使得第2个三角形能够紧挨着第1个三角形。

CSS

.rds-arrow-wrapper { position: relative; width: 20em; text-align:
center; } .rds-arrow, .rds-arrow:after { display: inline-block;
position: relative; width: 0; height: 0; border-top: 1rem solid
transparent; border-left: 2rem solid #fff; border-bottom: 1rem solid
transparent; border-right: 2rem solid transparent; } .rds-arrow {
margin-left: 1rem; } .rds-arrow:after { content: “”; position: absolute;
left: 100%; top: -1rem; bottom: 0; }

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
.rds-arrow-wrapper {
    position: relative;
    width: 20em;
    text-align: center;
}
 
.rds-arrow,
.rds-arrow:after {
    display: inline-block;
    position: relative;
    width: 0;
    height: 0;
    border-top: 1rem solid transparent;
    border-left: 2rem solid #fff;
    border-bottom: 1rem solid transparent;
    border-right: 2rem solid transparent;
}
 
.rds-arrow {
    margin-left: 1rem;
}
 
.rds-arrow:after {
    content: "";
    position: absolute;
    left: 100%;
    top: -1rem;
    bottom: 0;
}

需要注意的是,箭头方向是向右的,但在CSS里面是通过border-left的颜色来控制的。

示例5

上面我们画的小三角的斜边都是依靠原来盒子的边, 还有另外一种形式的小三角,
就是斜边在盒子的对角线上

图片 22

#test5 {
    height:0;
    width:0;
    overflow: hidden;
    font-size: 0;
    line-height: 0;
    border-color:#FF9600 #3366ff transparent transparent;
    border-style:solid solid dashed dashed;
    border-width:40px 40px 0 0 ;
}

保留其中一种颜色, 就可以得到斜边在对角线上的三角形了…多个这样的三角形,
通过设置边框大小, 颜色, 拼凑起来可以形成任意形状的三角形.

图片 23

像这种不规则的三角形, 延伸一下, 放在气泡框上,
就可以省去拼背景图片的麻烦了.

图片 24

另外, 关于气泡框, 可以使用棱形字符(◆)来实现, 设置其font-size,
颜色和背景色一致, 定位可以使用margin负值和absolute绝对定位来实现,
见示例.

 

 

实现气泡

气泡是我们常见的一种图案,它是由一个三角形和一个长方形组成的。

图片 25

由于三角形是放在长方形前面的,所以我们使用:before伪类,并设置绝对定位。

CSS

.bubble { position: relative; background-color: #33AAEE; width: 10rem;
height: 3rem; font-size: 2rem; line-height: 3rem; color: #FFF;
text-align: center; } .bubble:before { position: absolute; content: “”;
right: 100%; top: 1rem; width: 0; height: 0; border-top: 0.6rem solid
transparent; border-right: 0.6rem solid #33AAEE; border-bottom: 0.6rem
solid transparent; border-left: 0.6rem solid transparent; } .bubble
.text { display: inline-block; }

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
.bubble {
    position: relative;
    background-color: #33AAEE;
    width: 10rem;
    height: 3rem;
    font-size: 2rem;
    line-height: 3rem;
    color: #FFF;
    text-align: center;
}
 
.bubble:before {
    position: absolute;
    content: "";
    right: 100%;
    top: 1rem;
    width: 0;
    height: 0;
    border-top: 0.6rem solid transparent;
    border-right: 0.6rem solid #33AAEE;
    border-bottom: 0.6rem solid transparent;
    border-left: 0.6rem solid transparent;
}
 
.bubble .text {
    display: inline-block;
}

应用之圆角生成

应该说是近似圆角,,其实由一个高度非常小的梯形展示出来
– 上梯形(无上边框,下左右3px宽度, 左右颜色去掉)+矩形+下梯形

图片 26

自适应圆角1:
– 整个rc设置为float: left 或 display: inline-block 分为top,bd,bottom,
top中又有两个层rc1和rc2, rc1只设置border-top, 高度为0,
并设置左右margin呈短小的一横线,
rc2只设置左右border并且左右margin小于rc1, height为1px,
中间bd设置左右border,不设置左右margin;

– 不过 IE 6&7 出现 bug:rc在IE6中依然显示为dispaly:block,而IE7中top 和
bottom缩成一坨,不肯扩展开来,而在rc1/rc2/rc3
中插入文字xxx后只能扩展到文字宽度,不能与bd对齐.

– 见自适应圆角1

自适应圆角2
– 自 Google 系产品的 1px 圆角按钮,,,三层div,
最外层div1正常设置边框宽度1px, 呈现出上下边框线, 中间div2只设置左右边框,
且把左右margin设置成负值, 呈现出圆角处的4个圆点
内层div3同样只设置左右边框, 同时margin上下空出div2的高度,
margin左右也设置与div2相同的负值.

– 见自适应圆角2

实现丝带

丝带的实现则稍微复杂一些,不过我们可以将它拆分成3个部分:

  1. 一个显示文字的长方形
  2. 左右两侧的耳朵(被啃了一口的长方形)
  3. 在下方用于显示阴影的两个小三角形

图片 27

第1步:实现丝带主体长方形

CSS

.ribbon { position: relative; width: 10rem; height: 3rem; padding:
0.7rem 0; font-size: 1.6rem !important; color: #fff; text-align:
center; background: #ff0066; }

1
2
3
4
5
6
7
8
9
10
.ribbon {
    position: relative;
    width: 10rem;
    height: 3rem;
    padding: 0.7rem 0;
    font-size: 1.6rem !important;
    color: #fff;
    text-align: center;
    background: #ff0066;
}

图片 28

第2步:实现丝带左右两侧的耳朵

:before伪类实现左耳朵,:after伪类实现右耳朵

CSS

.ribbon:before, .ribbon:after { content: “”; position: absolute;
display: block; bottom: -0.6rem; border: 1.5rem solid #ff0066; z-index:
-1; } .ribbon:before { left: -2.4rem; border-right-width: 1.5rem;
border-left-color: transparent; box-shadow: 1px 1px 0 rgba(176, 102,
166, 0.8); } .ribbon:after { right: -2.4rem; border-left-width: 1.5rem;
border-right-color: transparent; box-shadow: 0 1px 0 rgba(176, 102, 166,
0.8); }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
.ribbon:before,
.ribbon:after {
    content: "";
    position: absolute;
    display: block;
    bottom: -0.6rem;
    border: 1.5rem solid #ff0066;
    z-index: -1;
}
 
.ribbon:before {
    left: -2.4rem;
    border-right-width: 1.5rem;
    border-left-color: transparent;
    box-shadow: 1px 1px 0 rgba(176, 102, 166, 0.8);
}
 
.ribbon:after {
    right: -2.4rem;
    border-left-width: 1.5rem;
    border-right-color: transparent;
    box-shadow: 0 1px 0 rgba(176, 102, 166, 0.8);
}

图片 29

第3步:实现阴影

CSS

.ribbon .ribbon-content:before, .ribbon .ribbon-content:after { content:
“”; position: absolute; display: block; border-style: solid;
border-color: #bf004c transparent transparent transparent; bottom:
-0.6rem; } .ribbon .ribbon-content:before { left: 0; border-width:
0.6rem 0 0 0.6rem; } .ribbon .ribbon-content:after { right: 0;
border-width: 0.6rem 0.6rem 0 0; }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
.ribbon .ribbon-content:before,
.ribbon .ribbon-content:after {
    content: "";
    position: absolute;
    display: block;
    border-style: solid;
    border-color: #bf004c transparent transparent transparent;
    bottom: -0.6rem;
}
 
.ribbon .ribbon-content:before {
    left: 0;
    border-width: 0.6rem 0 0 0.6rem;
}
 
.ribbon .ribbon-content:after {
    right: 0;
    border-width: 0.6rem 0.6rem 0 0;
}

HTML代码:

XHTML

<div class=”ribbon”> <span
class=”ribbon-content”>金卡会员</span> </div>

1
2
3
<div class="ribbon">
    <span class="ribbon-content">金卡会员</span>
</div>

最终效果:

图片 30

其他小问题

  • 透明:

IE6浏览器不支持transparent透明属性,就border生成三角技术而言,直接设置对应的透明边框的border-style属性为
dotted或是dashed即可解决这一问题,原因是在IE6下,
点线与虚线均以边框宽度为基准,点线长度必须是其宽度的3倍以上(height>=border-width*3),虚线宽长度必须是其宽度的5倍
以上(height>=border-width*5),否则点线和虚线都不会出现.

  • IE6的奇偶bug:

如果定位外框高度或是宽度为奇数,则IE6下,绝对定位元素的低定位和右定位会有1像素的误差.所以,尽量保证外框的高度或宽度为偶数值.

  • IE6的空div高度bug:
    IE6下,空div会有莫名的高度,也就是说height:0;不顶用,此时形成的尖角的实际占高于其他浏览器是有差异的.可使用font-size:0; +
    overflow:hidden;修复此问题.

  • filter: chroma滤镜
    该属性属性可以设置一个对象中指定的颜色为透明色, 如:

    border-color: pink;
    filter: chroma(color=pink);

页面实现

有以上的知识基础,实现本文开头的设计图就较为简单了。
由于代码较长,我就不贴出来了,请各位直接到GitHub上查看这个demo吧。

View
Demo

扩展学习

通过上面给力的文章,我们了解到使用css制作兼容的小三角。

但是日常的小三角哪有这么简单呢?例如我们的一个下拉菜单,里面有一个小三角行的,小三角行有蓝色边框,底色为白色。这就需要运用两个小三角来制作定位了。

通常设置上面的ul相对于上面的li为position:absolute;

这两个的小三角行则是通过伪元素来制作,同时通过一些标签来兼容IE6和IE7的。如:

.header .menu ul:before,.header .menu ul .before {
display:inline-block;
width:0;
height:0;
overflow:hidden;
line-height:0;
font-size:0;
vertical-align:middle;
border-bottom:7px solid #0088CC;
border-top:0 none;
border-left:7px dashed transparent;
border-right:7px dashed transparent;
_color:#FF3FFF;
_filter:chroma(color=#FF3FFF);
content:"";
left:37px;
position:absolute;
top:-7px
}
.header .menu ul:after,.header .menu ul .after {
display:inline-block;
width:0;
height:0;
overflow:hidden;
line-height:0;
font-size:0;
vertical-align:middle;
border-bottom:6px solid #ffffff;
border-top:0 none;
border-left:6px dashed transparent;
border-right:6px dashed transparent;
_color:#FF3FFF;
_filter:chroma(color=#FF3FFF);
content:"";
left:38px;
position:absolute;
top:-6px
}

同时我还发现了一个bug,那就是在IE6下面当隐藏UL,然后鼠标经过LI时显示时小三角不显示了,不知道是什么原因,我通过给UL直接设置为visibility:hidden而不是display:none,如果你也遇到同样的情况,希望这个发现能够对你有用,如果你无视IE6、IE7,那么就直接用伪元素吧。什么hack都不用。

总结

读完以上内容,是不是觉得实现这些图案变得很简单了?是不是感觉很酷?现在你可以叫自己为爸爸了。
三角形的运用场景非常之多,你尽可以发挥你的想象去实现它们!

2 赞 20 收藏 2
评论

图片 31

参考资料

  1. CSS小三角原理
  2. CSS气泡效果
  3. IE6下边框透明原理解析
  4. CSS3实现的机器猫图形

发表评论

电子邮件地址不会被公开。 必填项已用*标注