Техника отображения изображений в Интернете
Одним из решений, которое необходимо сделать frontend разработчику при создании веб-сайта, является метод включения изображения. Это может быть HTML img
, или изображение через фоны CSS, или, может быть, SVG image
. Выбор правильной техники важен и может сыграть огромную роль в производительности и доступности.
В этой статье мы изучим различные способы включения изображения в дополнение к упоминанию о преимуществах и недостатках каждого из них, а также о том, когда и зачем их использовать.
HTML- элемент Img
Элемент изображения в его простейших случаях должен содержать атрибут src
по мере необходимости.
<img src="cool.jpg" alt="">
Установка атрибутов ширины и высоты
При загрузке страницы они будут сдвигаться по нескольким макетам во время загрузки изображений страницы. Чтобы избежать этого, мы можем установить атрибуты для этого: width
height
<img src="cool.jpg" width="200" height="100" alt="">
Хотя для некоторых это может показаться немного старой школой, но это полезно. Давайте представим это, чтобы понять концепцию:
Вы заметили, как у изображения справа зарезервировано место, даже если оно еще не загружено? Вот так width
и height
установлены. Это делает заметную разницу!
Скрытие изображения с помощью CSS
Изображение может быть скрыто с помощью CSS. Тем не менее, оно все равно будет загружено на странице. По этой причине, пожалуйста, будьте осторожны. Если изображение должно быть скрыто, то, вероятно, это для декоративных целей.
img {
display: none;
}
Опять же, вышесказанное не помешает браузеру загрузить изображение, даже если оно визуально скрыто. Причина в том, что элемент img
считается замененным , поэтому мы не можем контролировать загружаемый контент.
Проблемы доступности
HTML-изображения должны быть доступны, установив для атрибута alt
содержательное описание. Это может быть очень полезно для пользователей программ чтения с экрана.
Однако, если описание alt
не нужно, пожалуйста, не удаляйте его, и если вы это сделаете, изображение src
будет зачитано! Это очень плохо для доступности.
Не только это, но если изображение по какой-то причине не загружается и имеет четкое изображение alt
, оно будет отображаться как запасной вариант. Давайте рассмотрим визуально, потому что есть интересные вещи, в которых я хочу убедиться, что вы это знаете.
У нас есть следующие изображения:
<img class="food-thumb" width="300" height="200" src="cheescake.jpg">
<img class="food-thumb" width="300" height="200" src="cheescake.jpg" alt="">
src
является недействительным и не сработал. Первый не имеет атрибута alt
, а второй - пустой alt
. Можете ли вы ожидать визуальный результат этого?
Изображение без alt
все еще остается зарезервированное пространство, что сбивает с толку и ухудшает доступность. В то время как другой свернулся, чтобы соответствовать содержимому своего пустого атрибута alt
, это вызвало его появление в виде крошечной точки из-за наличия border
.
Однако, когда есть значение атрибута alt
, оно будет выглядеть так:
Разве это не хорошая обратная связь? Кроме того , когда источник изображения не получится , вы можете добавить псевдо-элемент к ним.
Адаптивные изображения
Хорошая вещь о img
, что это может быть расширено, чтобы иметь несколько версий фотографии для определенных размеров области просмотра. Это может быть использовано, например, для изображений статей.
У нас есть два разных способа получения адаптивного набора изображений:
<img src="small.jpg" srcset="medium.jpg 500w, large.jpg 800w" alt="">
1. Атрибут srcset
Это очень просто. Для меня я не вижу, что использование srcset
является идеальным решением для того, чтобы иметь несколько размеров изображений, которые появляются в зависимости от ширины экрана. Выбор заключается только в том, чтобы браузер выбрал соответствующее изображение, и у нас нет контроля над этим.
2. HTML - Элемент picture
<picture>
<source srcset="large.jpg" media="(min-width: 800px)" />
<source srcset="medium.jpg" media="(min-width: 500px)" />
<img src="small.jpg" />
</picture>
Другой вариант - использование элемента picture
. Я предпочитаю этот, так как он проще и более предсказуем.
Изменение размера изображений
Единственная замечательная вещь, которую мы можем использовать с img
это свойства object-fit
и object-position
. Они дают нам контроль над тем, как img
можно изменять размер и расположение контента, как фоновые изображения CSS.
Возможные значения для подгонки объекта: заполнить, содержать, покрыть, нет, уменьшить
Это можно использовать так:
img {
object-fit: cover;
object-position: 50% 50%;
}
Теперь, когда мы познакомились с элементом img
, пришло время двигаться вперед и изучить вторую технику.
CSS фоновое изображение
При использовании CSS-фона для показа изображения необходим элемент с содержимым, определенной шириной или высотой. Обычно основное использование фонового изображения должно быть в декоративных целях.
Как использовать фоновое изображение CSS
Просто нам нужен элемент.
<div class="element">Some content</div>
.element {
background: url('cool.jpg');
}
Несколько фонов
Хорошо с фоновыми изображениями CSS иметь несколько фонов, которыми можно легко управлять с помощью CSS. Рассмотрим следующий пример:
.element {
background: url('cool-1.jpg'), url('cool-2.jpg');
}
Скрытие изображения
Мы можем скрыть и показать изображение в определенном окне просмотра, не загружая его. Если изображение не настроено с помощью CSS, оно не будет загружено. Это дополнительное преимущество по сравнению с использованием img
.
@media (min-width: 700px) {
.element {
background: url('cool-1.jpg');
}
}
В приведенном выше примере у нас есть фоновое изображение, которое отображается только тогда, когда ширина области просмотра больше, чем 700px
.
Проблемы доступности
При неправильном использовании фоновое изображение может ухудшить доступность.
Не могут быть загружены пользователями, не являющимися разработчиками
Это может показаться смешным, но обычные люди знают, что если вы хотите сохранить изображение, вы просто щелкаете левой кнопкой мыши и затем выбираете сохранить. Это не относится к фоновым изображениям CSS. Невозможно загрузить изображение, которое добавляется с помощью CSS, пока вы не осмотрите элемент, а затем не откроете ссылку внутри url
в DevTools.
Псевдоэлементы
Можно использовать pseudo-elements
вместе с фоновыми изображениями CSS, например, чтобы показать наложение в верхней части изображения. С помощью img
, это невозможно, пока мы не добавим отдельный элемент для наложения.
SVG Image
SVG рассматривается как изображение, и его наибольшая сила заключается в масштабировании, не влияющем на качество. Добавлю , что, с SVG, мы можем встроить JPG
, PNG
или SVG
изображение. Смотрите HTML ниже:
<svg width="200" height="200">
<image href="cheesecake.jpg" height="100%" width="100%" preserveAspectRatio="xMidYMid slice" />
</svg>
Вы заметили preserveAspectRatio
? Это то, что сохраняет изображение на всю ширину и высоту SVG без растяжения или сжатия.
Когда image
ширина больше, он заполнит ширину родительского (SVG) без растяжения.
Это очень похоже на object-fit: cover
или background-size: cover
в CSS.
Проблемы доступности
Когда дело доходит до доступности с SVG, это напоминает мне элемент title
. Например, мы можем добавить его, как показано ниже:
<svg width="200" height="200">
<title>A photo of blueberry Cheescake</title>
<image href="cheesecake.jpg" height="100%" width="100%" preserveAspectRatio="xMidYMid slice" />
</svg>
Более того, мы можем использовать элемент desc
:
<svg width="200" height="200">
<title>A photo of blueberry Cheescake</title>
<desc>A meaningful description about the image</desc>
<image href="cheesecake.jpg" height="100%" width="100%" preserveAspectRatio="xMidYMid slice" />
</svg>
Не могут быть загружены пользователями, не являющимися разработчиками
Невозможно загрузить изображение, встроенное в SVG, пока вы не осмотрите элемент и не скопируете URL-адрес изображения. Однако это может быть полезно, если мы хотим запретить пользователям загружать определенное изображение. По крайней мере, это уменьшит шансы на загрузку изображения легко.
Случаи применения
Раздел Hero
При создании раздела героя нам иногда требуется изображение, которое будет находиться под заголовком и другим содержимым. Смотрите рисунок ниже:
Обратите внимание, что есть изображение. Как бы вы подошли к созданию этого? Что ж, позвольте мне добавить некоторые требования раньше:
- Образ должен быть динамически изменен при интеграции его с внутренней CMS.
- Над ним есть наложение, помогающее сделать содержимое легким для чтения.
- Существует три размера изображения: маленький, средний и большой. Каждый из них предназначен для определенного видового экрана.
Прежде чем начать с решений, давайте спросим себя о природе этого фона. Вот несколько начальных вопросов:
- Важно ли иметь это изображение для пользователя, или его можно пропустить?
- Нужно ли иметь его на всех размерах окна просмотра?
- Это статично или будет динамически меняться (например, из CMS)?
Hero - Решение 1
Используя несколько фонов CSS, мы можем иметь один для наложения, а другой для реального изображения. Смотрите 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. Смотрите ниже:
<section class="hero" style="background: linear-gradient(rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5)), url('landscape.jpg');">
<!-- Hero content -->
</section>
Я добавил фон в качестве встроенного CSS. Пока это работает, это выглядит уродливо, и это не практично.
Может быть, мы можем использовать переменные CSS? Давайте исследуем это.
<section class="hero" style="--bg-url: url('landscape.jpg')">
<!-- Hero content -->
</section>
Теперь мы можем легко обновить переменную --bg-url
, и это будет динамически менять фон. Это в миллион раз лучше встроенных штучек.
Решение 1 Вынос
- Решение хорошо только в том случае, если изображение не важно
- Когда изображение не будет изменено динамически из внутренней CMS
Hero - Решение 2
Для этого решения мы будем использовать изображение HTML. Смотрите ниже:
<section class="hero">
<h2 class="hero__title">Using Images in CSS</h2>
<p class="hero__desc">An article about which and when to use</p>
<img src="landscape.jpg" alt="">
</section>
В 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
. Кроме того, будет более полезно, если изображение важно иметь.
Кроме того, что мне нравится в использовании HTML img
- это возможность добавить запасной вариант на случай, если изображение не загрузилось. Этот запасной вариант, по крайней мере, может сделать содержимое читабельным.
.hero img {
/* Other styles */
background: #2962ff;
}
Хорошо, что фон будет работать только в случае сбоя источника. Разве это не круто?
Логотип cайта
Логотип-это очень важная вещь, поскольку он отличает один сайт от другого. Чтобы встроить логотип, у нас есть несколько вариантов:
<img> ->
png,
jpg, or
svg`- Встроенный SVG
- Изображение на заднем плане
Давайте узнаем, какую технику использовать и как выбрать правильную.
Логотип c большим количеством деталей
Когда у логотипа много деталей или форм, использование его в качестве встроенного SVG может быть не очень полезным. Я рекомендую использовать img
и тип изображения может быть png
, jpg
или svg
.
<a href="#"><img src="logo.svg" alt="Nature Food"></a>
Простой логотип, который нужно анимировать
У нас есть простой логотип, который состоит из формы и текста. При наведении, форма и текст должны меняться в цвете. Как это сделать? Лучшее решение для меня - использование встроенного SVG.
<a href="#">
<svg class="logo" width="115" height="47" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(-5 -5)" fill="none" fill-rule="evenodd">
<rect fill="#D8D8D8" transform="rotate(45 28.5 28.5)" x="9" y="9" width="39" height="39" rx="11" />
<text font-family="Rubik-Medium, Rubik" font-size="25" font-weight="400" fill="#6F6F6F">
<tspan x="63.923" y="36.923">Rect</tspan>
</text>
</g>
</svg>
</a>
.logo rect,
.logo text {
transition: 0.3s ease-out;
}
.logo:hover rect,
.logo:hover text {
fill: #4a7def;
}
Адаптивный логотип
Это напоминает мне логотип Smashing Magazine. Мне нравится, что это изменяется от маленького символа до полного логотипа. Смотрите макет ниже:
Идеальным решением для этого является элемент picture
, куда можно добавить две версии логотипа. См. ниже:
<a class="logo" href="/">
<picture>
<source media="(min-width: 1350px)" srcset="sm-logo--full.svg"><img src="sm-logo.svg" alt="Smashing Magazine"></picture>
</a>
А в CSS нам нужно изменить ширину в области просмотра, равную или большую, чем 1350px
.
.logo {
display: inline-block;
width: 45px;
}
@media (min-width: 1350px) {
.logo {
width: 180px;
}
}
Простое и понятное решение.
Логотип с градиентом
Когда есть логотип с градиентом, процесс его экспорта из дизайнерского приложения, такого как Illustrator или Sketch, может быть не идеальным, а иногда он ломается.
С SVG мы можем легко добавить градиент к логотипу. Я добавил linearGradient
и применил его fill
к тексту.
<svg class="logo" width="115" height="47" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="gradient" x1="0%" y1="100%" x2="0%" y2="0%">
<stop offset="0%" stop-color="#4a7def"></stop>
<stop offset="50%" stop-color="#ab4787"></stop>
</linearGradient>
</defs>
<g transform="translate(-5 -5)" fill="none" fill-rule="evenodd">
<rect fill="#AB4787" transform="rotate(45 28.5 28.5)" x="9" y="9" width="39" height="39" rx="11" />
<text font-family="Rubik-Medium, Rubik" font-size="30" font-weight="400" fill="url(#gradient)">
<tspan x="63.923" y="36.923">Rect</tspan>
</text>
</g>
</svg>
Аватар пользователя
Для аватара пользователя они имеют много форм, но наиболее распространенными являются прямоугольные или округлые. В этом сценарии использования мне интересно объяснить важный совет, который может оказаться полезным.
Во-первых, давайте посмотрим на макет ниже. Обратите внимание, что у нас есть идеальные аватары, и они на 100% прозрачны.
Однако, когда пользователь загружает полубелый аватар или очень легкий аватар, этот дизайн потерпит неудачу.
Обратите внимание на макет выше, не ясно, что там есть круг, пока вы не очень хорошо сфокусировались. Это проблема. Чтобы это исправить, мы должны добавить границу внутри аватара, которая будет использоваться в качестве запасного варианта, если изображение слишком светлое.
У нас есть несколько вариантов сделать это:
- элемент
img
- С
img
аdiv
- А
div
с CSS фоном - SVG
image
Какой из них лучший? Давайте исследуем.
Использование HTML img
Первое, о чем вы могли подумать, это добавить границу, верно? Давайте исследуем это (извините, вы можете часто видеть мое лицо в следующих разделах).
.avatar {
border: 2px solid #f2f2f2;
}
Наша цель - создать внутреннюю границу, которая гармонирует с изображением. Наличие прочной границы не практично.
Использование HTML img с div
Проблема в том, что для добавления внутренней границы мы не можем использовать вставку, так box-shadow
как она не будет работать с изображением. Решение состоит в том, чтобы обернуть аватар в a div
и добавить элемент, который выделен для внутренней границы.
<div class="avatar-wrapper">
<img class="avatar" src="shadeed2.jpg" alt="A photo of Ahmad Shadeed">
<div class="avatar-border"></div>
</div>
.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);
}
Имея границу div
с 10% черного цвета, мы можем гарантировать, что граница будет сливаться с темным изображением и будет видна только в том случае, если изображение светлое. Смотрите макет ниже:
А div с CSS фоном
Если я буду использовать div
для отображения аватара, это, вероятно, означает, что изображение является декоративным. Я вспомнил случай использования этого, который представляет собой случайные аватары, разбросанные по странице.
У нас может быть что-то вроде этого:
<div class="avatar" style="--img-url: url(shadeed2.jpg)"></div>
.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);
}
SVG image
Это самое интересное решение для меня. Я заметил это во время проверки нового дизайна Facebook .
<svg role="none" style="height: 36px; width: 36px;">
<mask id="avatar">
<circle cx="18" cy="18" fill="white" r="18"></circle>
</mask>
<g mask="url(#avatar)">
<image x="0" y="0" height="100%" preserveAspectRatio="xMidYMid slice" width="100%" xlink:href="avatar.jpg" style="height: 36px; width: 36px;"></image>
<circle cx="18" cy="18" r="18"></circle>
</g>
</svg>
Позвольте мне сначала разобрать его, он содержит следующее:
- Маска для обрезки изображения в виде круга
- Группа, к которой применена маска
- Само изображение с
preserveAspectRatio="xMidYMid"
- Круг, который будет использоваться для внутренней границы
В CSS у нас будет следующее:
circle {
stroke-width: 2;
stroke: rgba(0, 0, 0, 0.1);
fill: none;
}
Это все, что касается использования аватара пользователя.
Вход со значком
Распространено видеть вход со значком, Как добавить это? Что происходит, когда ввод сфокусирован? Давайте исследуем это.
<p>
<label for="name">Full name</label>
<input type="text" id="name">
</p>
Для меня лучшее решение для этого случая - CSS фоновые изображения. Это просто, быстро и не требует добавления дополнительных элементов.
input {
background-color: #fff;
background-image: url('user.svg');
background-size: 20px 20px;
background-position: left 10px center;
background-repeat: no-repeat;
}
А чтобы изменить цвет значка на фокусе, мы можем использовать SVG-кодировку с URL-адресами и сделать это легко. Этот инструмент от Yoksel великолепен.
CSS печать
Пользователю может потребоваться распечатать веб-страницу. Скажем, у нас есть рецепт, и вы хотите распечатать его, чтобы вы могли посмотреть его на кухне без проверки вашего телефона или компьютера.
Для рецепта, содержащего иллюстративные шаги, важно показать их в печати, иначе пользователь не получит никакой выгоды от печати веб-страницы.
Избегайте включения изображений в качестве фона CSS
Когда изображение включено в качестве фона CSS, оно не будет напечатано и вместо него появится пустое место. Смотрите рисунок ниже:
Вот что происходит. Мы можем решить эту проблему, заставив браузер показывать изображение, хотя это не работает для Firefox и IE.
.element {
background: url('cheesecake.png') center/cover no-repeat;
-webkit-print-color-adjust: exact; /* Force the browser to render the background in print mode */
}
Однако безопаснее использовать HTML, img
поскольку он будет печатать без проблем.