前言:
好久不刷掘金,今天上来图看到首页一篇关于圆角 Tab 绘制的文章在最后作者说他当年遇到过的一个面试题,用 CSS 手写一个太极图,如下:
思考以及实现:
仔细思考了一下,第一感觉是要实现这个阴阳太极感觉并不难,大致就是:
一个大盒子,里面两个小盒子,一黑一白左右两边站,然后分别在两个小盒子里面再各自弄一个不同颜色的圆形小盒子,定位向对方偏移放到指定位置去。
思路是酱紫没错啦,但是让我手写是不可能的,这辈子都不可能手写。打开 Vscode
火速实操一下。
1. 左右两分布局
<div class="taiji">
<div class="left"></div>
<div class="right"></div>
</div>
.taiji {
width: 300px;
height: 300px;
background-color: #fff;
margin-top: 24px;
border-radius: 50%;
overflow: hidden;
border: 1px solid #000;
}
.left {
height: 100%;
width: 50%;
float: left;
}
.right {
height: 100%;
width: 50%;
float: left;
background-color: #000;
}
2. 实现异色定位圆球
接下来就是分别在左右各自实现一个如下草稿所示的定位的异色圆球:
这里打算直接用伪类来实现,就不加 DOM 元素了:
.left {
/* 加上相对定位 */
position: relative;
height: 100%;
width: 50%;
float: left;
}
.right {
position: relative;
height: 100%;
width: 50%;
float: left;
background-color: #000;
}
/*
这里用 border + background-color 来实现黑套白和白套黑的效果,可以节省一个伪类
*/
.right::after {
position: absolute;
content: "";
top: 0;
left: -75px;
background-color: #fff;
width: 50px;
height: 50px;
border-radius: 50%;
border: 50px solid #000;
}
.left::after {
position: absolute;
content: "";
bottom: 0;
right: -75px;
background-color: #000;
width: 50px;
height: 50px;
border-radius: 50%;
border: 50px solid #fff;
}
但是一看实现后的效果有点难蹦了,恍然大悟,这也许就是这东西拿出来考的意义?
众所周知 CSS 中的元素是有层叠顺序的,这里明显 left Box 的小球被 right Box 盖住了
我们换个思路,为什么不直接把两个小球都直接用 right Box 伪类实现呢:
.right::before {
position: absolute;
content: "";
top: 0;
left: -75px;
background-color: #fff;
width: 50px;
height: 50px;
border-radius: 50%;
border: 50px solid #000;
}
.right::after {
position: absolute;
content: "";
bottom: 0;
left: -75px;
background-color: #000;
width: 50px;
height: 50px;
border-radius: 50%;
border: 50px solid #fff;
}
铛铛铛铛,完美实现了一个太极图
完整代码如下:
<div class="taiji">
<div class="left"></div>
<div class="right"></div>
</div>
.taiji {
width: 300px;
height: 300px;
background-color: #fff;
margin-top: 24px;
border-radius: 50%;
overflow: hidden;
border: 1px solid #000;
}
.left {
position: relative;
height: 100%;
width: 50%;
float: left;
}
.right {
position: relative;
height: 100%;
width: 50%;
float: left;
background-color: #000;
}
.right::before {
position: absolute;
content: "";
top: 0;
left: -75px;
background-color: #fff;
width: 50px;
height: 50px;
border-radius: 50%;
border: 50px solid #000;
}
.right::after {
position: absolute;
content: "";
bottom: 0;
left: -75px;
background-color: #000;
width: 50px;
height: 50px;
border-radius: 50%;
border: 50px solid #fff;
}
etc: 评论区说用渐变色实现,确实可以,不过径向渐变存在锯齿问题,用1px的过度解决的话又会有大小上的细微差别,还是不如用伪元素实现的丝滑: