Css progress bar with circles

Building a Progress Ring, Quickly

On some particularly heavy sites, the user needs to see a visual cue temporarily to indicate that resources and assets are still loading before they taking in a finished site. There are different kinds of approaches to solving for this kind of UX, from spinners to skeleton screens. If we are using an out-of-the-box solution that provides us the current progress, like preloader package by Jam3 does, building a loading indicator becomes easier. For this, we will make a ring/circle, style it, animate given a progress, and then wrap it in a component for development use.

Step 1: Let’s make an SVG ring

From the many ways available to draw a circle using just HTML and CSS, I’m choosing SVG since it’s possible to configure and style through attributes while preserving its resolution in all screens.

Inside an element we place a tag, where we declare the radius of the ring with the r attribute, its position from the center in the SVG viewBox with cx and cy and the width of the circle stroke. You might have noticed the radius is 58 and not 60 which would seem correct. We need to subtract the stroke or the circle will overflow the SVG wrapper.

radius = (width / 2) - (strokeWidth * 2)

These means that if we increase the stroke to 4, then the radius should be 52.

Читайте также:  Xgboost classifier python примеры

To complete the ring we need to set fill to transparent and choose a stroke color for the circle. See the Pen SVG ring by Jeremias Menichelli (@jeremenichelli) on CodePen.

The next step is to animate the length of the outer line of our ring to simulate visual progress. We are going to use two CSS properties that you might not have heard of before since they are exclusive to SVG elements, stroke-dasharray and stroke-dashoffset .

This property is like border-style: dashed but it lets you define the width of the dashes and the gap between them.

With those values, our ring will have 10px dashes separated by 20px. See the Pen Dashed SVG ring by Jeremias Menichelli (@jeremenichelli) on CodePen.

The second one allows you to move the starting point of this dash-gap sequence along the path of the SVG element. Now, imagine if we passed the circle’s circumference to both stroke-dasharray values. Our shape would have one long dash occupying the whole length and a gap of the same length which wouldn’t be visible. This will cause no change initially, but if we also set to the stroke-dashoffset the same length, then the long dash will move all the way and reveal the gap. Decreasing stroke-dasharray would start to reveal our shape. A few years ago, Jake Archibald explained this technique in this article, which also has a live example that will help you understand it better. You should go read his tutorial.

What we need now is that length which can be calculated with the radius and this simple trigonometric formula.

circumference = radius * 2 * PI
const circle = document.querySelector('.progress-ring__circle'); const radius = circle.r.baseVal.value; const circumference = radius * 2 * Math.PI;
circle.style.strokeDasharray = `$ $`; circle.style.strokeDashoffset = circumference;

Step 3: Progress to offset

With this little trick, we know that assigning the circumference value to stroke-dashoffset will reflect the status of zero progress and the 0 value will indicate progress is complete. Therefore, as the progress grows we need to reduce the offset like this:

function setProgress(percent) < const offset = circumference - percent / 100 * circumference; circle.style.strokeDashoffset = offset; >

One particular thing about stroke-dashoffset , its starting point is vertically centered and horizontally tilted to the right. It’s necessary to negatively rotate the circle to get the desired effect.

Putting all of this together will give us something like this. See the Pen vegymB by Jeremias Menichelli (@jeremenichelli) on CodePen. A numeric input was added in this example to help you test the animation. For this to be easily coupled inside your application it would be best to encapsulate the solution in a component.

Now that we have the logic, the styles, and the HTML for our loading ring we can port it easily to any technology or framework. First, let’s use web components.

class ProgressRing extends HTMLElement window.customElements.define('progress-ring', ProgressRing);

This is the standard declaration of a custom element, extending the native HTMLElement class, which can be configured by attributes.

Inside the constructor of the element, we will create a shadow root to encapsulate the styles and its template.

