Независимо от того, как долго вы изучаете веб-дизайн и веб-разработку, элемент <img> не нуждается в особом представлении. Запущенный в Netscape (тогда он ещё назывался Mosaic) в 1993 году и добавленный в спецификацию HTML в 1995 году, <img> долгое время играл простую, но важную роль на сайтах. Разработчик добавляет «исходный» файл изображения с помощью атрибута src и предоставляет текстовую альтернативу через атрибут alt на случай, если изображение невозможно отобразить или вспомогательные технологии запрашивают альтернативу. Дальше у браузера остаётся только одна задача: получить данные изображения, а затем отобразить их как можно быстрее.
<img
src="image/aquilegia.jpg"
alt="Белая аквилегия">
На протяжении большей части истории веб-разработки работа с изображениями не сильно усложнилась. Несмотря на всю сложность современного веба, основы работы с изображениями не поменялись: используйте подходящий формат изображения для совместимости; разумное сжатие для экономии полосы пропускания; размеры, соответствующие месту, которое изображение будет занимать в макете страницы.
Использование макетов с фиксированной шириной, как это было в те времена, когда мы думали, что имеем больше прав на то, как пользователи воспринимают веб-страницы, сделало такой процесс несложным. Особенно легко было задать размер исходного изображения. Для изображения, занимающего ширину 550 и высоту 300 пикселей, достаточно было указать исходное изображение такого же размера.
Изображения в адаптивном макете
Наряду с гибким макетом и использованием медиа-запросов, «гибкие изображения и медиа» являются одним из трёх определяющих аспектов адаптивного веб-дизайна. Чтобы сделать изображение гибким, разработчики начали использовать CSS и устанавливать max-width: 100% для конкретного изображения (или всех изображений на сайте). Тем самым указывая браузеру, что изображение никогда не превысит родительский контейнер при уменьшении масштаба. Визуально это работает идеально — уменьшение растрового изображения происходит незаметно. С помощью пары строк CSS уменьшенное изображение всегда будет выглядеть так, будто мы указали источник изображения, предназначенный для отображения в таком размере. Когда механизмам отображения предоставляется больше данных об изображении, чем необходимо для пространства, занимаемого изображением в макете, они могут принимать обоснованное решение о том, как отобразить уменьшенное изображение, и делать это без каких-либо визуальных артефактов или размытия.
<style>
.scaleup {
width: 200px;
}
</style>
<h1>Масштабирование изображения</h1>
<p>Уменьшенное изображение по-прежнему выглядит чётким.</p>
<h2>Исходный размер</h2>
<img src="image/pansies-sm.jpg" alt="Белые и жёлтые анютины глазки.">
<h2>Половинный размер</h2>
<img src="image/pansies-sm.jpg" alt="Белые и жёлтые анютины глазки." class="scaleup">
Обычно вам не требуется увеличивать масштаб изображения, то есть отображать <img> в размере, превышающем собственный размер исходного изображения. Отображаемое изображение будет выглядеть размытым и зернистым.
<style>
.scaleup {
width: 800px;
}
</style>
<h1>Масштабирование изображения</h1>
<p>Увеличенное изображение выглядит размытым и зернистым.</p>
<h2>Исходный размер</h2>
<img src="image/pansies-sm.jpg" alt="Белые и жёлтые анютины глазки.">
<h2>Двойной размер</h2>
<img src="image/pansies-sm.jpg" alt="Белые и жёлтые анютины глазки." class="scaleup">
Использование img { max-width: 100% } означает, что при изменении размеров гибкого контейнера изображения будут соответствующим образом уменьшены. В отличие от более жёсткого значения width: 100%, это также гарантирует, что изображение не будет масштабироваться выше своего размера. Долгое время правила работы с изображениями были таковы: используйте формат, понятный браузерам, используйте разумный уровень сжатия и никогда не масштабируйте изображения в большую сторону.
<style>
img {
max-width: 100%;
}
</style>
<img
src="image/aquilegia.jpg"
alt="Белая аквилегия">
Но каким бы простым и эффективным ни был этот подход визуально, он стоил огромных потерь в производительности. Поскольку <img> поддерживал только один источник данных, этот подход требовал от нас предоставления ресурса изображения с размером, равным наибольшему размеру, при котором оно могло отображаться. Изображение, которое должно было занимать место в макете шириной от 300 до 2000 пикселей, в зависимости от размера области просмотра пользователя, требовало источника изображения с собственной шириной не менее 2000 пикселей. Для пользователя, который просматривает страницу только через небольшую область просмотра, все будет выглядеть как и ожидалось — изображение прекрасно масштабируется. На обработанной странице массивное, но уменьшенное исходное изображение не будет отличаться от изображения подходящего размера. Тем не менее, они по-прежнему будут передавать и отображать изображение шириной 2000 пикселей, используя огромную пропускную способность и вычислительную мощность без какой-либо ощутимой выгоды.
Ситуация значительно ухудшилась с появлением первых устройств с дисплеями Retina, так как плотность отображения стала проблемой наряду с размером области просмотра. Для того чтобы изображение подходило для дисплея с высокой плотностью, ему требуется большая собственная ширина. Проще говоря, дисплей с удвоенной плотностью требует в два раза больше пикселей для максимально чёткого отображения изображения.
Здесь разработчики снова смогли положиться на способность механизма отображения визуально уменьшать масштаб изображений. Предоставив браузеру исходное изображение шириной 800px в атрибуте src, а затем указав в CSS, что оно должно отображаться шириной 400px, вы получаете изображение, отображаемое с удвоенной плотностью пикселей:
<style>
.scaledown {
width: 400px;
}
</style>
<h1>Уменьшение размера изображения для дисплеев высокой плотности</h1>
<p>На дисплее высокой плотности изображение исходного размера (здесь ширина <code>800 пикселей</code>), будет выглядеть слегка зернистым. Уменьшив его до 50%, то же изображение будет выглядеть намного чётче.</p>
<h2>Исходный размер</h2>
<img src="image/geranium-sylvaticum.jpg" alt="Герань лесная">
<h2>Уменьшено до 50%</h2>
<img src="image/geranium-sylvaticum.jpg" alt="Герань лесная" class="scaledown">
Одно исходное изображение, обрезанное так, чтобы оно занимало как можно больше места в макете и на дисплеях высокой плотности, конечно, визуально подходит для всех пользователей. Огромное изображение с высоким разрешением, выведенное на маленький дисплей с низкой плотностью, будет выглядеть как любое другое маленькое изображение с низкой плотностью, но работать станет гораздо медленнее. Пользователь будет вынужден нести все издержки производительности этого огромного источника изображения шириной 4000px, не получая от этого никакой выгоды.
Долгое время <img> в основном выполнял одну задачу — «получал данные изображения и выводил их на экран». Конечно, он справлялся с этим достаточно хорошо, но <img> не смог приспособиться к радикальным изменениям в контексте просмотра, с которыми мы столкнулись. В то время как адаптивный веб-дизайн стал основной практикой разработки, браузеры оптимизировали производительность <img> почти двадцать лет, но для всех, кроме самых привилегированных пользователей, содержание изображений на страницах было неэффективным с самого начала. Независимо от того, насколько быстро браузеру удалось запросить, проанализировать и отобразить исходное изображения, запрашиваемый ресурс, скорее всего, будет гораздо больше, чем нужно пользователю.