Effective前端3:用CSS画一个三角形
p { text-indent: 2em }
.triangle-container p { text-indent: 0 }
img { margin: 15px 0 }
三角形的场景很常见,打开一个页面可以看到各种各样的三角形:

由于div一般是四边形,要画个三角形并不是那么直观。你可以贴一张png,但是这种办法有点low,或者是用svg的形式,但是太麻烦。三角形其实可以用CSS画出来。如上图提到,可以分为两种三角形,一种是纯色的三角形,第二种是有边框色的三角形,先介绍最简单的纯色三角形。
1. 三角形的画法
三角形可以用border画出来,首先一个有四个border的div应该是这样的:

然后把它的高度和宽度去掉,剩下四个border,就变成了:

再把border-top去掉,没有了border-top就把上面的区域给裁掉了:

接下来,再让左右两边的border透明,就是一个三角形了:

这里是用了底部的border作为三角形,如果要取左边border,同理只需让上下两个border颜色为transparent,同时不要右边的border:
CSS
border-bottom: 50px solid transparent;
border-left: 50px solid #000;
|
1
2
3
|
border-top:50px solid transparent;
border-bottom:50px solid transparent;
border-left:50px solid #000;
|
效果如下:
斜边在左边
斜边在顶部
斜边在右边
2. 控制三角形的角度
上面画的三角形是一个直角三角形,用得比较多的应该是等边三角形,那么怎样画一个等边三角形呢?
首先,保持border-left和border-right的大小不变,让border-bottom不断变大,观察下形状是怎么变的:
bottom 40px
bottom 50px
bottom 60px
可以看到顶部的角度在不断变小,换句话说三角形底边长不变,而底边的高在不断地变大,因为border-bottom-width其实就是底边的高:

然后再做第二个实验,让border-left不断地变大,其它两个border保持不变:
left 40px
left 50px
left 60px
left 40px
left 50px
left 60px
通过上下对比,看出border-left变大增加了左边那条边的长度。由此可以想到,如果右边的border-width是0的话,那么它将是一个直角三角形,并且直角在右下角:
right 0
right 0
即代码为:
CSS
border-right: 0 solid transparent;
border-bottom: 40px solid #000;
|
1
2
3
|
border-left: 60px solid transparent;
border-right: 0 solid transparent;
border-bottom: 40px solid #000;
|
border-right为0,也就是border-right可以和width、height一样不用设置,两行代码即可。其中border-left决定了底部直角边的长度,而border-bottom决定了右边直角边的长度,刚好跟直观的想法相反。明白这一点很重要。
同时,通过切换四个border的设置就可以控制直角边在不同的位置,例如如果想要直角边在右上角的话,那应该是设置border-left和border-top,读者可以自行想象一下。
回到上面的问题,怎样画一个等边三角形,等边三角形的底边的高是底边的1/sqrt(2)倍。经过上面的分析可以知道,底边是由border-left加上border-right的长度合起来的,而底边的高是border-bottom,所以如果border-bottom-width是40px,那么border-left和border-right的宽度都是40px * sqrt(2) / 2 ~= 28px,约等于28px。验证一下:
确实画出了一个等边三角形。到这里你可能会有一个疑问:上面取了约等,因为像素大小是不能为小数,但是上面是28个px,舍掉的小数相对很小,如果我画的三角形本来就比较小,像那种下拉的右边的三角形,舍去个小数影响比较大,这时候怎么办?其实这个问题本身是无解的,因为你要画的区域就那么小,要想画个绝对等边的三角形本身就有难度,就算用其它的办法也会有一样的困境。
3. 画一个有边缘色的三角形
这种三角形很常见,特别是tip的提示框、聊天消息的框等:
上面实现是用了一个图标字体,跟svg差不多,但是同于高度没有那么刚刚好,导致它看起来有点错位了。如果用CSS画,就不会有这种问题。
这种画法其实很简单,只是不容易想到——就是先画一个深色的三角形,然后再画一个同样大小白色的三角形盖在它上面,两个三角形错位2个像素,这样深色三角形的边缘就刚好露出一个像素。
首先画一个深色的三角形:
XHTML
.chat-msg {
width: 300px;
height: 80px;
border: 1px solid #ccc;
position: relative;
}
.chat-msg:before{
position: absolute;
left: -10px;
top: 34px;
border-top: 6px solid transparent;
border-bottom: 6px solid transparent;
border-right: 10px solid #ccc;
}
</style>
<div class="chat-msg">hi,亲</div>
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
<style>
.chat-msg {
width:300px;
height:80px;
border:1pxsolid#ccc;
position:relative;
}
.chat-msg:before{
position:absolute;
left:-10px;
top:34px;
border-top:6px solid transparent;
border-bottom:6px solid transparent;
border-right:10px solid #ccc;
}
</style>
<div class="chat-msg">hi,亲</div>
|
效果如下:

然后再画一个白色的三角形盖上去,错位两个像素
CSS
position: absolute;
left: -8px;
top: 34px;
border-top: 6px solid transparent;
border-bottom: 6px solid transparent;
border-right: 10px solid #fff;
}
|
1
2
3
4
5
6
7
8
|
.chat-msg:before{
position:absolute;
left:-8px;
top:34px;
border-top:6px solid transparent;
border-bottom:6px solid transparent;
border-right:10px solid #fff;
}
|
效果如下:

