用 border + 零宽高 + 三边 transparent 是最可靠、兼容性最好、语义最轻的三角形绘制方案,因其依赖浏览器原生边框交汇渲染机制,不依赖 transform 或 clip-path,IE8+ 全支持。

直接说结论:用 border + 零宽高 + 三边 transparent 是最可靠、兼容性最好、语义最轻的方案,99% 的小三角形图标都该从这里起步。
为什么 border 能画出三角形
浏览器渲染边框时,相邻两边会在角上交汇成一个斜边——当元素 width 和 height 都为 0,四条边就完全退化为四个等腰直角三角形,顶点汇聚于中心。只要把其中三边设为 transparent,剩下那一边的实色边框自然就显现出一个清晰的三角形。
这不是“模拟”或“遮罩”,而是浏览器原生渲染行为,不依赖 transform、clip-path 或渐变,所有 IE8+ 都支持。
- 必须同时设置
width: 0和height: 0,缺一不可 -
border-style: solid是隐式前提,dashed或dotted会断裂 - 边框宽度决定三角形大小,但左右/上下边框宽度不相等时,得到的是直角三角形而非等边
- 例如指向下的等边三角形:底边宽度 ≈ 左右透明边宽度 × √3(实际常用
border-bottom: 60px+border-left/right: 35px近似)
border 方向与方向控制的关键参数
三角形朝向由哪条边设为实色决定,其余三边必须为 transparent;但写法有坑,容易漏掉重置。
立即学习“前端免费学习笔记(深入)”;
- 指向上:
border-top: 20px solid #333; border-right: 20px solid transparent; border-bottom: 20px solid transparent; border-left: 20px solid transparent; - 指向右:
border-left: 20px solid #333; border-top: 20px solid transparent; border-bottom: 20px solid transparent;(border-right可省略,但显式写transparent更安全) - 指向左:用
border-right实色,其他三边透明 —— 注意不是border-left设负值,那无效 - 常见错误:只写
border-top: 20px solid #333,没管其他边,默认继承上一条规则或用户代理样式,导致意外边框残留
伪元素 + border 是更实用的图标写法
纯 div 占位画三角形会破坏文档流高度(即使宽高为 0,border 仍参与 layout),真正做下拉箭头、气泡尖角时,应该用 ::after 或 ::before。
- 父容器需加
position: relative - 伪元素设
position: absolute,再用top/right/bottom/left定位到目标位置(比如下拉菜单下方居中) - 定位后常需
transform: translate(-50%, 0)微调水平居中,因为三角形本身无 content-box 基准点 - 避免用
margin或top: 50%硬调,容易在不同字号/缩放下偏移
别踩这些兼容性和表现坑
看似简单,但在真实项目里最容易翻车的地方往往藏在细节里:
-
box-sizing:如果全局设了box-sizing: border-box,对零宽高元素无影响,但若后续加 padding 或其他修饰,建议显式写box-sizing: content-box避免混淆 - 高清屏(dpr > 1)下,1px 边框可能被 subpixel 渲染模糊,三角形尖角发虚 —— 解决办法是统一用偶数像素(如
12px、16px),或改用clip-path(但放弃 IE 支持) - 用在 SVG 内联图标或 font-icon 混合场景时,
border三角形无法 inherit 父级color,必须单独指定颜色;而clip-path+currentColor才能真正响应主题色 - 动画需求(如旋转展开箭头):直接对
border三角形做transform: rotate()会失真,应包裹一层span或用clip-path替代
真正难的从来不是“怎么画出来”,而是“怎么让它在各种上下文里不突兀、不破布局、不糊、不卡主题”。border 方案胜在稳,但稳的前提是每个透明边都写全、每个定位都算清、每个 dpr 场景都验过。


















