前言
最近看了一些利用CSS样式实现的几何图形,如五角星,梯形,爱心等,研究后发现,如果是由线条组成的几何图形,可以使用border属性实现,但是如果是爱心等曲线,就需要使用到radius属性,使其出现弧度。
(一)五角星
由于五角星并不是简单的四个边的边框折叠,所以另外考虑一种方法----通过组合多个图形,最终使得几个图形的大小匹配,从而实现五角星的视觉效果。
- 首先创建五角星的顶部三角
.star {
width: 0px;
height: 0px;
border-bottom: 9.5px solid yellow;
border-left: 3.1px solid transparent;
border-right: 3.1px solid transparent;
}
- 使用一个div容器装下这个三角形
<body>
<div class="star">
</div>
</body>
- 使用伪类after和bofore,分别设计出五角星的剩下的四个角,由于四个角是对称的,可以使用两个三角形重叠组合实现:
.star::before, .star::after {
content: "";
width: 0px;
height: 0px;
border-bottom: 9.5px solid yellow;
border-left: 13.1px solid transparent;
border-right: 13.1px solid transparent;
}
- 按照一定比例(参考他人代码),构建出两个三角形,而后与最开始的顶部三角形组合,请看图示:
- 两个三角形组合的理论可行,接着我们需要把三角形移动到对应位置,为了方便操作,我们为两个三角形都开启定位position,并设置为绝对定位。
.star::before {
position: absolute;
}
.star::after {
position: absolute;
}
- 刚刚在我们的理论阶段,两个下半部分的三角形是有一定程度上的旋转和位置变换的,在一次次的尝试后将两个三角形移动到对应位置即可,在此给出一个可行的数据:
.star::before {
transform: rotate(-36deg);
top: 8.6px;
left: -13.4px;
}
.star::after {
transform: rotate(36deg);
top: 8.6px;
left: -12.8px;
}
整体代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Star</title>
<style>
.star {
width: 0px;
height: 0px;
border-bottom: 9.5px solid yellow;
border-left: 3.1px solid transparent;
border-right: 3.1px solid transparent;
position: relative;
}
.star::before, .star::after {
content: "";
width: 0px;
height: 0px;
border-bottom: 9.5px solid yellow;
border-left: 13.1px solid transparent;
border-right: 13.1px solid transparent;
}
.star::before {
transform: rotate(-36deg);
position: absolute;
top: 8.6px;
left: -13.4px;
}
.star::after {
transform: rotate(36deg);
position: absolute;
top: 8.6px;
left: -12.8px;
}
</style>
</head>
<body>
<div class="star">
</div>
</body>
</html>
补充:
参考他人的数据,得出比例(全靠大佬数据):
/* 泛化:假设星型边长为 a,那么可以计算得到样式数据如下:
.star {
width: 0px;
height: 0px;
border-bottom: 【0.951a】px solid yellow;
border-left: 【0.309a】px solid transparent;
border-right: 【0.309a】px solid transparent;
position: relative;
}
.star::before, .star::after {
content: "";
width: 0px;
height: 0px;
border-bottom: 【0.951a】px solid yellow;
border-left: 【1.309a】px solid transparent;
border-right: 【1.309a】px solid transparent;
}
.star::before {
transform: rotate(-36deg);
position: absolute;
top: 【0.86a】px;
left: 【-1.33852a】px;
}
.star::after {
transform: rotate(36deg);
position: absolute;
top: 【0.86a】px;
left: 【-1.27948a】px;
}
说明:由于在计算过程中只保留有限小数,所以星型边长越大,误差越大 */
(二)爱心
爱心不同于五角星有棱有角的形状,可以通过border属性得到。爱心需要radius设置圆角的属性,实现爱心的两个半圆轮廓。
- 首先把爱心拆分,由两个类似于柱状的图形组成:
- 组合的过程请看图示:
右半部分是一样的,就不展示了。
- 理论成立,实践开始。
- 由于爱心由两个图示的柱状组成,但是如果使用两个div装的话,position设置会比较麻烦,所以照样使用伪类after与before实现两个柱子,并为两个柱子设置position使其便于移动位置。
<body>
<div class="love">
</div>
</body>
/*div设置定位是为了使div成为两个伪类的包含块,
这样在给两个伪类设置绝对定位后,参考的就是div了*/
.love {
position: relative;
}
.love::before, .love::after {
content: "";
width: 10px;
height: 15px;
/*设置弧度radius为宽度的一半,勾勒出爱心的两个半圆顶部*/
border-radius: 5px 5px 0 0;
background: red;
position: absolute;
}
- 设置完两个柱子后,分别使其旋转45度,出现爱心的大致结构
.love::before {
transform: rotate(-45deg);
top: 0;
}
.love::after {
transform: rotate(45deg);
top: 0;
}
- 在脑海中模拟一下,很明显,目前还是不行的,会出现如下效果:
- 这是由于之前两个伪类构成的柱子是重叠的,即使各自旋转45度后,底部也会超出对方的位置,因此对其进行微调,使得柱的底部与另外一个柱的直线边重叠。
.love::before {
transform: rotate(-45deg);
left: -1.76px;
top: 0;
}
.love::after {
transform: rotate(45deg);
left: 1.76px;
top: 0;
}
- 效果:
整体代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>LOVE</title>
<style>
.love {
position: relative;
}
.love::before, .love::after {
content: "";
width: 10px;
height: 15px;
border-radius: 5px 5px 0 0;
background: red;
position: absolute;
}
.love::before {
transform: rotate(-45deg);
left: -1.76px;
top: 0;
}
.love::after {
transform: rotate(45deg);
left: 1.76px;
top: 0;
}
</style>
</head>
<body>
<div class="love">
</div>
</body>
</html>
结语
感觉前端有个特别有意思的地方就是想要什么效果,自己就能做出来,一步步看大佬们的代码,可以学到很多特别有意思的布局效果,实际上手操作之后也发现了不少小问题,诸如position等。路漫漫其修远兮,加油!