constructor() < super(); // get config from attributes const stroke = this.getAttribute('stroke'); const radius = this.getAttribute('radius'); const normalizedRadius = radius - stroke * 2; this._circumference = normalizedRadius * 2 * Math.PI; // create shadow dom root this._root = this.attachShadow(); this._root.innerHTML = `  $" style="stroke-dashoffset:$" stroke-width="$" fill="transparent" r="$" cx="$" cy="$" /> circle `; >

You may have noticed that we have not hardcoded the values into our SVG, instead we are getting them from the attributes passed to the element. Also, we are calculating the circumference of the ring and setting stroke-dasharray and stroke-dashoffset ahead of time. The next thing is to observe the progress attribute and modify the circle styles.

setProgress(percent) < const offset = this._circumference - (percent / 100 * this._circumference); const circle = this._root.querySelector('circle'); circle.style.strokeDashoffset = offset; >static get observedAttributes() < return [ 'progress' ]; >attributeChangedCallback(name, oldValue, newValue) < if (name === 'progress') < this.setProgress(newValue); >>

Here setProgress becomes a class method that will be called when the progress attribute is changed. The observedAttributes are defined by a static getter which will trigger attributeChangeCallback when, in this case, progress is modified. See the Pen ProgressRing web component by Jeremias Menichelli (@jeremenichelli) on CodePen. This Pen only works in Chrome at the time of this writing. An interval was added to simulate the progress change.

Web components are great. That said, some of the available libraries and frameworks, like Vue.js, can do quite a bit of the heavy-lifting. To start, we need to define the view component.

const ProgressRing = Vue.component('progress-ring', <>);

Writing a single file component is also possible and probably cleaner but we are adopting the factory syntax to match the final code demo. We will define the attributes as props and the calculations as data.

const ProgressRing = Vue.component('progress-ring', < props: < radius: Number, progress: Number, stroke: Number >, data() < const normalizedRadius = this.radius - this.stroke * 2; const circumference = normalizedRadius * 2 * Math.PI; return < normalizedRadius, circumference >; > >);

Since computed properties are supported out-of-the-box in Vue we can use it to calculate the value of stroke-dashoffset .

Next, we add our SVG as a template. Notice that the easy part here is that Vue provides us with bindings, bringing JavaScript expressions inside attributes and styles.

template: ` " :stroke-width="stroke" :r="normalizedRadius" :cx="radius" :cy="radius" /> `

When we update the progress prop of the element in our app, Vue takes care of computing the changes and update the element styles. See the Pen Vue ProgressRing component by Jeremias Menichelli (@jeremenichelli) on CodePen. Note: An interval was added to simulate the progress change. We do that in the next example as well.

In a similar way to Vue.js, React helps us handle all the configuration and computed values thanks to props and JSX notation. First, we obtain some data from props passed down.

class ProgressRing extends React.Component < constructor(props) < super(props); const < radius, stroke >= this.props; this.normalizedRadius = radius - stroke * 2; this.circumference = this.normalizedRadius * 2 * Math.PI; > >

Our template is the return value of the component’s render function where we use the progress prop to calculate the stroke-dashoffset value.

render() < const < radius, stroke, progress >= this.props; const strokeDashoffset = this.circumference - progress / 100 * this.circumference; return (  strokeDasharray= < this.circumference + ' ' + this.circumference >style= < < strokeDashoffset >> stroke-width= < stroke >r= < this.normalizedRadius >cx= < radius >cy= < radius >/> ); >

A change in the progress prop will trigger a new render cycle recalculating the strokeDashoffset variable. See the Pen React ProgressRing component by Jeremias Menichelli (@jeremenichelli) on CodePen.

The recipe for this solution is based on SVG shapes and styles, CSS transitions and a little of JavaScript to compute special attributes to simulate the drawing circumference. Once we separate this little piece, we can port it to any modern library or framework and include it in our app, in this article we explored web components, Vue, and React.

Источник

Circular Progress Bar using HTML and CSS

