[Перевод] [в закладки] Работа с изображениями в веб
Одно из решений, которые приходится принимать фронтенд-разработчику при создании сайта, касается выбора способа включения изображений в состав веб-страниц. Этот способ может заключаться в использовании HTML-тега . Это может быть применение CSS-свойства
background
или тега
элемента . Выбор правильного подхода к работе с изображениями весьма важен, так как это может очень сильно повлиять на производительность и доступность проекта.
Материал, перевод которого мы сегодня публикуем, посвящён изучению различных способов включения изображений в состав веб-страниц. Здесь будут обсуждены преимущества и недостатки этих способов. Кроме того, мы поговорим о том, когда и почему их обычно используют.
HTML-элемент
Элемент в простейших вариантах его использования содержит лишь необходимый для его правильной работы атрибут
src
:
▍Настройка атрибутов width и height
Если не будут настроены ширина и высота изображения, то при загрузке странице с последующей загрузкой изображения макет страницы может понадобиться перестроить. Для того чтобы этого избежать, можно задать атрибуты width
и height
тега :
Хотя кому-то такой подход может слегка напомнить, так сказать, «старую школу», он, на самом деле, довольно полезен. Давайте, чтобы лучше в этом разобраться, продемонстрируем вышесказанное примером. А именно, я предлагаю вам посмотреть это короткое видео.
Кадр из видео. У изображения слева ширина и высота не заданы. У изображения справа — заданы
Здесь показана панель Network
инструментов разработчика браузера и продемонстрирован процесс загрузки пары изображений. Одно из них, расположенное слева, представлено тегом , у которого атрибуты
width
и height
не заданы. У другого значения этих атрибутов заданы.
Вы заметили, что на странице место под правое изображение резервируется ещё до того, как это изображение будет загружено? Всё дело в заданных атрибутах width
и height
. Обратите внимание и на то, что происходит с подписями к изображениям в процессе их загрузки. Это — наглядная демонстрация силы атрибутов width
и height
.
→ Вот рабочий пример
▍Скрытие изображения средствами CSS
Изображение можно скрыть с помощью CSS. Правда, такое изображение всё равно загружается при загрузке страницы. Поэтому, поступая так, следует соблюдать осторожность. Если некое изображение нужно скрыть, то оно, возможно, используется лишь в декоративных целях.
Вот CSS-код, скрывающий изображение:
img {
display: none;
}
Повторюсь: при таком подходе браузер будет загружать изображение, делая это даже в том случае, если оно оказывается невидимым. Дело тут в том, что элемент считается замещаемым элементом, поэтому наши возможности по управлению таким элементом из CSS ограничены.
▍О доступности контента
Доступность изображений, выводимых на страницах с помощью HTML-элемента , обеспечивается их атрибутами
alt
. В таком атрибуте должно содержаться понятное описание изображения. Это может очень пригодиться пользователям, применяющим средства для чтения с экрана.
Однако в том случае, если в alt
-описании изображение не нуждается, этот атрибут, всё равно, удалять не рекомендуется. Дело в том, что если это сделать, то «озвучено» будет содержимое атрибута src
. Это очень плохо для доступности контента.
Но атрибут alt
полезен не только в вышеописанном случае. Если по какой-то причине изображение не будет загружено, и у него имеется атрибут alt
, то текст из этого атрибута будет выведен вместо изображения. Хочу проиллюстрировать вышесказанное следующим примером.
У нас есть пара изображений:
В атрибуте src
записан неправильный адрес к графическому файлу, этот файл не может быть загружен браузером. У первого нет атрибута
alt
, а у второго есть такой атрибут, в который записана пустая строка. Как вы думаете, как эти элементы будут выведены на странице?
Слева — изображение без атрибута alt. Справа — с пустым атрибутом alt
Под изображение без атрибута alt
резервируется пространство страницы, что может запутать пользователя и ухудшить доступность контента. А другое изображение занимает совсем мало места, которое нужно для вывода «содержимого» пустого атрибута alt
. В результате оно больше похоже на точку, а не на изображение. Происходит это и-за настроек свойства border
изображения.
Правда, когда в атрибут alt
что-то записано, изображение будет выглядеть уже по-другому.
Справа — изображение, в атрибут alt которого записан текст
Это гораздо лучше, чем ничего. Кроме того, если не удаётся загрузить файл, выводимый в , можно добавить к нему псевдо-элемент.
▍Отзывчивые изображения
Изображения разных размеров
Элемент хорош тем, что его можно настроить так, чтобы он выводил бы разные версии изображения в областях просмотра страницы разного размера. Это, например, можно использовать для изображений, применяемых в статьях.
Отзывчивый набор изображений можно настроить двумя способами.
1. Атрибут srcset
Вот код изображения, в котором используется атрибут srcset
:
Это — простой пример. Я не считаю идеальным решением использование srcset
для описания изображений разных размеров, выводимых на экранах с разными характеристиками. Дело в том, что в такой ситуации последнее слово остаётся за браузером, а разработчик на выбор браузера повлиять не может.
2. HTML-элемент picture
Вот код, в котором используется элемент :
Другой вариант создания отзывчивых изображений заключается в использовании элемента . Мне больше нравится этот подход из-за того, что он проще, и из-за того, что он даёт более предсказуемые результаты.
Вот демонстрационный проект к этому разделу.
▍Изменение размеров изображений
Слева — изображение, у которого не задано CSS-свойство object-fit. Справа — изображение, у которого это свойство задано
CSS-свойства object-fit
и object-position
— это замечательные инструменты, которые можно использовать с элементом . Они дают нам контроль над тем, как изменяется и позиционируется содержимое элемента
. Это напоминает работу с CSS-свойством
background
.
Свойство object-fit
может иметь следующие значения: fill
, contain
, cover
, none
, scale-down
.
Вот как им пользоваться:
img {
object-fit: cover;
object-position: 50% 50%;
}
Теперь, когда мы немного разобрались с элементом , пришло время двигаться дальше и осваивать следующую методику работы с изображениями.
Изображения, задаваемые CSS-свойством background
Когда для вывода изображений используют CSS-свойство background
, нужно, чтобы это свойство применялось бы к элементу с неким содержимым, или к элементу, у которого заданы размеры. Обычно главной сферой использования этого свойства являются декоративные элементы.
▍Как пользоваться CSS-свойством background
Для того чтобы воспользоваться CSS-свойством background
, нам сначала понадобится элемент:
Some content
Потом понадобится стиль:
.element {
background: url('cool.jpg');
}
▍Задание нескольких изображений в свойстве background
Приятное свойство изображений, выводимых средствами CSS-свойства background
, заключается в том, что таких изображений может быть несколько. Этими изображениями можно управлять средствами CSS:
.element {
background: url('cool-1.jpg'), url('cool-2.jpg');
}
▍Скрытие изображения
Средствами CSS можно скрывать и показывать изображения в конкретной области просмотра. При этом изображения, которые не будут выводиться, не будут и загружаться. Если изображение в CSS не настроено как видимое, то и загружаться оно не будет. Это — дополнительное преимущество CSS-свойства background
перед элементом .
@media (min-width: 700px) {
.element {
background: url('cool-1.jpg');
}
}
В этом примере описано фоновое изображение, которое выводится только в том случае, когда ширина области просмотра больше 700px
.
▍О доступности контента
Если изображениями, выводимыми с помощью CSS-свойства background
, пользоваться неправильно, это может повредить доступности контента. Например, доступность может пострадать при использовании такого изображения для закладки статьи, которая жизненно важна при работе со статьей.
▍Сложности с загрузкой background-изображений обычными пользователями
Обычные пользователи знают о том, что если нужно сохранить некое изображение — достаточно щёлкнуть по нему левой кнопкой мыши и выбрать соответствующую команду контекстного меню. Может, это покажется вам забавным, но с изображениями, задаваемыми с помощью CSS-свойства background
, этот приём не работает. Такое изображение обычным способом не загрузить. Для его загрузки потребуется исследовать код элемента в инструментах разработчика и воспользоваться ссылкой из url
.
▍Псевдо-элементы
Псевдо-элементы можно использовать и с изображениями, задаваемыми CSS-свойством background
. Например — для показа одного изображения поверх другого. В случае с элементом этого можно достичь только с использованием дополнительного элемента, накладываемого на другой элемент.
Теперь поговорим об использовании SVG-изображений
SVG-изображения
Основной сильной стороной SVG-изображений считается возможность их масштабирования без потери качества. Более того, элемент может выводить, помимо SVG-изображений, ещё и файлы формата JPG и PNG. Вот HTML-код SVG-изображения:
JPG-изображение, выведенное средствами элемента SVG
Обратили внимание на атрибут preserveAspectRatio
? Благодаря ему изображение занимает полную ширину и высоту элемента , не растягиваясь и не сжимаясь.
Если ширина элемента
больше, оно заполнит родительский элемент () по ширине, но при этом не будет растягиваться.
Изображение не растягивается
Это очень похоже на то, как работают CSS-свойства object-fit: cover
или background-size: cover
.
▍О доступности контента
Если говорить о доступности контента при использовании SVG-изображений, то могу сказать, что такой разговор сразу напоминает мне об элементе
. Ниже показан пример кода, в котором к изображению, выводимому средствами , добавлен такой элемент:
Тут, более того, можно воспользоваться и элементом
:
▍Сложности с загрузкой
Изображение, выведенное с помощью , можно загрузить, лишь проанализировав его код и добравшись до ссылки на изображение. Это минус, но в том случае, если некто хочет ограничить возможности обычных пользователей по загрузке изображений, эта особенность может и пригодиться. По меньшей мере, это снизит шансы на загрузку такого изображения.
→ Вот пример к этому разделу
Сценарии использования разных способов вывода изображений
▍Раздел страницы, выводимый в её верхней части
Проектируя раздел страницы, находящийся в её верхней части (такой раздел называют «Hero Section»), иногда нужно сделать так, чтобы в нём выводилось бы изображение, поверх которого выводится заголовок и какие-то другие данные о странице. Выглядеть это может примерно так, как показано ниже.
Верхняя часть страницы с изображением и надписями
Обратите внимание на то, что тут имеется фоновое изображение. Как бы вы подошли к разработке подобного раздела страницы? Но, прежде чем вы ответите на этот вопрос, позвольте мне сформулировать некоторые требования:
- Изображение должно поддерживать лёгкую динамическую смену при интеграции страницы с бэкенд-CMS.
- Поверх изображения должен быть наложен элемент, упрощающий чтение текста.
- Нужно поддерживать вывод изображения в трёх размерах: в маленьком, среднем и большом. Каждый из них предназначен для собственной области просмотра.
Прежде чем переходить к решению этой задачи, зададимся вопросом о природе фонового изображения, которое тут будет использоваться. Вот некоторые вспомогательные вопросы, которые помогут нам докопаться до сути:
- Важно ли это изображения с точки зрения пользователя, или он ничего не потеряет в том случае, если оно будет не видно?
- Нужно ли, чтобы это изображение выводилось в областях просмотра всех размеров?
- Является ли это изображение статическим, или оно динамически меняется (из CMS, например)?
Рассмотрим пару вариантов решения этой задачи.
Первый вариант решения задачи
Используя CSS-свойство background
с несколькими заданными в нём изображениями, одно из них можно использовать для элемента, накладываемого на основное изображение, а другое — для представления самого изображения. Взгляните на этот CSS-код:
.hero {
background-image: linear-gradient(rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0.4)), var('landscape.jpg');
background-repeat: no-repeat;
background-size: 100%, cover;
}
Этот подход позволяет достичь желаемого, background-image
можно менять средствами JavaScript:
Свойство background
я определил во встраиваемом стиле. Хотя это и рабочий код, выглядит он плохо и отличается непрактичностью.
Может быть, можно воспользоваться здесь CSS-переменными?
Вот результат исследования стиля.
Исследование стиля элемента
Теперь для изменения фонового изображения нам достаточно поменять переменную --bg-url
. Это в миллион раз лучше, чем встроенные стили.
Анализ
- Предложенный здесь вариант решения задачи хорош лишь в том случае, если изображение не особенно важно.
- Он может подойти в том случае, если изображение не планируется менять динамически, средствами CMS, используемой на бэкенде проекта.
→ Вот рабочий пример
Второй вариант решения задачи
Здесь мы воспользуемся HTML-средствами вывода изображения:
Using Images in CSS
An article about which and when to use
В CSS надо настроить абсолютное позиционирование изображения, расположив его под текстом. Кроме того, тут нам понадобится псевдо-элемент, который будет играть роль элемента, накладываемого на изображение:
.hero {
position: relative;
}
.hero img {
position: absolute;
left: 0;
top: 0;
z-index: -1;
width: 100%;
height: 100%;
object-fit: cover;
}
.hero:after {
content: "";
position: absolute;
left: 0;
top: 0;
z-index: -1;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.4);
}
Это решение хорошо тем, что при его использовании очень легко поменять атрибут изображения src
. Кроме того, оно лучше для того случая, когда выводимое изображение важно.
Кроме того, отмечу, что мне нравится в -изображениях то, что при их использовании можно использовать резервные механизмы, срабатывающие в том случае, если файл изображения загрузить не удаётся. Такой вспомогательный механизм, скажем, вывод вместо изображения простого цветного фона, по крайней мере, позволит пользователям прочитать текст:
.hero img {
/* Другие стили */
background: #2962ff;
}
Фоновый цвет, выводимый в том случае, если изображение загрузить не удаётся
Здесь хорошо то, что фоновый цвет выведется только в том случае, если не удастся загрузить изображение. Это нас устроит.
→ Вот рабочий пример
▍Логотип веб-сайта
Логотип — это очень важно. Логотипы добавляют сайтам уникальности. Для того чтобы вывести на странице логотип, мы можем прибегнуть к нескольким возможностям:
- Элемент
, выводящий PNG, JPG или SVG-изображение.
- Встроенное SVG-изображение.
- Фоновое изображение.
Поговорим о том, какой способ вывода изображений стоит использовать для логотипов, и о том, как выбрать именно то, что нужно.
Логотип с множеством деталей
Если логотип имеет множество деталей или содержит много фигур, вывод его с использованием встроенного SVG-изображения может оказаться не такой уж хорошей идеей. В такой ситуации я рекомендую использовать тег , средствами которого выводится PNG, JPG или SVG-изображение.
Разные логотипы
Вот код для вывода подобного логотипа, хранящегося в формате SVG:
Простой логотип, который нужно анимировать
Простой анимированный логотип
Рассмотрим ситуацию, когда имеется простой логотип, содержащий некую фигуру или текст. При наведении на него указателя мыши нужно изменить цвет фигуры и текста. Как это сделать? Мне кажется, что в этой ситуации лучше всего воспользоваться встроенным SVG-изображением:
Вот стили:
.logo rect,
.logo text {
transition: 0.3s ease-out;
}
.logo:hover rect,
.logo:hover text {
fill: #4a7def;
}
Вот демонстрационный проект к этому разделу:
Отзывчивый логотип
Когда я подумал об отзывчивых логотипах, то вспомнил логотип Smashing Magazine. Мне нравится то, как меняется его размер. Вот макет, иллюстрирующий базовый логотип и логотип, выводимый в больших областях просмотра.
Отзывчивый логотип
Для реализации такого поведения логотипа идеально подойдёт элемент , который позволяет описать две версии логотипа:
В CSS нужно поменять ширину логотипа в том случае, если ширина область просмотра будет равной или большей 1350px
:
.logo {
display: inline-block;
width: 45px;
}
@media (min-width: 1350px) {
.logo {
width: 180px;
}
}
Перед нами — простое и понятное решение проблемы отзывчивых логотипов.
→ Вот рабочий пример к этому разделу
Логотип с градиентом
Пример логотипа с градиентом
Работая с логотипами, на которых имеется градиент, нужно знать о том, что экспорт подобного логотипа из приложения для дизайна, вроде Adobe Illustrator или Sketch, может завершиться далеко не идеально. В ходе этого процесса что-то в логотипе может «поломаться».
При использовании формата SVG можно легко применить к логотипу градиентный цвет. В следующем примере я использовал
, настроив с его помощью атрибут текста fill
:
→ Вот пример
▍Аватар пользователя
Бывают аватары самых разных форм, но обычно используются квадратные или круглые аватары. В данном примере мне хочется поделиться одним важным советом, который вы, вполне возможно, сочтёте полезным.
Для начала взгляните на следующий макет. Обратите внимание на то, что там представлены два аккуратных аватара с чёткими краями.
Пара удачных аватаров
А что если пользователь, в качестве аватара, решит использовать картинку с почти белым фоном? Если так — то аватар будет выглядеть уже далеко не так хорошо.
Неудачный аватар
Обратите внимание на то, что на предыдущем рисунке изображён аватар с очень светлым фоном. В результате для того чтобы понять то, что он имеет круглую форму, к нему приходится присматриваться. Это плохо. Для того чтобы исправить эту проблему, нужно добавить к аватару внутреннюю границу. Эта граница будет использоваться в качестве вспомогательного решения, применяемого в том случае, когда изображение оказывается слишком светлым.
Слева — аватар со слишком светлым фоном. Справа — результат решения этой проблемы
Решить эту задачу можно несколькими способами:
- С использованием
.
- С использованием
и вспомогательного элемента
.- С использованием
и CSS-свойстваbackground
.- С использованием
в.
Что тут подходит лучше всего? Давайте выясним.Использование
Как решить эту задачу? Может — просто настроить границу элемента? Исследуем эту возможность (сразу извиняюсь за то, что ниже вы часто будете видеть мою фотографию).Вот CSS-код:
.avatar { border: 2px solid #f2f2f2; }
Вот как это выглядит.
Результат оказался не таким, как ожидается: тёмная граница расположена за пределами границ изображенияТо, что получилось, нас не устраивает. Нам надо, чтобы у изображения была бы внутренняя граница, которая сливается с тёмным изображением. В результате оказывается, что настройка границы элемента нам тут не поможет.
Использование и вспомогательного элемента
Напомню, что перед нами стоит задача добавления к изображению внутренней тени. Эту задачу мы не можем решить с помощью внутренней тени (box-shadow
) и ключевого словаinset
, так как HTML-элементывнутреннюю тень не поддерживают. Для решения этой задачи нужно поместить аватар в элемент
и воспользоваться ещё одним элементом, единственное предназначение которого — вывод внутренней границы.Вот HTML-код:
Вот стили:.avatar-wrapper { position: relative; width: 150px; height: 150px; } .avatar-border { position: absolute; left: 0; top: 0; width: 100%; height: 100%; border-radius: 50%; border: 2px solid rgba(0, 0, 0, 0.1); }
Если у элементаимеется граница, окрашенная в 10%-й чёрный цвет, это обеспечит нам то, что такая граница на тёмном изображении будет не видна, а на светлом будет заметна, выделяя его границу. Вот как это выглядит.
Внутренняя граница, видимая только на светлых изображениях→ Вот пример к этому разделу
Использование
и CSS-свойства background
Если бы я использовал для вывода аватара элемент, то это, возможно, значило бы, что изображение играет декоративную роль. Мне тут приходит в голову один пример, показанный ниже. Здесь разные аватары просто разбросаны по странице.
Аватары, разбросанные по страницеHTML-код здесь будет таким:
Вот стиль:.avatar { background: var(--img-url) center/cover; width: 150px; height: 150px; border-radius: 50%; box-shadow: inset 0 0 0 2px rgba(#000, 0.1); }
Здесь можно найти работающий пример.Использование
в
Я полагаю, что это — наиболее интересное решение нашей задачи. Я обнаружил этот приём, изучая новый дизайн Facebook.Вот разметка:
Сначала разберём этот код. Вот что тут есть:- Маска, обрезающая изображение в виде круга.
- Группа, к которой применяется маска.
- Само изображение с атрибутом
preserveAspectRatio=«xMidYMid»
. - Круг, который используется в роли внутренней границы.
Вот как это стилизуется:circle { stroke-width: 2; stroke: rgba(0, 0, 0, 0.1); fill: none; }
→ Здесь можно найти примерС аватарами мы на этом разобрались. Поэтому идём дальше.
▍Поле ввода с иконкой
Вот пример поля ввода с иконкой.
Поле ввода с иконкойТакие поля встречаются довольно часто. Как оснастить поле иконкой? Что происходит при получении таким полем фокуса? Исследуем эти вопросы.
Вот HTML-код:
Я полагаю, что лучшее решение этой задачи заключается в использовании фоновых изображений, задаваемых средствами CSS. Это просто, быстро и не требует привлечения дополнительных HTML-элементов:input { background-color: #fff; background-image: url('user.svg'); background-size: 20px 20px; background-position: left 10px center; background-repeat: no-repeat; }
Для изменения цвета иконки при получении полем фокуса можно использовать URL-кодированное SVG-изображение. Сделать это очень легко. Например, для этого предназначен данный инструмент, разработанный Yoksel.Вот пример.
▍CSS-стили для печати
Посетителю страницы может понадобиться распечатать её на принтере. Предположим, на странице имеется кулинарный рецепт, и его нужно распечатать, сделав это для того, чтобы на кухне не приходилось бы постоянно заглядывать в телефон или в компьютер.Если в рецепте есть шаги, проиллюстрированные картинками, важно, чтобы они попали бы в его печатную версию, иначе тот, кто выведет страницу на печать, не сможет воспользоваться рецептом.
Постарайтесь не включать в страницы, предназначенные для печати, изображения, выводимые с помощью CSS-свойства background
Если изображение включается в состав страницы с помощью CSS-свойстваbackground
, тогда на печать оно выводиться не будет. То место, где оно отображалось, при печати окажется пустым. Вот о чём я говорю.
Пустые места вместо изображений, включённых в страницу с помощью CSS-свойства backgroundОт такой печатной версии рецепта будет мало пользы. Исправить это можно, заставив браузер выводить подобные изображения в печатной версии страницы. Но этот подход не работает в Firefox и в IE. Вот как это выглядит в CSS:
.element { background: url('cheesecake.png') center/cover no-repeat; -webkit-print-color-adjust: exact; /* Принудительный вывод фонового изображения в режиме печати */ }
В подобных ситуациях лучше всего пользоваться HTML-элементом. Изображения, включённые в страницу с помощью этого элемента, выводятся на печать без проблем.
→ Вот пример
Итоги
Сегодня мы поговорили о разных способах включения изображений в состав веб-страниц, обсудили их плюсы и минусы, рассмотрели сценарии их использования. Надеемся, вам пригодится то, о чём вы сегодня узнали.Уважаемые читатели! Сталкивались ли вы с проблемами при выводе изображений на веб-страницах?
- С использованием