前言
在前端开发中,有时我们需要一些非矩形的图形来增强页面的视觉效果,比如下拉菜单的小箭头、加载动画的扇形进度条。利用纯 CSS 绘制这些图形,不仅能减少图片请求,还能展示你对 CSS 底层渲染机制的深刻理解。
一、 纯 CSS 绘制三角形
1. 原理揭秘:Border 的“魔法”
当一个元素的 width 和 height 都设置为 0 时,它的 border 属性就会呈现出奇特的几何形状:
.box {
width: 0;
height: 0;
border: 50px solid;
border-color: #96ceb4 #ffeead #d9534f #ffad60; /* 上右下左 */
}
如图所示,四条边框会形成四个三角形。要画出我们想要的三角形,只需将不需要的边框颜色设置为透明 transparent 即可。
2. 绘制向下三角形步骤
- 清空宽高:将元素的
width和height设置为0。 - 方向选择:确定三角形方向,例如要向下,则保留
border-top的颜色,其他边设为透明。 - 控制大小:
border-width决定三角形的腰长,而border-color不透明的那条边的宽度就是三角形的高度。
.triangle-down {
width: 0;
height: 0;
border-left: 25px solid transparent; /* 左腰 */
border-right: 25px solid transparent; /* 右腰 */
border-top: 50px solid #d9534f; /* 底部,即三角形的“高” */
}
二、 纯 CSS 绘制扇形
绘制扇形的方法相对复杂,这里介绍两种常见思路。
核心知识点:
1. 思路一:基于三角形 + border-radius
如果你需要一个圆心角很小的扇形,可以在三角形的基础上,利用 border-radius 实现圆角效果。
-
border-radius :用于设置圆形的边角,设置的值为边角半径
- 四个值分别为左上、右上、右下、左下(顺时针)
- 三个值分别为左上、右上左下、右下(第二个值为第二个对角)
- 两个值为左上右下、右上左下(两个对角)
- 一个值为四周
-
clip:用于裁剪绝对定位的元素(元素属性必须为absolute、fixed)
- clip的rect:接受四个值分别为top、right、bottom、left
- top、right、bottom、left都是基于左上角来计算的
.sector-small {
width: 0;
height: 0;
border-top: 50px solid blue;
border-left: 10px solid transparent;
border-right: 10px solid transparent;
border-radius: 50px; /* 半径等于三角形的高 */
}
2. 思路二:利用半圆 + clip / transform (更通用)
这种方法可以绘制任意角度的扇形,尤其适用于进度条等场景。
-
画一个完整的圆:
border-radius: 50%。 -
创建两个半圆遮罩:使用伪元素
::before和::after或绝对定位的div。 -
核心技法:
clip: rect(top, right, bottom, left):用于裁剪绝对定位元素。它接受四个值,基于元素的左上角计算,用来裁剪出半圆。transform: rotate():旋转这些半圆,露出扇形区域。
<!DOCTYPE html>
<html>
<body>
<div class="container">
<div class="pie-chart">
<div class="left-half"></div>
<div class="right-half"></div>
</div>
</div>
<script></script>
</body>
<style>
html,
body {
height: 100vh;
margin: 0;
padding: 0;
}
.container {
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.pie-chart {
width: 200px;
height: 200px;
border-radius: 50%;
background-color: aqua; /* 背景色作为扇形颜色 */
position: relative;
overflow: hidden; /* 隐藏溢出部分 */
}
/* 左半圆遮罩,通常初始设为遮挡 */
.left-half {
width: 200px;
height: 200px;
position: absolute;
top: 0;
left: 0;
background-color: white; /* 遮罩色 */
clip: rect(0px, 100px, 200px, 0px); /* 裁剪出左半部分 */
transform-origin: center center; /* 旋转中心 */
transform: rotate(-20deg); /*动态旋转以露出扇形 */
}
/* 右半圆遮罩 */
.right-half {
width: 200px;
height: 200px;
position: absolute;
top: 0;
left: 0;
background-color: white; /* 遮罩色 */
clip: rect(0px, 200px, 200px, 100px); /* 裁剪出右半部分 */
transform-origin: center center;
transform: rotate(65deg); /* 动态旋转以露出扇形 */
}
</style>
</html>