Кроссбраузерный <progress>-бар

в 15:54, , рубрики: <progress>-бар, css, html, Веб-разработка, метки:

image

Доброе время суток, Хабро-сообщество!

Совсем недавно по работе мне попалась интересная задачка, которую я всё же реализовал. Нужно было соорудить прогресс-бар, который был бы полностью универсальный, поддающийся любой стилизации и плюс ко всему кроссбраузерный (начиная c IE7+)!

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


Как вы понимаете, в задачу входило не только сделать, но и ещё по максимуму использовать в работе натуральный элемент <progress>. Его плюс в том, что он является уже почти что готовым решением + семантически правильным в данной ситуациии. Но каково было моё разочарование, когда я понял, что этот элемент, мало того, что очень плохо стилизуется, так ещё и не поддерживается даже в одном из последних браузеров.

Что с поддержкой в браузерах?

На сегодняшний день поддержка в браузерах такова: Firefox 11, Opera 11.61, Chrome 17.
Такой скудный расклад меня явно огорчил и абсолютно не устраивал((. Честно говоря, я рассчитывал на нечто большее, предполагая, что и Safari 5.1 и Internet Explorer 9 всё будет так же здорово.

Что же делать?

В общем для начала я решил порыскать в инете и попробовать найти какие нибудь полезные проприетарные штуки для браузеров. В итоге нашлись три вещи:

  • ::-webkit-progress-bar
  • ::-webkit-progress-value
  • ::-moz-progress-bar

Вкраце, это псевдоэлементы, благодаря которым можно достучаться до элемента <progress> в браузерах Firefox и в Webkit-ных.

Промежуточный тест

Не смотря на то, что в некоторых браузерах есть поддержка элемента <progress>, его стилизация, даже там, оставляет желать лучшего. Например, Opera не хочет поддаваться стилизации и на любое неверное движение приводит полосу индикатора к ненужному нам цвету, а в Safari вообще не работает сам индикатор. Поэтому, я решил использовать найденные свойства и посмотреть, что это мне даст.

<progress max="100" value="30">
    Текст
</progress>​
progress {
    margin: 2em auto;
    display: block;
        width: 100px;
    border-radius : 8px;
    background: #fff;
    padding: 0;
    border: 0;
    text-align: center;
    height: 20px;
    box-shadow: 1px 2px rgba(0,0,0,.3) inset, 0 0 0 1px rgba(0,0,0,.5);
    overflow:hidden;
    background: -o-linear-gradient(#4c4, #8f8 50%, #4c4);

}

progress::-moz-progress-bar {
    background: -moz-linear-gradient(#4c4, #8f8 50%, #4c4);
    border-radius: 8px;
}
progress::-webkit-progress-bar {
    background: #fff;
    box-shadow: 1px 2px rgba(0,0,0,.3) inset, 0 0 0 1px rgba(0,0,0,.5);

}
progress::-webkit-progress-value {
    background: -webkit-linear-gradient(#4c4, #8f8 50%, #4c4);
    border-radius: 8px;
}

И вот что получилось:
image

В Firefox и Chrome мы смогли подчинить себе прогресс-бар полностью, включая каркас и сам индикатор. Случилось это благодаря проприетарным свойтсвам (без них почему-то картина была такая же, как и в Opera) Но, к сожалению в Safari такой номер не прошёл и даже фон исчез полностью. В Opera цвет полоски стал иным после того, как я применил стили к элементу <progress>, а про IE я вообще помолчу.

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

Однозначно можно сказать про две вещи. Основные скрипты не нужны для Firefox и Chrome, но полюбому нужны для IE6-9 и Safari. А вот с Opera я решил вообще не париться и оставить в ней цвет индикатора на совести разработчиков этого браузера.

Задача

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

  • По максимуму задействовать элемент <progress> там, где это возможно. Семантика здесь играет ключевую роль (если это не вредит качеству) и поэтому использовать семантические элементы для нас очень важно.
  • Прогресс-бар должен содержать отдельный текст, который будет отображать текущий процент заполнения индикатора.
  • Прогресс-бар должен быть легко настраиваемый и видоизменяющимся. В зависимости от класса он должен менять ширину, высоту, цвет и т.д.
  • Наш прогресс-бар должен работать по возможности одинаково во всех браузерах, начиная с IE7+

Исходя из задачи, я сделал вывод, что в нашем случае подошёл бы общий контейнер, в котором находились бы сам элемент <progress> и второй элемент для текста.

<div class="psyProgressBar">​
        <progress max="80" value="0" class="psyProgressBar__line">​</progress>​
        <i class="psyProgressBar__text">​0%</i>​
</div>​

Далее уже должно идти путешествие по скрипту, но я решил оставить эту часть для тех, кто захочет прочитать статью полностью.

Единственное скажу, что суть в том, что для «нормальных» браузеров я применил скрипт только лишь для заполнения индикатора, а для всех остальных браузеров сделал подмену элемента <progress> на элемент <div> со спец. классом, через который в итоге можно стилизовать наш прогресс-бар как нам вздумается.

Так что здесь я выложу уже готовое решение, а тем, кто уже знаком с моим стилем и хочет прочитать всю статью целиком, милости прошу в саму статью. Не забудьте о печеньках! :)

Автор: psywalker

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js