Сверстать можно практически что угодно, но иногда реализация дизайнерской задумки может привести к настолько сложной вёрстке, что становится проще “нарисовать” всё необходимое. Есть как минимум два способа это сделать: canvas и SVG-графика. Canvas - это тег HTML5 на котором изображения создаются посредством JavaScript. В отличие от него SVG является языком разметки подобным HTML, а значит имеет знакомый верстальщику вид. Кроме того, для SVG применимы CSS-стили.
Один из примеров удачного использования SVG - создание круглого прогресс бара. Эту задачу можно решить как на чистом CSS, так и с использованием canvas, но мне вариант на SVG кажется наиболее красивым.
Для начала научимся рисовать окружность и её часть.
<html>
<head>
<style>
svg {
width: 200px; /* могут быть любыми */
height: 200px;
}
</style>
</head>
<body>
<svg viewbox="0 0 200 200">
<circle r="80" cx="100" cy="100" fill="none" stroke-width="12" stroke="#ccc"/>
</svg>
<svg viewbox="0 0 200 200">
<circle r="80" cx="100" cy="100" fill="none" stroke-width="12" stroke="orangered"
stroke-linecap="round" stroke-dasharray="226 502,4"/>
</svg>
<svg viewbox="0 0 200 200">
<circle r="80" cx="100" cy="100" fill="none" stroke-width="12" stroke="orangered"
stroke-linecap="round" stroke-dasharray="226 502.4"
stroke-dashoffset="-45" />
</svg>
</body>
</html>
Код выше описывает svg-документ размерами 200px на 200px, по центру которого нарисована окружность радиусом 80px. Изображение можно легко масштабировать с помощью CSS атрибутов width
и height
, не меняя размеры внутри SVG-тегов. При этом качество векторной графики не пострадает.
Для заполнения части окружности используют пунктирную линию в качестве границы. Параметры пунктира описываются атрибутом stroke-dasharray
, где первый параметр задаёт длину штриха, второй - расстояние между штрихами. Рассчитываются они исходя из длины окружности (L=2πR).
В нашем случае длина окружности радиусом 80 составит 502,4. Тогда 1% будет соответствовать длине пунктира 502,4 / 100 * 1 = 5.
С помощью параметра stroke-dashoffset
можно регулировать смещение пунктира, таким образом начиная отстчёт с любой точки окружности. Значение может задаваться как в абсолютных единицах, так и в процентах.
Наложим эти круги друг на друга и добавим текст.
<html>
<head>
<style>
svg {
width: 200px; /* могут быть любыми */
height: 200px;
}
</style>
</head>
<body>
<svg viewbox="0 0 200 200">
<circle r="80" cx="100" cy="100" fill="none" stroke-width="12" stroke="#ccc"/>
<circle r="80" cx="100" cy="100" fill="none" stroke-width="12" stroke="orangered"
stroke-linecap="round" stroke-dasharray="226 502.4"
stroke-dashoffset="-45" />
<text x="100" y="125" font-family="Arial" font-size="70"
text-anchor="middle" fill="#444">
50
</text>
</svg>
</body>
</html>
Обратите внимание, что текст вставляется не внутрь тега circle, а под ним, иначе он не отобразится.
Теперь можно добавить элементы оформления: белый край у линии и тень.
<html>
<head>
<style>
svg {
width: 200px;
height: 200px;
}
</style>
</head>
<body>
<svg viewbox="0 0 200 200">
<defs>
<filter id="blurFilter" y="-5" height="40">
<feGaussianBlur in="SourceGraphic" stdDeviation="3" y="-"/>
</filter>
</defs>
<circle r="80" cx="95" cy="110"
fill="none" stroke-width="12"
stroke="#e0e0e0" filter="url(#blurFilter)">
</circle>
<circle r="80" cx="100" cy="100"
fill="none" stroke-width="12"
stroke="#ccc" stroke-dasharray="502,4 502,4"
stroke-linecap="round">
</circle>
<circle r="24" cx="172" cy="123"
fill="#e0e0e0" stroke-width="0"
stroke="#e0e0e0" filter="url(#blurFilter)">
</circle>
<circle r="80" cx="100" cy="100" fill="none"
stroke-width="12" stroke="#F3F5F6" stroke-dashoffset="-42"
stroke-dasharray="10.5 502.4" stroke-linecap="round">
</circle>
<circle r="80" cx="100" cy="100" fill="none"
stroke-width="12" stroke="orangered" stroke-linecap="round"
stroke-dashoffset="-45" stroke-dasharray="4.5 502.4">
</circle>
<text x="100" y="125" font-family="Arial" font-size="70"
text-anchor="middle" fill="#444">
1
</text>
<g>
<circle r="24" cx="175" cy="120" fill="#F3F5F6"
stroke-width="0" stroke="#F3F5F6"/>
<circle r="20" cx="175" cy="120" fill="orangered"
stroke-width="0" stroke="orangered"/>
<text x="175" y="126" font-family="Arial" font-size="18"
text-anchor="middle" fill="#fff">
%
</text>
</g>
</svg>
</body>
</html>
Ссылка на "живой" пример.