惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Cloudbric
Cloudbric
T
Threat Research - Cisco Blogs
Simon Willison's Weblog
Simon Willison's Weblog
AWS News Blog
AWS News Blog
P
Privacy & Cybersecurity Law Blog
H
Help Net Security
云风的 BLOG
云风的 BLOG
G
GRAHAM CLULEY
Spread Privacy
Spread Privacy
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
A
Arctic Wolf
Project Zero
Project Zero
Engineering at Meta
Engineering at Meta
P
Privacy International News Feed
Blog — PlanetScale
Blog — PlanetScale
Stack Overflow Blog
Stack Overflow Blog
M
MIT News - Artificial intelligence
The Register - Security
The Register - Security
Recorded Future
Recorded Future
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
C
Cisco Blogs
PCI Perspectives
PCI Perspectives
Recent Announcements
Recent Announcements
Martin Fowler
Martin Fowler
A
About on SuperTechFans
W
WeLiveSecurity
GbyAI
GbyAI
V
Vulnerabilities – Threatpost
The GitHub Blog
The GitHub Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
C
Check Point Blog
Y
Y Combinator Blog
月光博客
月光博客
Scott Helme
Scott Helme
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Google DeepMind News
Google DeepMind News
F
Fortinet All Blogs
U
Unit 42
G
Google Developers Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
T
Threatpost
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Google Online Security Blog
Google Online Security Blog
Recent Commits to openclaw:main
Recent Commits to openclaw:main
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Cisco Talos Blog
Cisco Talos Blog
博客园 - 三生石上(FineUI控件)
Hugging Face - Blog
Hugging Face - Blog
MongoDB | Blog
MongoDB | Blog
博客园 - 司徒正美

CSS Articles by Temani Afif

Get Ready For the Powerful CSS border-shape Property! | CSS-Tricks Let’s Play With Gap Decorations! How to Control Infinite CSS Animations (Part 2 of 2) How to Control Infinite CSS Animations (Part 1 of 2) Two Circles, One Arrow, and Anchor Positioning Making a Responsive Pyramidal Grid With Modern CSS | CSS-Tricks How to Create a CSS-only Elastic Text Effect Making Complex CSS Shapes Using shape() | CSS-Tricks Responsive Hexagon Grid Using Modern CSS | CSS-Tricks Responsive List of Avatars Using Modern CSS (Part 2) | CSS-Tricks Responsive List of Avatars Using Modern CSS (Part 1) | CSS-Tricks Perfectly Pointed Tooltips: To The Corners Perfectly Pointed Tooltips: All Four Sides Perfectly Pointed Tooltips: A Foundation Sequential linear() Animation With N Elements | CSS-Tricks Infinite Marquee Animation using Modern CSS Better CSS Shapes Using shape() — Part 4: Close and Move | CSS-Tricks Drawing CSS Shapes using corner-shape Better CSS Shapes Using shape() — Part 3: Curves | CSS-Tricks Better CSS Shapes Using shape() — Part 2: More on Arcs | CSS-Tricks Better CSS Shapes Using shape() — Part 1: Lines and Arcs | CSS-Tricks Creating Blob Shapes using clip-path: shape() Creating Flower Shapes using clip-path: shape() Custom progress element using the attr() function A CSS-Only Star Rating Component and More! (Part 2) | CSS-Tricks A CSS-Only Star Rating Component and More! (Part 1) | CSS-Tricks How to Create Wavy Boxes Using CSS Full-Bleed Layout with Modern CSS Fancy Menu Navigation Using Anchor Positioning | CSS-Tricks How to Create a Zig-Zag Box Using CSS How to Create Zig-Zag CSS Loaders Using One Element Custom Progress Element Using Anchor Positioning & Scroll-Driven Animations How to Create Filling CSS Loaders Using One Element How to Create Curved-Edge and Rounded-Edge Shapes Using CSS CSS Tricks That Use Only One Gradient | CSS-Tricks How to create Shapes with Inner Curves using CSS Mask Custom Range Slider Using Anchor Positioning & Scroll-Driven Animations How to Get the Width/Height of Any Element in Only CSS How Keyboard Navigation Works in a CSS Game How To Create Cut-Out Shapes using The clip-path property The Modern Guide For Making CSS Shapes — Smashing Magazine css-shape.com: The Ultimate Collection of CSS-only Shapes ⚡️ Sliding 3D Image Frames In CSS — Smashing Magazine CSS Tricks To Master The clip-path Property Creating Wavy Circles with Fancy Animations in CSS Modern CSS Tooltips And Speech Bubbles (Part 2) — Smashing Magazine Do you need a Tooltip or a Speech Bubble? I have created 100 using CSS 😲 Modern CSS Tooltips And Speech Bubbles (Part 1) — Smashing Magazine Creating Flower Shapes using CSS Mask & Trigonometric Functions CSS Shapes: The Triangle The Complex But Awesome CSS border-image Property — Smashing Magazine CSS Tricks to add 3D Effects to your Text CSS Responsive Multi-Line Ribbon Shapes (Part 2) — Smashing Magazine CSS Responsive Multi-Line Ribbon Shapes (Part 1) — Smashing Magazine I have made 100+ CSS-only Ribbon Shapes | The Perfect Collection 🎀 How to create a CSS-only infinite scroll animation Re-Creating The Pop-Out Hover Effect With Modern CSS (Part 2) — Smashing Magazine Re-Creating The Pop-Out Hover Effect With Modern CSS (Part 1) — Smashing Magazine How to Create CSS Ribbon Shapes with a Single Element CSS Shapes: The Ribbon Revealing Images With CSS Mask Animations — Smashing Magazine css-loaders.com: The Biggest Collection of Loading Animations (more than 500 🤯) How To Define An Array Of Colors With CSS — Smashing Magazine CSS effects on images II Shines, Perspective, And Rotations: Fancy CSS 3D Effects For Images — Smashing Magazine What's your Lucky CSS Pattern? Check It Now! How to Add a CSS Reveal Animation to Your Images Modern Layouts using CSS Grid I created 100+ unique CSS patterns | The best collection 🤩 How to Create a Custom Range Slider Using CSS CSS Shapes: The Heart CSS Shapes: Polygon & Starburst A Text Reveal Animation using CSS CSS Tip: learn CSS the easy way! How to build a CSS-only accordion How to create Breadcrumb Navigation with CSS Different Ways to Get CSS Gradient Shadows | CSS-Tricks A CSS-only responsive Stepper component A Fancy Hover Effect For Your Avatar | CSS-Tricks How to make a zoom effect using CSS Creating a Custom Cursor using CSS CSS Infinite 3D Sliders | CSS-Tricks CSS Infinite Slider Flipping Through Polaroid Images | CSS-Tricks How to create a responsive sidebar menu using CSS CSS Infinite and Circular Rotating Image Slider | CSS-Tricks Making Static Noise From a Weird CSS Gradient Bug | CSS-Tricks CSS Grid and Custom Shapes, Part 3 | CSS-Tricks Fancy Image Decorations: Outlines and Complex Animations | CSS-Tricks Fancy Image Decorations: Masks and Advanced Hover Effects | CSS-Tricks Fancy Image Decorations: Single Element Magic | CSS-Tricks How to create an infinite image slider using CSS How to Create Wavy Shapes & Patterns in CSS | CSS-Tricks How I Made a Pure CSS Puzzle Game | CSS-Tricks How to create a Tooltip/Speech Bubble using CSS CSS Grid and Custom Shapes, Part 2 | CSS-Tricks CSS Grid and Custom Shapes, Part 1 | CSS-Tricks Zooming Images in a Grid Layout | CSS-Tricks How to create a CSS-only loader with one element Exploring CSS Grid’s Implicit Grid and Auto-Placement Powers | CSS-Tricks How to create background pattern using CSS & conic-gradient
How to Create a Pie Chart Using Only CSS
Temani Afif · 2022-01-06 · via CSS Articles by Temani Afif

