Круговой индикатор загрузки css

Circle progress bar with pure CSS and HTML

Progress bars are widely used on websites to highlight specific data in a more appealing way for users. One benefit of using a circle progress bar over a regular (horizontal) progress bar is that you can fit more progress bars in one row, thus displaying more data to the user.

I’ve already covered how you can style a progress bar in my earlier article. But now we’re going to look at how you can create a circle progress bar.

Setup

To display a circle progress bar with CSS we want to use as few HTML elements as possible. A proper way to show a progress bar is to use a semantic HTML element called progress.

However, it has specific default styles which make its unique appearance, thus preventing us from using all available CSS properties and displaying it as a circle.

As an alternative, we can use a div element with a progressbar role.

So to create a circle progress bar with only CSS we will need to use a div element anyway. There are two options for the markup.

Option 1

The first option is to use a regular div with a progressbar role along with additional ARIA attributes such as aria-valuenow , aria-valuemin , and aria-valuemax to indicate the range of the progress bar. HTML looks as follows:

 class="progress-bar" role="progressbar" aria-valuenow="75" aria-valuemin="0" aria-valuemax="100">

Option 2

The second option is to wrap a progress element inside a div and hide it with CSS. That way we use a native progress element that will still be accessible in the DOM (just visually hidden) and the div will act as a visual representation. HTML looks as follows:

 class="progress-bar">  value="75" min="0" max="100" style="visibility:hidden;height:0;width:0;">75%  

Conic gradient

Since in both HTML approaches we will be styling a div element to create a circular progress bar, we’re going to use gradients. For the background property, we’ll set a radial-gradient function and a conic-gradient function that is available in CSS.

The conic-gradient will show the actual progress (the current value) and the radial-gradient will act as a mask on top of the conic-gradient .

.progress-bar  width: 100px; height: 100px; border-radius: 50%; background: radial-gradient(closest-side, white 79%, transparent 80% 100%), conic-gradient(hotpink 75%, pink 0); > 

To break it down. The conic-gradient function accepts multiple parameters (steps). In our case it is two steps, the first one will start at 0 degrees (12 o’clock) and span all the way up to 75% of the circumference of the circle (9 o’clock).

The radial-gradient in our case represents the mask, and consists of a white color (to match the background) and transparent color to show the progress bar.

The first parameter of the radial-gradient function is the size of the gradient’s ending shape, in our case, it is equal to the closest-side . Meaning the gradient’s ending shape meets the side of the box closest to its center.

After the size of radial-gradient , we specify the color and size of our mask (white overlay) white 79% and transparent color to take up the remaining size of the circle transparent 80% 100% . The one percent difference (79% and 80%) is made to smooth out the border of the gradient.

Browser compatibility for conic-gradient function:

Conic gradient browser support

Browser compatibility for radial-gradient function:

Radial gradient browser support

Showing the percentage

Additionally, let’s display a percentage value in the middle of the circle to inform users about the exact value of our progress bar.

To do so, we can use a pseudo-element with a content property. As for the progress bar div , we’ll need to set additional properties to center the percentage, flex in this case.

.progress-bar  display: flex; justify-content: center; align-items: center; width: 100px; height: 100px; border-radius: 50%; background: radial-gradient(closest-side, white 79%, transparent 80% 100%), conic-gradient(hotpink 75%, pink 0); > .progress-bar::before  content: "75%"; > 

Animation

💡 NOTE: The animation of such a progress bar will only work in Chromium-based browsers.

To make the progress bar animate, we’ll need to specify the value inside a CSS variable, and then change its value inside the animation.

We must use @property rule to use the variable value inside the animation, but like I said previously, this way we are limited to Chromium based browsers.

Specifying CSS variables in a traditional way like —progress-value: 0 won’t work inside the animation, as per specification they are not animatable.

Browser compatibility for @property rule:

@property browser support

We’ll need to change the percentage value to a calc() function to calculate the percentage for the conic-gradient .

