Веб и разработка / CLEARBYTE

Адаптивные изображения: как работают srcset, sizes и DPR

srcset перечисляет доступные файлы изображения. При дескрипторах ширины sizes описывает ожидаемый размер изображения в CSS-пикселях. Браузер учитывает его, плотность пикселей и собственную политику выбора ресурса. Фактическое расположение и размер элемента по-прежнему задаёт CSS.

В этом руководстве

Картинка может выглядеть правильно, но загружать гораздо больше пикселей, чем использует вёрстка. Обратная проблема — небольшой файл, растянутый на экране высокой плотности. Адаптивная разметка связывает подготовленные файлы с местом изображения на странице. Она полезна, когда размеры файлов и описание вёрстки согласованы.

Начните с одного настоящего компонента и нескольких разумных размеров. В примере ширина области ограничена 800 CSS-пикселями, а на узком экране с каждой стороны оставлено по 16 пикселей. Все файлы содержат одинаковую композицию с соотношением сторон 4:3.

Различайте пиксели файла, CSS-пиксели и DPR

Файл шириной 800 пикселей не обязан занимать столько же CSS-пикселей. Его можно показать в области шириной 400 CSS-пикселей. При DPR 2 это соответствует примерно 800 физическим пикселям по горизонтали. Такая связь помогает планировать разрешение, но не заставляет браузер выбирать единственный конкретный файл.

Сначала вычислите ширину области: меньшее из 800 и ширины окна за вычетом 32 пикселей. Затем умножьте её на DPR, чтобы получить целевую ширину исходника. Умножать всю ширину окна неверно, если изображение находится только в узкой колонке.

Расчёт для колонки с максимальной шириной 800 CSS-пикселей
Ширина окнаОбласть в CSS-пикселяхDPRЦелевая ширина файла
3923601360 пикселей
3923602720 пикселей
10248001800 пикселей
102480021600 пикселей

Используйте дескрипторы ширины для меняющейся вёрстки

Дескриптор w обозначает настоящую ширину файла в пикселях. Это не контрольная точка адаптивной вёрстки: значение должно совпадать с размерами ресурса. sizes сообщает ожидаемую ширину изображения. В разметке ниже при окне от 832 CSS-пикселей используется область 800 пикселей, а на узком экране — ширина окна минус наружные отступы.

CSS в примере является частью решения. Если компонент перенесут в половину сетки, sizes нужно изменить вместе с вёрсткой. Устаревшее описание на полную ширину может приводить к загрузке слишком большого файла. Правильный атрибут описывает реальный блок, а не просто перечисляет популярные экраны.

<img
  src="/images/workspace-800.webp"
  srcset="/images/workspace-400.webp 400w,
          /images/workspace-800.webp 800w,
          /images/workspace-1600.webp 1600w"
  sizes="(min-width: 832px) 800px, calc(100vw - 32px)"
  width="1600" height="1200"
  alt="A desk with a monitor and an open notebook"
  style="display:block;width:calc(100vw - 32px);max-width:800px;height:auto;margin-inline:auto"
>

Сначала рассчитайте ожидаемый вариант, затем проверьте выбор

При ширине окна 392 и DPR 2 область занимает 360 CSS-пикселей, целевой исходник — 720 пикселей. Из предложенного набора разумно ожидать вариант 800w. Для широкой колонки при DPR 2 целевой размер составляет 1600 пикселей. Эти вычисления объясняют входные данные алгоритма браузера, но не служат принудительной командой загрузки.

Браузер учитывает дополнительные факторы и может сохранить уже загруженную большую картинку после уменьшения окна. Для чистой проверки сначала выберите параметры устройства и выполните свежую загрузку страницы. Сопоставьте выбранный URL и переданные байты в инструментах разработчика. Одно последовательное изменение размеров прогретой страницы может ввести в заблуждение.

Набор вариантов требует настоящей подготовки файлов шириной 400, 800 и 1600 пикселей. Проверьте качество и ответы по каждому URL. Нельзя скопировать один большой файл под разными именами и обозначить копии разными значениями w.

  • Измерьте ширину самого элемента, не предполагая равенства ширине окна.
  • Сравните URL currentSrc с ответом изображения в панели Network.
  • Проверьте размеры файла, тип ответа, состояние кеша и переданные байты.
  • Повторите проверку на узком и широком экране при DPR 1 и DPR 2.
  • Проверьте горизонтальную прокрутку и смещения блоков до и после загрузки изображения.

Дескрипторы плотности подходят фиксированному размеру

Для небольшого логотипа неизменной ширины можно использовать дескрипторы x. Если элемент занимает 120 CSS-пикселей, подготовьте файл шириной 120 для 1x и 240 для 2x. Они описывают разные разрешения одного размера отображения. В одном srcset не смешивают дескрипторы x и w.

Различающееся кадрирование — отдельная задача. Если на телефоне нужен крупный план лица, а на компьютере общий вид, используйте picture с подходящими условиями media у source. В основном примере этого руководства композиция одинакова и меняется только разрешение. Альтернативный текст должен передавать значимое содержимое картинки.

<img src="/images/mark-120.png"
     srcset="/images/mark-120.png 1x, /images/mark-240.png 2x"
     width="120" height="120" alt="Example project mark">

Учитывайте соотношение сторон и момент загрузки

Атрибуты width и height позволяют заранее зарезервировать место по соотношению сторон. Они не запрещают CSS менять размеры адаптивного изображения. В примере 4:3 ширине 800 соответствует высота 600, а ширине 360 — высота 270 пикселей. Это помогает избежать скачка вёрстки после получения файла.

Отложенная загрузка полезна для изображений ниже по странице. Однако важную картинку, которую читатель видит сразу, не следует бездумно задерживать. Выбирайте стратегию по месту компонента. Адаптивные варианты уменьшают избыток пикселей; сжатие, формат и приоритет загрузки решают другие части задачи.

Размер файла в сети и память после декодирования различаются. Сжатый WebP может занимать мало байтов при передаче, но разворачиваться в большой пиксельный буфер. Калькулятор памяти использует размеры декодированного изображения, а вес сжатого файла нужно измерять отдельно.

Проверка компонента перед публикацией

Храните правило вёрстки и правило подготовки файлов как единый договор компонента. Вместе задавайте ширины кандидатов, кадрирование, пропорции, качество и sizes. Например, переход с максимальной ширины 800 на 1000 пикселей требует заново оценить набор исходников.

Перед выпуском проверьте резервный src, все URL из srcset, осмысленный альтернативный текст и зарезервированное место. Калькулятор CSS-пикселей и DPR позволяет повторить расчёт под свою область, а калькулятор пропорций — получить нужную высоту. Итогом должен быть компонент, у которого файлы соответствуют фактической вёрстке на разных устройствах.

Частые вопросы

Меняет ли sizes ширину изображения в CSS?

Нет. При дескрипторах ширины он описывает ожидаемую область для выбора файла. Реальные размеры задаёт CSS. Эти два описания должны соответствовать друг другу.

Почему после уменьшения окна остался большой файл?

Браузер может повторно использовать уже загруженное изображение. Проверьте свежую загрузку с нужной шириной и DPR, затем выбранный ресурс и передачу данных. Одного изменения размера окна недостаточно.

Файл для 2x всегда весит вдвое больше?

Нет. Удвоение обоих измерений увеличивает число пикселей вчетверо, но вес зависит также от содержимого, формата и качества сжатия. Измеряйте подготовленные файлы.

Источники и определения

Метод проверен: