SPB Git

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%
4.0 KB · 99 lines html
Raw Blame History
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