Finally, let’s animate the percentage value along with the progress bar. We will do it in a similar fashion. We’ll use existing CSS variable and set it equal to a pseudo-element counter property, as well as specify the animation property.

@property --progress-value  syntax: ""; initial-value: 0; inherits: false; > @keyframes progress  to  --progress-value: 75; > > .progress-bar  display: flex; justify-content: center; align-items: center; width: 100px; height: 100px; border-radius: 50%; background: radial-gradient(closest-side, white 79%, transparent 80% 100%), conic-gradient(hotpink calc(var(--progress-value) * 1%), pink 0); animation: progress 2s 1 forwards; > .progress-bar::before  counter-reset: percentage var(--progress-value); content: counter(percentage) '%'; animation: progress 2s 1 forwards; > 

Result (refresh page):

Conclusion

While pure CSS solution for circle progress bar is easy to implement it lacks additional customization. For the most part you can only control the width and color of the bar.

Another aspect of this solution, is that it’s not yet fully supported by all browsers, the animation to be exact. So if you’re considering a bulletproof way to display a circle progress bar with animation and possible customizations, you’d might want to use SVG solution.

Finally the end result with complete code can be viewed on CodePen:

See the Pen Untitled by Nikita Hlopov (@nikitahl) on CodePen.

Источник

Индикатор загрузки на чистом CSS

Подпишись на наш телеграм-канал TechRocks WEB-разработка?

Если у вас есть сайт, вам пригодится индикатор загрузки, чтобы пользователи, нажав на кнопку или ссылку, видели, что что-то происходит.

Этот компонент можно использовать во многих местах. При этом желательно, чтобы он был как можно проще.

В этой статье мы рассмотрим создание индикаторов загрузки двух типов. В обоих случаях мы будем использовать всего один html-элемент и несколько строк CSS-кода. Стоит отметить, что наши индикаторы будут настраиваемыми: вы запросто сможете создать множество их вариаций на основе одного и того же кода.

Как создать спиннер

В CodePen вы видите демо того, что мы создадим:

Здесь у нас четыре разных индикатора на основе одного кода. Благодаря изменению всего нескольких переменных мы можем генерировать новый индикатор, не прикасаясь к CSS-коду.

Переменные у нас следующие:

  • —b задает толщину черточек
  • —n — число черточек
  • —g определяет промежутки между черточками. Поскольку у нас круговой элемент, это значение задается как угол.
  • —c определяет цвет.

Вот эти переменные на картинке — для лучшего понимания:

Приступаем к CSS-коду. Для иллюстрации пошагового создания индикатора загрузки используем другую фигуру:

Тут пока ничего сложного. Обратите внимание на использование aspect-ratio . Это позволит менять всего одно значение при изменении размера индикатора.

Затем мы добавляем заливку с коническим градиентом от прозрачного до заданного цвета (переменная —c ):

На этом этапе мы вводим свойство mask , чтобы спрятать некоторые части круга (повторяющимся образом). Тут будут применяться переменные —n и —g .

Если вы присмотритесь к нашей фигуре, вы заметите следующий шаблон:

видимая часть невидимая часть видимая часть невидимая часть и т. д.