Pie charts are common components that let you show portions of a whole, and you can use them for many different purposes.

You will find a lot of articles around building such a component, but they typically either rely on SVG or a lot of HTML elements.

In this post, I will show you how to create a pie chart using CSS and only one element.

Below is an overview of what we are building:

Click to see the full code

20%

40%

60%

80%

90%

@property --p{
  syntax: 


As you can see in the CodePen above, we have a static pie chart, an animated one, and we can also have rounded edges. All this with a single <div> element.

In addition to that, we can easily adjust the different values using CSS variables so we don't have to bother ourselves with changing the CSS code.

I know the code may look a bit difficult at first glance, but after reading through the explanation below you will be able to confidently make your own pie charts.

The HTML Structure for the Pie Chart

As I mentioned above, we have a single <div> where we add the percentage value (the progress of the pie chart) as the main content:

<div class="pie" style="--p:60;--b:10px;--c:purple;">60%</div>

We also add the CSS variables as inline styles.

  • --p: This variable should contain the percentage value as a number (without the % sign). It be should the same as the content.

  • --b: This variable will define the thickness of the border.

  • --c: This variable will define the main color.

For the sake of this article and the demo, I am using a one-character variable to keep the code short. But it's better to consider more explicit variables when using the code in a production environment. Examples: --percentage, --border-thickness, and --main-color.

The CSS Setting for the Pie Chart

We first start by styling our content. This part is easy and the code is as follows:

.pie {
  --w: 150px;
  width: var(--w);
  aspect-ratio: 1;
  display: inline-grid;
  place-content: center;
  margin: 5px;
  font-size: 25px;
  font-weight: bold;
  font-family: sans-serif;
}

I am defining the element as inline-grid to easily place the content at the middle using place-content: center. We use aspect-ratio: 1 to make sure the element remains square. We can also use height: var(--w) but it's always good to learn and use a new CSS property.

You may wonder why I am using a variable to define the width instead of simply setting width: 150px. I need to know the value of the width for future usage so I am defining it as a variable.

All the remaining CSS is pretty basic to style the text. Feel free to update it as you want.

Let's move on to the interesting part – the main shape of our component. For this, we will use a pseudo element with the following styles:

.pie:before{
  content: "";
  position: absolute;
  border-radius: 50%;
  inset: 0;
  background: conic-gradient(var(--c) calc(var(--p)*1%),#0000 0);
}

A pseudo-element that has position: absolute covers all the area thanks to inset: 0. Yes, it's again a new CSS property which is the shorthand for top, right, bottom, and right (which you can read more about here).

Then we make it a circle ( border-radius: 50%) and we apply a conic-gradient(). Note the use of the CSS variables we defined as inline styles ( --c for the color and --p for the percentage).

Until now, this will give us the following result:

Conic-gradient applied to pseudo-element

Conic-gradient applied to pseudo-element

We are getting closer! The conic-gradient() is giving us a two-color gradient. From 0% to p% the main color and the remaining part is a transparent color (defined with the hexadecimal value #0000 ).

To keep only the border part we will use a mask to hide the middle part. We will use a radial-gradient() this time:

radial-gradient(farthest-side,red calc(99% - var(--b)),blue calc(100% - var(--b)))

The above applied as a background will give us the following:

Illustration of the radial-gradient

Illustration of the radial-gradient

Note the use of the variable --b that defines the thickness of the border (shown as blue in the above).

Now imagine the red part being the invisible part and the blue part the visible one. This is what we will get if we use the same gradient with the mask property:

Applying mask to the pseudo element

Applying mask to the pseudo element

We have our pie chart with one element and a few lines of CSS code.

.pie {
  --w:150px;

  width: var(--w);
  aspect-ratio: 1;
  position: relative;
  display: inline-grid;
  place-content: center;
  margin: 5px;
  font-size: 25px;
  font-weight: bold;
  font-family: sans-serif;
}
.pie:before {
  content: "";
  position: absolute;
  border-radius: 50%;
  inset: 0;
  background: conic-gradient(var(--c) calc(var(--p)*1%),#0000 0);
  -webkit-mask:radial-gradient(farthest-side,#0000 calc(99% - var(--b)),#000 calc(100% - var(--b)));
          mask:radial-gradient(farthest-side,#0000 calc(99% - var(--b)),#000 calc(100% - var(--b)));
}

And the HTML:

<div class="pie" style="--p:60;--b:10px;--c:purple;">60%</div>

How to add the the rounded edges

For this I will add an extra gradient layer to round the top edge and a pseudo element to round the other edge. Here is an illustration to understand the trick:

Illustration of the rounded edges

Illustration of the rounded edges

The code for (1) to round the top edge:

.pie:before {
  background:
    radial-gradient(farthest-side,var(--c) 98%,#0000) top/var(--b) var(--b) no-repeat,
    conic-gradient(var(--c) calc(var(--p)*1%),#0000 0);
}

In addition to the conic-gradient() we add a radial-gradient() placed at the top that has a size equal to the border thickness defined by --b.

The code for (2) to round the other edge:

.pie:after {
  content: "";
  position: absolute;
  border-radius: 50%;
  inset: calc(50% - var(--b)/2);
  background: var(--c);
  transform: rotate(calc(var(--p)*3.6deg)) translateY(calc(50% - var(--w)/2));
}

The inset property is setting the size of the pseudo-element to be equal to --b. Remember that it's the shorthand for top, right, bottom and left. If we have

left = right = 50% - b/2

this means that from each side we are moving to the center minus an offset equal to b/2 – so we end up having a width equal to 2*b/2 = b. Same logic for the height.

Now we need to correctly place our element, which is why we use the transform property. Our element is initially placed at the center so we need to first rotate it. Having the percentage we use the "Rule of three" to get the angle:

angle = percentage*360deg/100

Then we do a translation, and here we will need the width because we have to perform a translation by half the width (w/2).

Ok, ok – you might be a bit lost within all these formulas. Find below an illustration to understand the logic behind the transform property

Image

Applying the transform property to the pseudo-element

After that, we color the pseudo-element with the main color --c and we are done. We have our pie chart with rounded edges.

How to Animate the Pie Chart

A static pie chart is good but an animated one is better! To do this we will animate the percentage value --p from 0 to the defined value. By default, we cannot animate CSS variables, but thanks to the new @property feature it's now possible.

We register the variable:

@property --p{
  syntax: '<number>';
  inherits: true;
  initial-value: 0;
}

We create a keyframes:

@keyframes p {
  from {--p:0}
}

Note that we only need to specify the from. Doing this, the browser will make the to equal, by default, to the value we defined (<div class="pie" style="--p:60;">60%</div>).

And finally, we call the animation. You can define the duration/delay as you want.

animation: p 1s .5s both;

Unfortunately, this technique is not widely supported. You can test it on Chromium-based browsers (Chrome and Edge) but it will fail on Firefox and Safari. You can check out Can I Use to keep track of the support.

Before we end, here again is the full code and a demo of the final working product. You can see that I am using two classes to control the rounded edges and the animation so we can easily add/remove them as needed.

Click to see the full code

20%

40%

60%

80%

90%

@property --p{
  syntax: 

Learn to code for free. freeCodeCamp's open source curriculum has helped more than 40,000 people get jobs as developers. Get started