前言
直奔主题,下面就是我们要实现的效果:
抱歉各位,border-radius确实不能方形。但是我们是可以模仿这种效果的。
(标题为什么要加“震惊!惊呆了!”这些字?因为看到掘金上出现了一股现象:很多热点文章,标题总要加点乱七八糟的字眼。点进来一看,标题上突出的内容根本没讲明白。但是很引流啊。小的斗胆做一次标题党,请各位大佬见谅。-_-)
话说CSS中确实有很多奇形怪状需要画,看着还不太好实现。今天咱们就挑这一个来实现。
进入正题吧,本文就是想实现一个方形的border-radius效果。
咱们今天要用的就是clip-path属性。path就是路径。我们需要做的就是画出一条路径,来勾勒出我们需要实现的形状。
我们按照思考过程,写完整个实现过程。
1、实心三角形
先看效果:
图形总宽度 400px, 总高度 200px。
我们先给一个很常见的方案: 咦?这个很多同学都很熟悉:
来看代码吧:
.div {
height: 0;
width: 0;
border-top: 200px solid lightgreen;
border-bottom-width: 0;
border-left: 200px solid transparent;
border-right: 200px solid transparent;
}
然后我们看看用clip-path的方案: 我们只需要给出三个点的位置即可。
我们都知道,前端常用的坐标系,是一个Y轴朝下的坐标系。
左上角的点是(0,0),右下角的是(100%, 100%),当然,你也可以用px等任意长度单位。
第一个点是左上角,也就是 (0,0)
第二个点是底部这个点。x轴偏移50%, y轴偏移100%,就是(50%, 100%)
第三个点是右边这个点。x轴偏移100%, y轴偏移0,就是(100%, 0)
看代码:
.div {
height: 200px;
width: 400px;
background: lightgreen;
clip-path: polygon(0 0, 50% 100%, 100% 0);
}
其中有一个单词:polygon ,是多边形的意思。这里我们给出了多边形的三个顶点,浏览器渲染引擎帮我们渲染出了这三个点围成的一个形状,也就是三角形。
同理,我们如果给出n个点,我们可以实现实心的n边形。
2、实心圆
题外话,除了polygon以外,我们还可以实现圆形/椭圆形等,一下是一个圆形:
它的直径200px。
.div {
height: 400px;
width: 400px;
clip-path: circle(200px at 50% 50%);
background: green;
}
at前面这个数字,表示半径。 at后面的2个数字,表示圆心位置。
4、实心八边形
我们想实现方形的border-radius,实际上是要实现一个空心的八边形。
步子别跨的那么快,我们先把实心八边形搞定一下。
我们要实现下图的样子,首先分析一下每个点的坐标:
于是麻利的把8个点标注上去,代码如下:
.div {
height: 400px;
width: 400px;
clip-path: polygon(
20px 0, calc(100% - 20px) 0,
100% 20px, 100% calc(100% - 20px),
calc(100% - 20px) 100%, 20px 100%,
0 calc(100% - 20px), 0 20px
);
background: green;
}
4、实心八边形
我们想实现方形的border-radius,实际上是要实现一个空心的八边形。
步子别跨的那么快,我们先把实心八边形搞定一下。
我们要实现下图的样子,首先分析一下每个点的坐标:
于是麻利的把8个点标注上去,代码如下:
.div {
height: 400px;
width: 400px;
clip-path: polygon(
20px 0, calc(100% - 20px) 0,
100% 20px, 100% calc(100% - 20px),
calc(100% - 20px) 100%, 20px 100%,
0 calc(100% - 20px), 0 20px
);
background: green;
}
特别注意⚠️:我们只需要画八个点,最后一个点,不需要回到起点,会自动闭合。
5、空心的八边形
速度放慢一点,这个时候我们还不想立刻实现最终效果,我们先实现一个镂空的图形,之前踩了一个坑,下面是2份代码,做个比较:
正确代码:
.div {
height: 400px;
width: 400px;
clip-path: polygon(
20px 0, calc(100% - 20px) 0, 100% 20px, 100% calc(100% - 20px),
calc(100% - 20px) 100%, 20px 100%, 0 calc(100% - 20px), 0 20px,
20px 0, 50px 100px, 100px 50px);
background: green;
}
起点和终点自动闭合,效果如下:
错误代码:
这是错误示例: 内圈和外圈的方向一致,无法勾勒出空心图形。
.div {
height: 400px;
width: 400px;
clip-path: polygon(
20px 0, calc(100% - 20px) 0, 100% 20px, 100% calc(100% - 20px),
calc(100% - 20px) 100%, 20px 100%, 0 calc(100% - 20px), 0 20px,
20px 0, 50px 100px, 100px 50px);
background: green;
}
效果如下:
6、最终效果?不
这一步,我们将很接近想要实现的效果了。但还不是最终的。
我们这一步可以实现以下效果:
按照我们上一步的思路,内外方向如果相同,那么就会是实心的效果。所以,我们暂定:外圈是顺时针方向,内圈是逆时针方向:
内圈8个点,外圈8个点。 注意观察,我们中间的20px 0 使用2次了。
但是起点和终点,我们不能使用同一个点。
我们一共使用了17个点。
所以我们的代码是这样的:
.div {
height: 400px;
width: 400px;
clip-path: polygon(
20px 0,
calc(100% - 20px) 0,
100% 20px,
100% calc(100% - 20px),
calc(100% - 20px) 100%,
20px 100%,
0 calc(100% - 20px),
0 20px,
20px 0,
20px 4px,
4px 20px,
4px calc(100% - 20px),
20px calc(100% - 4px),
calc(100% - 20px) calc(100% - 4px),
calc(100% - 4px) calc(100% - 20px),
calc(100% - 4px) 20px,
calc(100% - 20px) 4px,20px 4px)
background: green;
}
细心的同学可能会发现,转折处的边框,是不是宽度变小了?
这到底是什么原因呢?
会不会是勾股定理?
哦,确实,实际转折处的宽度,是 4/1.414 = 2.8左右。
7、最终效果!
作为一个严谨的程序员,我们把这个小小的误差修复一下:
我们需要将外圈的20px,统统改为 20 - 4/1.414 = 18.8px左右。
.div {
height: 400px;
width: 400px;
clip-path: polygon(
18.8px 0,
calc(100% - 18.8px) 0,
100% 18.8px,
100% calc(100% - 18.8px),
calc(100% - 18.8px) 100%,
18.8px 100%,
0 calc(100% - 18.8px),
0 18.8px,
18.8px 0,
20px 4px,
4px 20px,
4px calc(100% - 20px),
20px calc(100% - 4px),
calc(100% - 20px) calc(100% - 4px),
calc(100% - 4px) calc(100% - 20px),
calc(100% - 4px) 20px,
calc(100% - 20px) 4px,
20px 4px
)
background: green;
}
最终效果:
转角处放大细节:
这次真的是等宽的边框了!!
后续
本来想写一个文章介绍所有CSS的奇形怪状,但是时间有限,挑了一个有意思的来实现。
这里实现的图形,是空心的,而且中间是透明的,不会遮挡底层内容。
我们可以写一个上述的div,position:absolute 定位作为背景使用,就相当于一个 方形的border-radius了。
最后:我这应该不算标题党吧。标题说的效果,我是百分百实现了啊。求各位大佬轻声批评!