css 半圆形分部图片
尽管HTML5 Canvas和SVG可能是用于构建图表的更优雅的解决方案,但是在本教程中,我们将学习如何仅使用普通CSS来构建自己的甜甜圈图。
要了解我们将要创建的内容,请看下面的嵌入式CodePen演示:
HTML标记
我们从一些非常基本的标记开始; 一个普通的无序列表,在每个列表项中都有一个span
元素:
<ul class="chart-skills">
<li>
<span>CSS</span>
</li>
<li>
<span>HTML</span>
</li>
<li>
<span>PHP</span>
</li>
<li>
<span>Python</span>
</li>
</ul>
将样式添加到列表
准备好标记后,首先我们将一些基本样式应用于无序列表:
.chart-skills {
position: relative;
width: 350px;
height: 175px;
}
然后,我们将为每个元素提供一个::after
和::before
伪元素,并对它们进行样式设置:
.chart-skills::before,
.chart-skills::after {
position: absolute;
}
.chart-skills::before {
content: '';
width: inherit;
height: inherit;
border: 45px solid rgba(211,211,211,.3);
border-bottom: none;
border-top-left-radius: 175px;
border-top-right-radius: 175px;
}
.chart-skills::after {
content: 'Top Skills';
left: 50%;
bottom: 10px;
transform: translateX(-50%);
font-size: 1.1rem;
font-weight: bold;
color: cadetblue;
}
注意::before
伪元素的样式。 这给了我们半圈。
到目前为止,上述规则为我们提供了以下结果:
将样式添加到列表项
现在让我们讨论列表项的样式。
定位
关于列表项的位置,我们执行以下操作:
- 将他们放在父母的正下方,
- 给他们适当的样式,以便创建一个反向的半圆。
此外,这里有几件事值得注意:
- 列表项是绝对定位的,因此我们可以设置其
z-index
属性。 - 我们修改列表项的默认
transform-origin
属性值(即transform-origin: 50% 50%
)。 具体来说,我们设置transform-origin: 50% 0
。 这样,当我们对项目进行动画处理(旋转)时,它们的中心上角将成为旋转中心。
以下是相关CSS样式:
.chart-skills li {
position: absolute;
top: 100%;
left: 0;
width: inherit;
height: inherit;
border: 45px solid;
border-top: none;
border-bottom-left-radius: 175px;
border-bottom-right-radius: 175px;
transform-origin: 50% 0;
}
.chart-skills li:nth-child(1) {
z-index: 4;
border-color: green;
}
.chart-skills li:nth-child(2) {
z-index: 3;
border-color: firebrick;
}
.chart-skills li:nth-child(3) {
z-index: 2;
border-color: steelblue;
}
.chart-skills li:nth-child(4) {
z-index: 1;
border-color: orange;
}
看看我们到目前为止在下一个可视化中构建的内容:
当前,唯一可见的列表项是绿色项(其z-index: 4;
),其他项在其下方。
动画制作
在介绍为列表项添加动画效果的步骤之前,让我们记下每个项目所需的百分比(即:每个甜甜圈将覆盖多少甜甜圈)。 请考虑下表:
语言 | 百分比 |
---|---|
CSS | 12 |
HTML | 32 |
PHP | 34 |
Python | 22 |
接下来,我们计算必须对每个项目进行动画(旋转)的度数。 为了找出每个项目的确切度数,我们将其百分比乘以180°(而不是360°,因为我们使用的是半圆甜甜圈图):
语言 | 百分比 | 学位数 |
---|---|---|
CSS | 12 | 12/100 * 180 = 21.6 |
HTML | 32 | 32/100 * 180 = 57.6 |
PHP | 34 | 34/100 * 180 = 61.2 |
Python | 22 | 22/100 * 180 = 39.6 |
至此,我们准备设置动画了。 首先,通过向.chart-skills li
添加一些规则,我们定义了所有项目之间共享的某些动画样式:
animation-fill-mode: forwards;
animation-duration: .4s;
animation-timing-function: linear;
然后,我们定义独特的动画样式:
.chart-skills li:nth-child(1) {
z-index: 4;
border-color: green;
animation-name: rotate-one;
}
.chart-skills li:nth-child(2) {
z-index: 3;
border-color: firebrick;
animation-name: rotate-two;
animation-delay: .4s;
}
.chart-skills li:nth-child(3) {
z-index: 2;
border-color: steelblue;
animation-name: rotate-three;
animation-delay: .8s;
}
.chart-skills li:nth-child(4) {
z-index: 1;
border-color: orange;
animation-name: rotate-four;
animation-delay: 1.2s;
}
请注意,除了第一个项目,我们对所有项目都添加了延迟。 通过这种方式,我们创建了不错的顺序动画。 例如,当第一个元素的动画结束时,出现第二个元素,依此类推。
下一步是指定实际的动画:
@keyframes rotate-one {
100% {
transform: rotate(21.6deg);
/**
* 12% => 21.6deg
*/
}
}
@keyframes rotate-two {
0% {
transform: rotate(21.6deg);
}
100% {
transform: rotate(79.2deg);
/**
* 32% => 57.6deg
* 57.6 + 21.6 => 79.2deg
*/
}
}
@keyframes rotate-three {
0% {
transform: rotate(79.2deg);
}
100% {
transform: rotate(140.4deg);
/**
* 34% => 61.2deg
* 61.2 + 79.2 => 140.4deg
*/
}
}
@keyframes rotate-four {
0% {
transform: rotate(140.4deg);
}
100% {
transform: rotate(180deg);
/**
* 22% => 39.6deg
* 140.4 + 39.6 => 180deg
*/
}
}
在继续之前,我们将简要介绍动画的工作原理:
第一个元素从transform: none
到transform: rotate(21.6deg)
。
第二个元素从transform: rotate(21.6deg)
(从第一个元素的最终位置开始)变为transform: rotate(79.2deg)
(57.6deg + 21.6deg)。
第三个元素从transform: rotate(79.2deg)
(从第二个元素的最终位置开始)到transform: rotate(140.4deg)
(61.2deg + 79.2deg)。
第四个元素从transform: rotate(140.4deg)
(从第三个元素的最终位置开始)到transform: rotate(180deg)
(140.4deg + 39.6deg)。
隐藏!
最后但并非最不重要的一点是,要隐藏图表的下半部分,我们必须添加以下规则:
.chart-skills {
/* existing rules....*/
overflow: hidden;
}
.chart-skills li {
/* existing rules....*/
transform-style: preserve-3d;
backface-visibility: hidden;
}
overflow: hidden
属性值确保仅第一个半圆(使用::before
伪元素创建的半圆)可见。 如果要测试列表项的初始位置,请随时删除该属性。
transform-style: preserve-3d
和backface-visibility: hidden
属性可防止由于动画而在不同浏览器中发生的闪烁效果。 如果您的浏览器中仍然存在此问题,则您可能还需要尝试这些解决方案 。
图表已准备就绪! 剩下的就是设置图表标签的样式,这将在下一部分中进行。
这是CodePen演示,显示了我们图表的当前外观:
在标签上添加样式
在本节中,我们将为图表标签设置样式。
定位
关于它们的位置,我们执行以下操作:
- 给他们
position: absolute
并使用top
和left
属性设置他们想要的位置。 - 使用负值旋转它们。 当然,这些不是随机值。 实际上,这些是从其父项的最后一帧中提取的。 例如,第二个列表项的最后一帧包含
transform: rotate(79.2deg)
,因此其相关标签将具有transform: rotate(-79.2deg)
。
以下是相应CSS样式:
.chart-skills span {
position: absolute;
font-size: .85rem;
}
.chart-skills li:nth-child(1) span {
top: 5px;
left: 10px;
transform: rotate(-21.6deg);
}
.chart-skills li:nth-child(2) span {
top: 20px;
left: 10px;
transform: rotate(-79.2deg);
}
.chart-skills li:nth-child(3) span {
top: 18px;
left: 10px;
transform: rotate(-140.4deg);
}
.chart-skills li:nth-child(4) span {
top: 10px;
left: 10px;
transform: rotate(-180deg);
}
动画制作
现在,我们已经定位了标签,是时候对它们进行动画处理了。 这里有两件事值得一提:
- 默认情况下,所有标签都是隐藏的,并且在为其父项设置动画时变得可见。
- 与父项类似,我们使用
animation-delay
属性创建连续动画。 另外,我们添加了backface-visibility: hidden
属性值,以确保没有动画引起的闪烁效果。
处理图表标签动画CSS规则如下所示:
.chart-skills span {
backface-visibility: hidden;
animation: fade-in .4s linear forwards;
}
.chart-skills li:nth-child(2) span {
animation-delay: .4s;
}
.chart-skills li:nth-child(3) span {
animation-delay: .8s;
}
.chart-skills li:nth-child(4) span {
animation-delay: 1.2s;
}
@keyframes fade-in {
0%,
90% {
opacity: 0;
}
100% {
opacity: 1;
}
}
这是最终的图表:
浏览器支持和问题
通常,该演示在所有浏览器中都能正常运行。 我只想讨论两个与border-radius
属性有关的小问题。
首先,如果我们要给商品赋予不同的颜色,则图表可能看起来像这样:
请注意,例如,第三项的上下角。 有两条红线来自第四项的边框颜色。 我们可以看到这些行,因为与第三项相比,第四项具有较深的边框颜色。 尽管这是一个小问题,但是最好为您自己的图表选择合适的颜色时要意识到这一点。
其次,在Safari中,图表如下所示:
看一下第二和第三项中出现的小差距。 如果您对此问题有任何了解,请在下面的评论中告诉我们!
结论
在本教程中,我们经历了使用纯CSS创建半圆甜甜圈图的过程。 再次,如引言中所述,可能存在更强大的解决方案(例如HTML5 Canvas和SVG)来创建此类内容。 但是,如果您想构建简单轻巧的东西并享受挑战,那么CSS是必经之路!
翻译自: https://webdesign.tutsplus.com/tutorials/how-to-build-a-css-only-semi-circle-donut-chart--cms-26997
css 半圆形分部图片