方案一:通过旋转三个长方形生成正六边形
分析:
如下图所示,我们可以通过旋转三个长方形来得到一个正六边形。

疑问:
1. 长方形的宽高分别是多少?

设正六边形的边长是100,基于一些数学常识,可以得出上图得一些数据。
我们现在开始求ac的长度:由于:sin30° = 1/2,则ac/ad = 1/2。因ad=100,所以ac=50;
再根据勾股定理求cd长度:ad²-ac² = 100² - 50² = cd²。故cd约等于86.60
**所以长方形的宽是100,高则是86.6 * 2 =173.2 **
2.需要将长方形旋转多少度?
由于css的transform的rotate是以中心点进行旋转的,所以我们要求的是∠abc,就知道需要将长方形旋转多少度了
1.由于ab是垂直ad的,所以∠bad是90°。
2.由于正六边形的内角是120%,bd是平分∠adc,所以∠adb是60°。
3.由于▲abd是直角三角形,所以∠abd = 180° - ∠bad - ∠adc = 30°。
4.由于▲abd和▲bcd完全相等,所以∠abc = 2 * ∠abd = 60°。
所以我们需要将长方形旋转60°
完整实现代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.app {
position: relative;
width: 100px;
height: 173.2px;
margin: 0 auto;
}
.item {
position: absolute;
top: 0;
left: 0;
width: 100px;
height: 173.2px;
border-top: 1px solid black;
border-bottom: 1px solid black;
}
.item_1 {
transform: rotate(60deg);
}
.item_3 {
transform: rotate(-60deg);
}
</style>
</head>
<body>
<div class="app">
<div class="item_1 item"></div>
<div class="item_2 item"></div>
<div class="item_3 item"></div>
</div>
</body>
</html>
方案二:基于伪元素 + border生成三角形原理
前言:由下图观察可知,正六边形可以通过2个三角形 + 1个长方形拼装出来。故左右两个三角则使用伪元素生成。
我们还是设正六边形的边长是100,由方案一可知道,三角形的高是50,底边是173.2。
border生成三角形原理
当我们将盒子的宽高设置为0之后,再设置border,我们会发现他会生成一个矩形,并且是由四个三角形组合而成。
代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.box {
width: 0;
height: 0;
border: 100px solid;
border-color: aqua rebeccapurple red blue;
}
</style>
</head>
<body>
<div class="box"></div>
</body>
</html>
效果:
从上图观察得知:
- 右边的三角形的高,是由border的厚度决定的
- 右边三角形的底边长,是由上下两个三角形的厚度相加决定的
正六边形的实现:
正六边形中三角形的生成原理(以生成左侧的三角形为例)
- 我们将上、下、左边的border填充颜色设置为透明,右边的三角形设置为红色,这样我们就可以得到一个三角形了。
- 通过border生成的三角形的高,是通过border的厚度决定的,由方案一可知,三角形的高是50,所以我们设置右侧的border厚度为50。
- 由于【右边三角形的底边长,是由上下两个三角形的厚度相加决定的】,我们在方案一中可以知道,底边长是173.2,所以上下两个三角形的border设置为173.2 / 2 =86.6。
- 生成三角形之后,通过定位向左移动100,这样就生成了。
正六边形实现代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.div {
position: relative;
width: 100px;
height: 173.2px;
margin: 0 auto;
background-color: red;
}
.div::before {
position: absolute;
display: block;
content: '';
width: 0;
height: 0;
border: 50px solid transparent;
border-right-color: red;
border-top-width: 86.6px;
border-bottom-width: 86.6px;
right: 100px;
}
.div::after {
position: absolute;
display: block;
content: '';
width: 0;
height: 0;
border: 50px solid transparent;
border-left-color: red;
border-top-width: 86.6px;
border-bottom-width: 86.6px;
right: -100px;
}
</style>
</head>
<body>
<div class="div"></div>
</body>
</html>
方案四:使用clip-path生成
实现比较简洁,但对于一些低版本的浏览器会有兼容性问题,慎用。
polygon是生成多边形的方法,通过提供坐标来生成。
如:polygon(x1 y1, x2 y2, x3 y3)这样子
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.div {
width: 100px;
height: 100px;
clip-path: polygon(25% 0, 75% 0, 100% 50%, 75% 100%, 25% 100%, 0 50%);
background-color: red;
}
</style>
</head>
<body>
<div class="div">
</div>
</body>
</html>