你已经得到了很好的答案。
只是为了给你另一种获得这个结果的方式,你可以使用多个背景。这种方法的好消息是你只需要一个div标签即可实现。
.test {
margin: 25px 0;
width: 200px;
height: 200px;
border-radius: 50%;
border: 12px solid transparent;
background-size: 100% 100%, 50% 50%, 50% 50%, 50% 50%, 50% 50%;
background-repeat: no-repeat;
background-image: linear-gradient(white, white),
linear-gradient(30deg, red 36%, lightgrey 30%),
linear-gradient(120deg, yellow 36%, lightgrey 30%),
linear-gradient(300deg, blue 36%, lightgrey 30%),
linear-gradient(210deg, green 36%, lightgrey 30%);
background-position: center center, left top, right top, left bottom, right bottom;
background-origin: content-box, border-box, border-box, border-box, border-box;
background-clip: content-box, border-box, border-box, border-box, border-box;
transform: rotate(30deg);
}
<div class="test"></div>
这些区块可以使用倾斜线性渐变获得,限制在可用空间的四分之一内。我们需要4个这样的区块,改变位置和角度。
在这些区块上方,另一个完全设置为白色的渐变将隐藏中心。
并且将background-origin和clip更改为border-box或content-box,使颜色使用保留给边框的空间。
请注意,此解决方案适用于任何边框/边框半径组合。
使用 CSS:
通过 CSS 可以实现(正如 Quantastical 的回答和这里所示),但是,CSS 真的是完成此任务的正确工具吗?我认为不是。原因是使用 CSS 创建这样的形状/效果本身就非常困难,并且除此之外,它们还带有一些限制。例如,下面的代码片段仅在背景为纯色时才起作用。剪辑路径示例在 IE 中完全不受支持,在 FF 中仅与内联 SVG 一起使用。
如果您仍然希望使用 CSS 完成它,则以下是另一种选择。在这里,我们利用 4 个元素(真实或伪装)的 skew 转换,它们都是其父级大小的 50% x 50%。skew 转换会产生类似于扇形的外观,因此看起来更加逼真。分配给这些倾斜元素的背景颜色覆盖在另一个具有完整边框的元素上,并且看起来好像部分边框颜色不同。最后,我们在所有这些元素的顶部添加另一个白色背景的 div 来遮盖圆形的内部区域(仅可见边框)。
.circle {
position: relative;
height: 100px;
width: 100px;
}
.circle, .dummy-border, .border, .dummy-background {
border-radius: 50%;
overflow: hidden;
}
.dummy-border, .border, .dummy-background {
position: absolute;
top: 0px;
left: 0px;
height: 100%;
width: 100%;
}
.border {
border: 4px solid #AAA;
border-radius: 50%;
z-index: -2;
}
.dummy-background {
padding: 4px;
background-color: white;
background-clip: content-box;
}
.circle:after, .circle:before, .dummy-border:before, .dummy-border:after {
position: absolute;
content: '';
height: 50%;
width: 50%;
z-index: -1;
}
.circle:before {
top: 0%;
left: 0%;
background: red;
transform-origin: right bottom;
transform: skewY(30deg) skewX(30deg);
}
.circle:after {
top: 0%;
left: 50%;
background: green;
transform-origin: left bottom;
transform: skewY(-30deg) skewX(-30deg);
}
.dummy-border:before {
top: 50%;
left: 0%;
background: orange;
transform-origin: right top;
transform: skewY(-210deg) skewX(-30deg);
}
.dummy-border:after {
top: 50%;
left: 50%;
background: blue;
transform-origin: left top;
transform: skewY(210deg) skewX(30deg);
}
*, *:after, *:before {
box-sizing: border-box;
}
<div class='circle'>
<div class='border'></div> <!-- gray border -->
<div class='dummy-border'></div> <!-- produces colors along with parent's pseudos -->
<div class='dummy-background'></div> <!-- overlays a white background to mask -->
</div>
使用 SVG:
出于上述原因,我建议您使用 SVG 完成此操作。 SVG 可以轻松创建这种形状和效果,代码易于理解,天生具有响应性。
我的 SVG 技能还不够好,很可能元素数量可以减少。下面的代码段仅是一个示例,用于说明可能实现的效果。
在这里,我们使用 5 个 circle
元素(一个用于灰色边框,其余每个颜色各用一个)。#gray
圆形具有完全灰色边框,而所有其他圆形仅具有部分边框(以所需颜色为准)。利用 stroke-dasharray
和 stroke-dashoffset
属性可生成部分边框。
stroke-dasharray
属性用于通过将描边(颜色)的长度和虚线(透明)的长度作为值来生成虚线边框。对于这种情况,虚线的长度应等于圆的周长(2 * PI * r),而对于描边的长度,我已经使用了值的 1/8 周长。
stroke-dashoffset
属性用于指定描边应该从哪里开始的偏移量。偏移量是从 0 度位置(由 (100%,50%) 表示的点)计算的。通过设置适当的偏移值,可以产生所需的效果。
svg {
height: 100px;
width: 100px;
}
circle {
stroke-width: 4px;
fill: transparent;
}
#gray{
stroke: #AAA;
}
#red{
stroke: red;
stroke-dasharray: 35.5, 284; /* length of arc, circumference of circle */
stroke-dashoffset: -159.75; /* offset of arc from start point (1/2 arc length + 1/4 circumference) */
}
#orange{
stroke: orange;
stroke-dasharray: 35.5, 284; /* length of arc, circumference of circle */
stroke-dashoffset: -88.75; /* offset of arc from start point (1/2 arc length + 1/4 circumference) */
}
#blue{
stroke: blue;
stroke-dasharray: 35.5, 284; /* length of arc, circumference of circle */
stroke-dashoffset: -17.75; /* offset of arc from start point (1/2 of arc length) */
}
#green{
stroke: green;
stroke-dasharray: 35.5, 284; /* length of arc, circumference of circle */
stroke-dashoffset: -230.75; /* offset of arc from start point (1/2 arc length + 3/4 circumference) */
}
<svg viewBox='0 0 100 100'>
<circle cx='50' cy='50' r='45' id='gray'/>
<circle cx='50' cy='50' r='45' id='red'/>
<circle cx='50' cy='50' r='45' id='green'/>
<circle cx='50' cy='50' r='45' id='blue'/>
<circle cx='50' cy='50' r='45' id='orange'/>
</svg>
#circle, #circle .segment {
border-color: lightgray;
border-radius: 50%;
border-style: solid;
border-width: 5px;
box-sizing: border-box;
height: 100px;
position: relative;
width: 100px;
}
#circle .segment {
-webkit-clip-path: inset(0 40px 50px 40px);
/*content: ''; EDIT: not needed */
left: -5px;
position: absolute;
top: -5px;
}
#circle .segment:nth-child(1) {border-color: red; transform: rotate(-20deg);}
#circle .segment:nth-child(2) {border-color: blue; transform: rotate(70deg);}
#circle .segment:nth-child(3) {border-color: green; transform: rotate(160deg);}
#circle .segment:nth-child(4) {border-color: yellow; transform: rotate(250deg);}
<div id="circle">
<div class="segment"></div>
<div class="segment"></div>
<div class="segment"></div>
<div class="segment"></div>
</div>
segment
类应用于伪元素时,您使用 content
属性是否有任何原因? - m4n0:before
和:after
来实现的,这就是为什么有content
属性的原因。但后来我改成了嵌套的div,却忘记把它删除了。其实它是不需要的。 - jeffjenx该解决方案使用conic-gradient绘制颜色停止点,并使用具有线性渐变的mask-image来移除内部圆形。
.target {
width: 60vmin;
height: 60vmin;
background: conic-gradient(
lightgrey 0deg 30deg,
red 30deg 60deg,
lightgrey 60deg 120deg,
yellow 12deg 150deg,
lightgrey 150deg 210deg,
green 210deg 240deg,
lightgrey 240deg 300deg,
blue 300deg 330deg,
lightgrey 330deg 360deg
);
-webkit-mask-image: radial-gradient(transparent 65%, black 65%);
mask-image: radial-gradient(transparent 65%, black 65%);
border-radius: 50%;
}
body {
display: flex;
align-items: center;
justify-content: center;
margin: 0;
height: 100vh;
}
<div class="target"></div>