到这里就说明完了,上面用的属性都是CSS 2最基本的一些属性,所以没有兼容性问题。这个方法的缺点是没办法设置三角形的box-shadow的轮廓为一个三角形,所以用不了box-shadow。
除了画一个三角形之外,还可以画其它很多形状,像五角形、爱心等等,详见css-tricks,但是这种由于借助了transform等属性,所以兼容性没有画一个三角形的好,并且大小不好扩展,你要改它的大小,要么你知道它画的原理,然后一个个去改各个构成的属性位置和大小,要么用scale,用scale会有文档流占用空间不一致的问题。所以这种比较复杂的css画法,实用性并不是很大,还不如用个图标字体。
扩展阅读:
Effective前端3:用CSS画一个三角形的更多相关文章
- Effective前端(3)用CSS画一个三角形
来源:https://zhuanlan.zhihu.com/p/26160325 三角形的场景很常见,打开一个页面可以看到各种各样的三角形: 由于div一般是四边形,要画个三角形并不是那么直观.你可以 ...
- CSS画一个三角形,CSS绘制空心三角形,CSS实现箭头
壹 ❀ 引 这两天因为项目工作较少,闲下来去看了GitHub上关于面试题日更收录的文章,毕竟明年有新的打算.在CSS收录中有一题是 用css创建一个三角形,并简述原理 .当然对于我来说画一个三角形是 ...
- Effective前端1---chapter 2 用CSS画一个三角形
1.CSS画三角形的画法 第一步:三角形可以用border画出来,首先一个有四个border的div长这样: <div class="triangle"></di ...
- 使用CSS画一个三角形
<div style="width:0px;height:0px;border-width:40px;border-style:solid;border-color:transpare ...
- 【前端切图】用css画一个卡通形象-小猪佩奇
最近在腾讯云技术社区遇到了一位奇才,用css画出了一个社会人小猪佩奇,不得不服.研究了一下他的文章https://segmentfault.com/a/1190000014909658,感觉甚是有趣, ...
- 如果用css的border属性画一个三角形
假设页面中有个div,如何通过css做一个三角形.这是我们项目中用到的今天就稍微总结下.顺便说一句偷偷写博客的感觉还挺爽 div { width: 0; height: 0; border-top: ...
- 用css画出三角形
看到有面试题里会有问到如何用css画出三角形 众所周知好多图形都可以拆分成三角形,所以说会了画三角形就可以画出很多有意思的形状 画出三角形的原理是调整border(边框)的四个方向的宽度,线条样式以及 ...
- 如何用css画出三角形
看到有面试题里会有问到如何用css画出三角形 众所周知好多图形都可以拆分成三角形,所以说会了画三角形就可以画出很多有意思的形状 画出三角形的原理是调整border(边框)的四个方向的宽度,线条样式以及 ...
- 用css画出三角形【转】
看到有面试题里会有问到如何用css画出三角形 众所周知好多图形都可以拆分成三角形,所以说会了画三角形就可以画出很多有意思的形状 画出三角形的原理是调整border(边框)的四个方向的宽度,线条样式以及 ...
随机推荐
- ExtJS 4.2 Grid组件的单元格合并
ExtJS 4.2 Grid组件本身并没有提供单元格合并功能,需要自己实现这个功能. 目录 1. 原理 2. 多列合并 3. 代码与在线演示 1. 原理 1.1 HTML代码分析 首先创建一个Grid ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(55)-Web打印
系列目录 前言 1.本次主要弥补工作流,用户表单数据的打印 2.使用JQprint做为web打印插件 3.兼容:FireFox,Chrome,IE. 4.没有依赖也没有配置,使用简单 代码下载:htt ...
- 比Mysqli操作数据库更简便的方式 。PDO
下面来说一下PDO 先画一张图来了解一下 mysqli是针对mysql这个数据库扩展的一个类 PDO是为了能访问更多数据库 如果出现程序需要访问其他数据库的话就可以用PDO来做 PDO数据访问抽象层1 ...
- Angular企业级开发(1)-AngularJS简介
AngularJS介绍 AngularJS是一个功能完善的JavaScript前端框架,同时是基于MVC(Model-View-Controller理念的框架,使用它能够高效的开发桌面web app和 ...
- Smarty的基本使用与总结
含义: Smarty是PHP的一个引擎模板,可以更好的进行逻辑与显示的分离,即我们常说的MVC,这个引擎的作用就是将C分离出来. 环境需求:PHP5.2或者更高版本 我使用的环境是:PHP5.3,wi ...
- 前端制作动画的几种方式(css3,js)
制作动态的网页是是前端工程师必备的技能,很好的实现动画能够极大的提高用户体验,增强交互效果,那么动画有多少实现方式,一直对此有选择恐惧症的我就总结一下,以便在开发的时候选择最好的实现方式. 1.css ...
- [原][Docker]特性与原理解析
Docker特性与原理解析 文章假设你已经熟悉了Docker的基本命令和基本知识 首先看看Docker提供了哪些特性: 交互式Shell:Docker可以分配一个虚拟终端并关联到任何容器的标准输入上, ...
- 小兔JS教程(三)-- 彻底攻略JS回调函数
这一讲来谈谈回调函数. 其实一句话就能概括这个东西: 回调函数就是把一个函数当做参数,传入另一个函数中.传进去的目的仅仅是为了在某个时刻去执行它. 如果不执行,那么你传一个函数进去干嘛呢? 就比如说对 ...
- ASP.NET MVC——模型绑定
这篇文章我们来讲讲模型绑定(Model Binding),其实在初步了解ASP.NET MVC之后,大家可能都会产生一个疑问,为什么URL片段最后会转换为例如int型或者其他类型的参数呢?这里就不得不 ...
- 解决使用IE8打开ADFS 3.0登录页面
系统上线前一天,发现客户竟然有XP系统和2003系统,这些系统都不能访问外网.测试时,客户端是IE8,打开我们系统ADFS的登录页面,一直在Loading,无法打开,也不报错.后来通过fiddler跟 ...