Создание компонентов пользовательского интерфейса с SVG и CSS

Например, создание круговой анимации загрузки или применение масок к изображениям. Это не означает, что использование CSS в таких случаях невозможно, но иногда может быть сложно бороться с кроссбраузерными проблемами, основанными на используемой технике (например, масках), поэтому использование SVG может сэкономить время и усилия.

Отличительной особенностью SVG является то, что они могут быть отзывчивыми, производительными и готовыми работать с HTML и CSS. Моя цель в этой статье— познакомить вас с различными вариантами использования, в которых мы можем использовать SVG вместе с HTML и CSS для создания определенных компонентов пользовательского интерфейса. Давайте перейдем к вариантам использования. Вы готовы?

Cut-Out Avatar

Содержание статьи:

Я заметил Cut-Out Avatar изучая CSS Facebook. В мессенджере аватарка пользователя может быть отмечена значком. Часть аватарки вырезается, чтобы выделить место для значка.

Практический курс по верстке адаптивного сайта с нуля!

Изучите курс и узнайте, как верстать современные сайты на HTML5 и CSS3

Это можно сделать, добавив белый border в CSS (как быстрое решение). Но почему бы не реализовать это в динамическом компоненте SVG?

CSS .badge { border: 2px solid #ff; }

123 .badge {    border: 2px solid #ff;}

Вы можете подумать, зачем использовать SVG, если border работает? Ну, здесь нет правильного или неправильного. Но есть решение, которое лучше другого. Вы помните, на уроках математики, когда учитель упоминал проблему, у нее могли быть разные решения, и одно из них могло быть лучшим с точки зрения гибкости? Я вижу то же самое для нашего случая.

В любом случае, я покажу вам, как решение с border может быстро сломаться:

При наведении: фон карты будет меняться, поэтому белая рамка будет казаться странной.

При использовании темного режима: белая рамка будет поверх черного фона.

Обратите внимание, как белая рамка значка пересекается с темным фоном а также при наведении:

Мы можем решить эту проблему, изменив цвет границы при наведении, но мне не кажется это лучшим решением.

CSS .card__badge { border: 2px solid #ff; } .card:hover .card__badge { border-color: lightgrey; } @media (prefers-color-scheme: dark) { .card__badge { border-color: #454545; } }

12345678910111213 .card__badge {    border: 2px solid #ff;} .card:hover .card__badge {    border-color: lightgrey;} @media (prefers-color-scheme: dark) {    .card__badge {        border-color: #454545;    }}

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

Мы используем элемент SVG <image> для размещения аватарки. Чтобы вырезать область значка, нам нужно создать два элемента <circle>, один белый, а другой черный.

При использовании маски любой элемент с черной заливкой будет скрыт, а белый будет виден. Черный круг расположен в правом нижнем углу с радиусом 18. В инструментах дизайна это называется вычитанием. Мы хотим вычесть маленький круг из большего. Вот финальная демонстрация:

Раздел заголовка

В одном из моих клиентских проектов я создал раздел заголовка, объединив SVG и CSS.

Компонент должен работать с короткими и длинными заголовками, а если заголовок слишком длинный, он должен переноситься на несколько строк без нарушения макета. Чтобы осуществить это, я сделал следующее:

скопировал фиксированную часть (справа) и добавил ее как встроенный SVG.

использовал CSS для создания строки под заголовком, а также для маленьких кружков в начале и в конце строки.

построил макет компонента с помощью flexbox, чтобы избежать использования ненужного позиционирования.

Начнем с базовых HTML и CSS.

<h2 class=”c-section__title”> <span>CSS is awesome</span> <svg xmlns=”http://www.w3.org/2000/svg” width=”128″ height=”34.5″ viewBox=”0 0 128 34.5″ preserveAspectRatio=”none”> <path fill=”none” stroke=”#d8d8d8″ stroke-width=”2″ d=”M127 1H33.5L1 33.5″></path> </svg> </h2>

123456 <h2 class=”c-section__title”>    <span>CSS is awesome</span>    <svg xmlns=”http://www.w3.org/2000/svg” width=”128″ height=”34.5″ viewBox=”0 0 128 34.5″ preserveAspectRatio=”none”>        <path fill=”none” stroke=”#d8d8d8″ stroke-width=”2″ d=”M127 1H33.5L1 33.5″></path>    </svg></h2>

CSS .c-section__title { max-width: 700px; width: fit-content; display: flex; margin-left: auto; margin-right: auto; }

1234567 .c-section__title {    max-width: 700px;    width: fit-content;    display: flex;    margin-left: auto;    margin-right: auto;}

Следующим шагом я хочу добавить границу под элементом <span>, чтобы имитировать соединенную линию с SVG.

Я заметил, что SVG никак не связан со строкой. Поскольку мы используем flexbox, исправить это несложно. Нам просто нужно выровнять flex-элементы по flex-end.

CSS .c-section__title { max-width: 700px; width: fit-content; display: flex; align-items: flex-end; margin-left: auto; margin-right: auto; }

12345678 .c-section__title {    max-width: 700px;    width: fit-content;    display: flex;    align-items: flex-end;    margin-left: auto;    margin-right: auto;}

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

Что еще хорошо в использовании SVG, так это то, что мы можем превратить SVG path в пунктирную линию, которую можно анимировать. Для этого нам нужно убедиться, что экспортируемый path в SVG не обведен.

<path d=”M127 1H33.5L1 33.5″ fill=”none” stroke=”#d8d8d8″ stroke-width=”2″></path>

1 <path d=”M127 1H33.5L1 33.5″ fill=”none” stroke=”#d8d8d8″ stroke-width=”2″></path>

Практический курс по верстке адаптивного сайта с нуля!

Изучите курс и узнайте, как верстать современные сайты на HTML5 и CSS3

Идея в том, чтобы получить длину нашего path. В Chrome DevTools выберите элемент <path>, вы увидите == $0 в конце элемента. Оставьте его выбранным и напишите в консоли следующий скрипт:

JavaScript $0.getTotalLength() // 139.46

12 $0.getTotalLength()// 139.46

$0 — это быстрый способ выбрать элемент из DOM, не вдаваясь в нечто подобное:

JavaScript let sectionPath = document.querySelector(‘#path’); console.log(sectionPath.getTotalLength());

12 let sectionPath = document.querySelector(‘#path’);console.log(sectionPath.getTotalLength());

Это был быстрый совет в контексте данного примера. Теперь, когда у нас есть длина, мы можем делать с ней все, что захотим. Например, мы можем анимировать path при наведении.

CSS .c-section__title–dashed path { stroke-dasharray: 139; stroke-dashoffset: 0; transition: 0.7s; } .c-section__title–dashed:hover path { stroke-dashoffset: 139; }

123456789 .c-section__title–dashed path {    stroke-dasharray: 139;    stroke-dashoffset: 0;    transition: 0.7s;} .c-section__title–dashed:hover path {    stroke-dashoffset: 139;}

Или мы можем просто превратить его в пунктирную линию (в этом случае нам не нужно знать длину path).

Подчеркивание пользовательских ссылок с помощью SVG

Мы можем использовать SVG для создания подчеркиваний пользовательских ссылок. Несколько лет назад я создал скрипт, который случайным образом генерирует path и перерисовывает его при наведении. Рассмотрим следующий рисунок для предварительного ознакомления до и после.

Идея состоит в том, что мы хотим вставить SVG в каждую ссылку, и это будет выглядеть следующим образом:

<svg width=”400″ height=”35″ xmlns=”http://www.w3.org/2000/svg”> <path id=”pathItem” d=”M5 5 Q 30 15 170 5″ stroke=”black” fill=”transparent” stroke-width=”7″ stroke-linecap=”round”/> </svg>

12345678 <svg width=”400″ height=”35″ xmlns=”http://www.w3.org/2000/svg”>    <path id=”pathItem”        d=”M5 5 Q 30 15 170 5″        stroke=”black”        fill=”transparent”        stroke-width=”7″        stroke-linecap=”round”/></svg>

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

Пользовательские ленты SVG

Во время работы над клиентским проектом мне понадобился способ прикрепить ленты к разделу таким образом, чтобы их можно было разместить где угодно с помощью CSS, и которые были бы достаточно динамичным, чтобы менять их цвет только с помощью одной переменной CSS. Рассмотрим следующий рисунок:

В Adobe Illustrator я разделил ленту на слои:

Базовый: принимает цвет заливки

Прозрачный черный: показывает более темные области

Прозрачный белый: показывает более светлые области.

Давайте посмотрим на код SVG.

<svg> <defs> <g id=”tape” fill=”currentColor”> <!– path contents –> </g> </defs> </svg>

1234567 <svg>  <defs>    <g id=”tape” fill=”currentColor”>      <!– path contents –>    </g>  </defs></svg>

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

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

Более того, мы можем превратить SVG в шаблон и использовать элемент SVG <use> для повторного использования ленты без дублирования SVG.

<svg style=”display: none;”> <defs> <g id=”tape” fill=”currentColor”> <!– path contents –> </g> </defs> </svg> <!– An example of using the tape from a template –> <svg class=”tape” style=”–angle: 10deg; color: red; –size: 120px;” aria-hidden=”true” focusable=”false” viewBox=”0 0 123 47″> <use href=”#tape”></use> </svg>

123456789101112 <svg style=”display: none;”>  <defs>    <g id=”tape” fill=”currentColor”>      <!– path contents –>    </g>  </defs></svg> <!– An example of using the tape from a template –><svg class=”tape” style=”–angle: 10deg; color: red; –size: 120px;” aria-hidden=”true” focusable=”false” viewBox=”0 0 123 47″>  <use href=”#tape”></use></svg>

Обратите внимание, как я добавил ленту с помощью элемента <use>. Что в этом хорошего, так это использование переменных CSS в качестве встроенных стилей. Вот как выглядит CSS:

CSS .tape { width: var(–size); transform: rotate(var(–angle)); }

1234 .tape {    width: var(–size);    transform: rotate(var(–angle));}

Заключение

Создание компонентов пользовательского интерфейса с помощью SVG может упростить задачу. Использование SVG для некоторых компонентов пользовательского интерфейса может не быть на 100% идеальным вариантом, но это зависит от контекста проекта, над которым вы работаете.

Автор: Ahmad Shadeed

Источник: webformyself.com

Comments (0)
Add Comment