Circular Progress Bar is a popular web element that is mainly used on business or personal websites. If you want to create a circular progress bar using HTML and CSS, then this article will help you. Here I am going to show you how to make a simple CSS circle progress bar. When you load the page, this animation will go from zero to your assigned meaning. A percentage of text is used here, but no animation is used in this text. It is made in a very simple way. ✅ Watch Live Preview 👉👉 Circular Progress Bar In this article, I will show you step by step how I made this circular progress bar design.To make it, you need to have an idea about basic HTML and CSS.

Step 1: The basic structure of Circular Progress Bar

I have used HTML and CSS to create the basic structure of the Circular Progress Bar. I have created a small circle on the webpage. The width and height of this circle are 150 px. The background color of the circle is white and margins are used to place it in the middle.

 class="circle-wrap">  class="circle">   
body  font-family: "Roboto", sans-serif; background:#d2eaf1; > .circle-wrap  margin: 150px auto; width: 150px; height: 150px; background: #fefcff; border-radius: 50%; border: 1px solid #cdcbd0; > 

The basic structure of Circular Progress Bar

Step 2: Half of the simple CSS circle progress bar

As I said before, the animation in this circle is divided into two parts. This means that the animation has been divided into two parts up to the customer value. I have made the first part of those two parts. Width and height 150 have been used to make this animation equal in size to the Circular Progress Bar. Similarly, border-radius 50% has been used to make it round. Here I have set the background-color to blue. If you want to play an animation in another color, you can use that color here.

 class="mask half">  class="fill">
.circle-wrap .circle .mask, .circle-wrap .circle .fill  width: 150px; height: 150px; position: absolute; border-radius: 50%; > .mask .fill  clip: rect(0px, 75px, 150px, 0px); background-color: #227ded; > 

Half of the simple CSS circle progress bar

Step 3: The other half of the Circular Progress Bar

Now I have designed the other half of the Circular Progress Bar. I set the time to three seconds by adding animation here. This means that when this page is opened, the animation will take 3 seconds to reach the meaning you set from zero. Here 135 degrees have been used using transform. This transform will determine where the animation will end in this circle. ➤ We know that a circle is formed by 360. Since here we have divided the CSS circle progress bar into two parts, so each part is 180 degrees. ➤ Here we have set a 135-degree animation for each part using Transform. So it will be 270 degrees for the total circle. Here I want to increase the animation to 75% so I have used 270 degrees.

You determine the value of this degree according to your needs. For example, if you want the animation of the Circular Progress Bar will be up to 80%. But for that, you have to use 144 degrees here . Lastly, I have implemented this animation using @keyframes.

 class="mask full">  class="fill">
.circle-wrap .circle .mask  clip: rect(0px, 150px, 150px, 75px); > .mask.full, .circle .fill  animation: fill ease-in-out 3s; transform: rotate(135deg); > @keyframes fill 0%  transform: rotate(0deg); > 100%  transform: rotate(135deg); > > 

The other half of the Circular Progress Bar

Step 4: Create a percentage in the Circular Progress Bar

Now I have added percentages in this circular progress bar. Although that percentage of animation is not added. Added text using basic HTML and CSS code. I have used text-align: center and position: absolute to place the text in the middle of the Circular Progress Bar. I used border-radius: 50% to make its background width and height 122 px and round. Here I have used font-size: 2em to make the size of the text smaller and larger.

.circle-wrap .inside-circle  width: 122px; height: 122px; border-radius: 50%; background: #d2eaf1; line-height: 120px; text-align: center; margin-top: 14px; margin-left: 14px; color: #1e51dc; position: absolute; z-index: 100; font-weight: 700; font-size: 2em; > 

Circular Progress Bar using HTML and CSS

Related Post:

  1. Responsive Footer HTML CSS
  2. Todo List using JavaScript
  3. Simple Stopwatch using JavaScript
  4. Javascript Age Calculator
  5. javaScript Password Generator
  6. Automatic Image Slider in Html CSS
  7. Sidebar Menu Using HTML CSS

As you can see in the picture above, now this CSS Circular Progress Bar is absolutely ready. Hope you find out from this article how I created this Circular Progress Bar using HTML and CSS.

Источник

Оцените статью