Oto zoptymalizowana wersja conic-gradient()
rozwiązania, w której możesz łatwo kontrolować liczbę myślników i odstęp między nimi
.box {
--d:4deg; /* distance between dashes */
--n:30; /* number of dashes */
--c:#000; /* color of dashes */
width: 180px;
display:inline-block;
border-radius:50%;
border:2px solid transparent; /* control the thickness of border*/
background:
linear-gradient(#fff,#fff) padding-box padding-box,
repeating-conic-gradient(
var(--c) 0 calc(360deg/var(--n) - var(--d)),
transparent 0 calc(360deg/var(--n))
) border-box;
}
/* keep the element square */
.box:before {
content:"";
display:block;
padding-top:100%;
}
<div class="box"></div>
<div class="box" style="--n:20;border-width:5px;width:150px"></div>
<div class="box" style="--n:8;--d:20deg;border-width:5px;width:150px"></div>
<div class="box" style="--n:10;--d:15deg;border-width:3px;width:100px"></div>
<div class="box" style="--n:10;--d:20deg;border-width:3px;width:100px"></div>
Aby mieć pełną przejrzystość, którą rozważamy mask
.box {
--d:4deg; /* distance between dashes */
--n:30; /* number of dashes */
--c:#000; /* color of dashes */
--b:2px; /* control the thickness of border*/
width: 180px;
display:inline-block;
border-radius:50%;
background:
repeating-conic-gradient(
var(--c) 0 calc(360deg/var(--n) - var(--d)),
transparent 0 calc(360deg/var(--n)));
-webkit-mask:radial-gradient(farthest-side,transparent calc(100% - var(--b)),#fff calc(100% - var(--b) + 1px));
mask:radial-gradient(farthest-side,transparent calc(100% - var(--b)),#fff calc(100% - var(--b) + 1px));
}
/* keep the element square */
.box:before {
content:"";
display:block;
padding-top:100%;
}
body {
background:linear-gradient(to right,yellow,pink);
}
<div class="box"></div>
<div class="box" style="--n:20;--b:5px;width:150px;--c:blue"></div>
<div class="box" style="--n:8;--d:20deg;--b:10px;width:130px;--c:red"></div>
<div class="box" style="--n:18;--d:12deg;--b:8px;width:100px;--c:green"></div>
<div class="box" style="--n:10;--d:20deg;--b:3px;width:100px;--c:purple"></div>
Aby było zabawnie , możemy nawet rozważyć bardziej złożone zabarwienie kresek:
.box {
--d:4deg; /* distance between dashes */
--n:30; /* number of dashes */
--b:2px; /* control the thickness of border*/
width: 180px;
display:inline-block;
border-radius:50%;
background:linear-gradient(red,blue);
-webkit-mask:
radial-gradient(farthest-side,transparent calc(100% - var(--b)),#fff calc(100% - var(--b) + 1px)),
repeating-conic-gradient(#000 0 calc(360deg/var(--n) - var(--d)),transparent 0 calc(360deg/var(--n)));
-webkit-mask-composite: source-in;
mask:
radial-gradient(farthest-side,transparent calc(100% - var(--b)),#fff calc(100% - var(--b) + 1px)),
repeating-conic-gradient(#000 0 calc(360deg/var(--n) - var(--d)),transparent 0 calc(360deg/var(--n)));
mask-composite: intersect;
}
/* keep the element square */
.box:before {
content:"";
display:block;
padding-top:100%;
}
body {
background:linear-gradient(to right,yellow,pink);
}
<div class="box"></div>
<div class="box" style="--n:20;--b:5px;width:150px;background:conic-gradient(green,orange,black)"></div>
<div class="box" style="--n:8;--d:20deg;--b:10px;width:130px;background:conic-gradient(black,white,black)"></div>
<div class="box" style="--n:18;--d:12deg;--b:8px;width:100px;background:linear-gradient(60deg,red 50%,green 0)"></div>
<div class="box" style="--n:10;--d:20deg;--b:3px;width:100px;background:#fff"></div>
Na pewno możesz chcieć mieć trochę zawartości, więc lepiej zastosuj maskę / tło do pseudoelementu, aby uniknąć maskowania zawartości:
.box {
--d:4deg; /* distance between dashes */
--n:30; /* number of dashes */
--b:2px; /* control the thickness of border*/
width: 180px;
display:inline-flex;
justify-content:center;
align-items:center;
font-size:35px;
border-radius:50%;
position:relative;
}
.box::after {
content:"";
position:absolute;
top:0;
left:0;
right:0;
bottom:0;
z-index:-1;
border-radius:inherit;
background:var(--c,linear-gradient(red,blue));
-webkit-mask:
radial-gradient(farthest-side,transparent calc(100% - var(--b)),#fff calc(100% - var(--b) + 1px)),
repeating-conic-gradient(#000 0 calc(360deg/var(--n) - var(--d)),transparent 0 calc(360deg/var(--n)));
-webkit-mask-composite: source-in;
mask:
radial-gradient(farthest-side,transparent calc(100% - var(--b)),#fff calc(100% - var(--b) + 1px)),
repeating-conic-gradient(#000 0 calc(360deg/var(--n) - var(--d)),transparent 0 calc(360deg/var(--n)));
mask-composite: intersect;
}
/* keep the element square */
.box:before {
content:"";
padding-top:100%;
}
body {
background:linear-gradient(to right,yellow,pink);
}
<div class="box">19</div>
<div class="box" style="--n:20;--b:5px;width:150px;--c:conic-gradient(green,orange,black)">17</div>
<div class="box" style="--n:8;--d:20deg;--b:10px;width:130px;--c:conic-gradient(black,white,black)">5</div>
<div class="box" style="--n:18;--d:12deg;--b:8px;width:100px;--c:linear-gradient(60deg,red 50%,green 0)">9</div>
<div class="box" style="--n:10;--d:20deg;--b:3px;width:100px;--c:#fff">13</div>
Podobne pytanie, aby uzyskać więcej pomysłów CSS, aby osiągnąć podobny wynik: Tylko wykres kołowy CSS - Jak dodać odstępy / wypełnienia między plasterkami? . Znajdziesz więcej obsługiwanych sposobów niż conic-gradient()
(w rzeczywistości nie działa w przeglądarce Firefox), ale musisz użyć dużo kodu, w przeciwieństwie do powyższego rozwiązania, w którym potrzebny jest tylko jeden element.
Korzystając z SVG, będziesz potrzebować również obliczeń, aby upewnić się, że masz jednolite odstępy:
svg {
width:200px;
}
<svg viewBox="-3 -3 106 106">
<!--
The circumference of the circle is 2*PI*R ~ 314.16
if we want N dashed we use d=314.16/N
For N = 20 we have d=15.71
For a gap of 5 we will have "10.71,5" (d - gap,gap)
-->
<circle cx="50" cy="50" r="50"
stroke-dasharray="10.71, 5"
fill="transparent"
stroke="black"
stroke-width="5" />
</svg>
Dzięki zmiennym CSS możemy to ułatwić, ale nie jest obsługiwane we wszystkich przeglądarkach (w rzeczywistości nie działa w przeglądarce Firefox)
svg {
--n:20; /* number of dashes*/
--d:5; /* distance */
width:200px;
}
svg circle {
stroke-dasharray:calc((2*3.14*50)/var(--n) - var(--d)), var(--d);
}
<svg viewBox="-3 -3 106 106">
<circle cx="50" cy="50" r="50" fill="transparent" stroke="black" stroke-width="5" />
</svg>
<svg viewBox="-3 -3 106 106" style="width:150px;--n:20;--d:10">
<circle cx="50" cy="50" r="50" fill="transparent" stroke="red" stroke-width="5" />
</svg>
<svg viewBox="-3 -3 106 106" style="width:100px;--n:8;--d:15">
<circle cx="50" cy="50" r="50" fill="transparent" stroke="green" stroke-width="5" />
</svg>
Możemy również łatwo użyć SVG jako tła, aby uczynić rzeczy bardziej elastycznymi:
.box {
display:inline-block;
width:200px;
background:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="-3 -3 106 106"><circle cx="50" cy="50" r="50" fill="transparent" stroke="black" stroke-width="5" style="stroke-dasharray:29.25, 10" /></svg>') center/contain;
}
.box:before {
content:"";
display:block;
padding-top:100%;
}
<div class="box">
</div>
<div class="box" style="width:150px;">
</div>
<div class="box" style="width:100px;">
</div>
W przypadku użycia jako tła należy ręcznie ustawić wartość, aby za każdym razem było potrzebne inne tło. Możemy jedynie ułatwić zmianę koloru za pomocą SVG jako maski;
.box {
display:inline-block;
width:200px;
position:relative;
}
.box:before {
content:"";
display:block;
padding-top:100%;
}
.box::after {
content:"";
position:absolute;
top:0;
left:0;
right:0;
bottom:0;
z-index:-1;
background:var(--c,red);
-webkit-mask:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="-3 -3 106 106"><circle cx="50" cy="50" r="50" fill="transparent" stroke="black" stroke-width="5" style="stroke-dasharray:29.25, 10" /></svg>') center/contain;
mask:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="-3 -3 106 106"><circle cx="50" cy="50" r="50" fill="transparent" stroke="black" stroke-width="5" style="stroke-dasharray:29.25, 10" /></svg>') center/contain;
}
<div class="box">
</div>
<div class="box" style="width:150px;--c:linear-gradient(60deg,green 50%,yellow 0);">
</div>
<div class="box" style="width:100px;--c:linear-gradient(red,blue)">
</div>