Чтобы достичь такого эффекта, мы используем repeating-conic-gradient(#000 0 X, #0000 0 Y) .

От 0 до X у нас непрозрачный цвет (видимая часть), а от X до Y — прозрачный (невидимая часть).

  • Нам нужен промежуток, равный g , между видимыми частями, так что формула для видимых частей X и Y будет X = Y — g .
  • Нам нужно n видимых частей, так что формула Y должна быть Y = 360deg/n . 360deg — это полный круг (360 градусов), который мы просто делим на n .

На данный момент у нас следующий код:

Следующий шаг самый заковыристый. Нам нужно применить еще одну маску, чтобы создать как бы отверстие в круге и таким образом получить итоговую форму.

Для этого мы используем radial-gradient() (что логично) с нашей переменной b :

radial-gradient(farthest-side,#0000 calc(100% - var(--b)),#000 0)

Это полный круг, из которого мы вычитаем толщину линии, равную b .

Добавляем это к предыдущей маске:

Теперь у нас два масочных слоя, но результат не такой, как нам хотелось. Мы получили круг:

Выглядит странно, но на самом деле такой вид совершенно закономерен. «Финальная» видимая часть — не что иное, как сумма всех видимых частей каждого масочного слоя. Это поведение можно изменить при помощи mask-composite . Об этом свойстве стоит написать отдельную статью, так что здесь я просто приведу значение.

В нашем случае нам нужно значение intersect (и destination-out для того же свойства с префиксом). Код становится таким:

С этой фигурой покончено! Только вот индикатор пока без анимации, а должно быть бесконечное вращение.

Обращаю ваше внимание, что для создания иллюзии неподвижных черточек с движущимися цветами я использовал анимацию steps .

Вот иллюстрация, чтобы вы могли понять разницу:

Первый вариант индикатора сделан при помощи линейной анимации (linear). При этом бесконечно вращается сама фигура (это не то, чего бы нам хотелось).

Во втором варианте анимация прерывистая (как нам и нужно).

Вот полный код, включая анимацию:

Вы заметите, что тут кое-что отличается от моих объяснений:

  • Я добавил padding: 1px и установил content-box в background
  • Здесь есть +/1deg между цветами repeating-conic-gradient()
  • Также здесь несколько процентов разницы между цветами внутри radial-gradient()

Это небольшие правки для исправления визуальных помех. Градиенты известны тем, что порой производят «странные» результаты. Во избежание этого приходится подгонять некоторые значения вручную.

Как создать индикатор прогресса загрузки

Как и с первым индикатором, давайте начнем с обзора:

У нас здесь та же конфигурация, что в предыдущем индикаторе. CSS-переменные для управления лоадером:

  • —n определяет число черточек/полосок
  • —s определяет ширину каждой полоски
  • —g задает пробел между полосками

Мы видим, что ширина всего элемента зависит от трех переменных. Наш CSS-код будет следующим:

Для создания промежутков со всех сторон мы используем padding . Наша ширина будет равна числу полосок, умноженному на ширину полосок, плюс промежутки. Один промежуток мы удаляем, потому что при N полосок у нас N-1 промежутков между ними.

Для создания полосок мы используем следующий градиент:

repeating-linear-gradient(90deg, currentColor 0 var(--s), #0000 0 calc(var(--s) + var(--g)) )

Здесь от 0 до s — заданный цвет, а от s до s + g — прозрачный цвет (промежуток).

currentColor , который я использую, это значение свойства color . Обратите внимание, что я не определял никакой цвет внутри border , так что здесь тоже будет использоваться значение color .

Благодаря использованию content-box градиент не закроет зону padding .

Затем я определяю размер как 100% 100% и позицию left.

В этом индикаторе мы будем анимировать background-size от 0% 100% до 100% 100% , т. е. ширину нашего градиента от 0% до 100%.

Как и в предыдущем случае, мы применим steps() , чтобы получить не плавную, а прерывистую анимацию.

Чтобы добиться такого эффекта, как на второй картинке, добавим следующий код:

Присмотревшись к нашей гифке, вы заметите, что анимация неполная. Мы пропускаем одну полоску в конце, хотя используем N . Это не баг, именно так и работает steps() .

Чтобы это исправить, нужно добавить дополнительный шаг. Мы увеличим background-size нашего градиента, чтобы там было N+1 полосок, и используем steps(N+1) .

В итоге наш код будет выглядеть так:

Обратите внимание, что ширина градиента равна N+1 , умноженному на ширину одной полоски, плюс промежутки (вместо 100%).

Источник

Читайте также:  List add java examples
Оцените статью