spb/svgarden Public
SVGarden — searchable bank of 74 self-contained SVG+CSS animation snippets (svgarden.dev)
HTML 79.2%
Astro 10.3%
JavaScript 6%
CSS 3.7%
Shell 0.8%
1<!--2 ============================================================3 SVGarden — https://www.svgarden.dev4 Author : Simon-Pierre Boucher5 Contact: contact@spboucher.ai6 File : snippets/charts/chart-donut-conic.html7 Desc : Donut chart from conic-gradient with @property sweep-open8 ============================================================9-->10<!--svgarden11title: Conic donut12slug: chart-donut-conic13category: charts14tags: [chart, donut, conic-gradient, property]15difficulty: advanced16techniques: ["@property", "conic-gradient()", "calc()", "css mask"]17how_it_works: >18 The whole donut is one conic-gradient: each segment is a pair of hard color19 stops, and every stop position is a fraction of a single angle variable —20 38% of the data is simply 0.38 × --sg-chart-donut-sweep. Registering that21 variable with @property and syntax '<angle>' is the key move: it tells the22 browser the value is a real angle, not an opaque string, so a keyframe from23 0deg to 360deg interpolates smoothly and every segment sweeps open in24 proportion at once. The hole is a radial-gradient mask punched through the25 middle, which keeps the center transparent on any page background. Browsers26 without @property skip the interpolation and simply show the finished donut.27support: >28 Sweep-open animation needs @property (Chrome 85+, Safari 16.4+, Firefox 128+)29 and segment tints use color-mix(); older browsers show the donut fully drawn.30customizable:31 - { var: "--sg-color", label: "Base color", type: color, default: "#7F77DD" }32 - { var: "--sg-size", label: "Size", type: range, min: 90, max: 240, default: 150, unit: px }33created: 2026-08-1034-->35<div class="sg-chart-donut-conic" style="--sg-color:#7F77DD; --sg-size:150px;">36 <div class="sg-chart-donut-conic-ring" role="img" aria-label="Donut chart of browser share: Chrome 38%, Safari 28%, Edge 20%, Firefox 14%"></div>37 <ul class="sg-chart-donut-conic-legend">38 <li>Chrome · 38%</li>39 <li>Safari · 28%</li>40 <li>Edge · 20%</li>41 <li>Firefox · 14%</li>42 </ul>43</div>44<style>45 @property --sg-chart-donut-sweep {46 syntax: '<angle>';47 inherits: false;48 initial-value: 360deg;49 }50 .sg-chart-donut-conic {51 display: flex;52 align-items: center;53 gap: 1.1em;54 font-family: inherit;55 }56 .sg-chart-donut-conic-ring {57 width: var(--sg-size);58 aspect-ratio: 1;59 border-radius: 50%;60 --sg-chart-donut-sweep: 360deg;61 background: conic-gradient(62 color-mix(in srgb, var(--sg-color) 100%, transparent) 0 calc(var(--sg-chart-donut-sweep) * 0.38),63 color-mix(in srgb, var(--sg-color) 65%, transparent) 0 calc(var(--sg-chart-donut-sweep) * 0.66),64 color-mix(in srgb, var(--sg-color) 40%, transparent) 0 calc(var(--sg-chart-donut-sweep) * 0.86),65 color-mix(in srgb, var(--sg-color) 22%, transparent) 0 var(--sg-chart-donut-sweep),66 transparent var(--sg-chart-donut-sweep) 360deg67 );68 -webkit-mask: radial-gradient(closest-side, transparent 61%, #000 62%);69 mask: radial-gradient(closest-side, transparent 61%, #000 62%);70 animation: sg-chart-donut-conic-open 1.1s cubic-bezier(0.25, 0.8, 0.3, 1);71 }72 @keyframes sg-chart-donut-conic-open {73 from { --sg-chart-donut-sweep: 0deg; }74 }75 .sg-chart-donut-conic-legend {76 list-style: none;77 margin: 0;78 padding: 0;79 font-size: 13px;80 display: grid;81 gap: 0.35em;82 }83 .sg-chart-donut-conic-legend li {84 display: flex;85 align-items: center;86 gap: 0.5em;87 }88 .sg-chart-donut-conic-legend li::before {89 content: '';90 width: 10px;91 height: 10px;92 border-radius: 3px;93 background: color-mix(in srgb, var(--sg-color) 100%, transparent);94 }95 .sg-chart-donut-conic-legend li:nth-child(2)::before { background: color-mix(in srgb, var(--sg-color) 65%, transparent); }96 .sg-chart-donut-conic-legend li:nth-child(3)::before { background: color-mix(in srgb, var(--sg-color) 40%, transparent); }97 .sg-chart-donut-conic-legend li:nth-child(4)::before { background: color-mix(in srgb, var(--sg-color) 22%, transparent); }98</style>99