Атрибут sizes в HTML: что это и как его записать

Атрибут sizes (от английского sizes, «размеры») сообщает браузеру, какую ширину картинка займёт на странице. Закрывающей части у него нет, он записывается внутри открывающего тега: sizes="50vw". Закрывающий тег нужен самому элементу не всегда: у <img> и <source> его нет. Работает атрибут только вместе с srcset, в котором файлы описаны дескриптором w.

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

HTML
<img src="cat-640.jpg"
  srcset="cat-640.jpg 640w, cat-1280.jpg 1280w"
  sizes="(min-width: 800px) 50vw, 100vw"
  alt="Кот на подоконнике">

Что такое атрибут sizes в HTML и зачем он нужен

Список файлов в srcset с дескрипторами w говорит только о том, какой ширины каждый файл. Чтобы выбрать из них один, браузер должен знать вторую величину: сколько пикселей картинка займёт на странице. Её он умножает на плотность пикселей экрана и берёт наименьший файл, которого хватает. Эту вторую величину и записывают в sizes.

Важно, чем sizes не является. Он не задаёт размер картинки: размер по-прежнему задают стили и атрибуты width и height. sizes только описывает этот размер браузеру заранее, поэтому его значение нужно согласовывать с вёрсткой самому. Если файлы описаны дескрипторами x, атрибут не нужен вовсе.

  • Без srcset с дескрипторами w атрибут sizes ничего не делает: остаётся адрес из src.
  • Без самого sizes браузер считает, что картинка занимает всю ширину окна, как при 100vw.
  • Прочитать записанное значение из скрипта можно через свойство img.sizes.

Для каких тегов работает sizes: img и source

Атрибут есть у двух тегов. Смысл у него один, но роль в разметке разная.

Теги, у которых работает sizes
ТегЧто делает sizesПример записи
<img>Описывает ширину самой картинки на странице<img srcset="a.jpg 640w, b.jpg 1280w" sizes="100vw" alt="Кот">
<source> внутри <picture>Описывает ширину картинки для одного условия: окна определённой ширины или формата<source srcset="a.webp 640w, b.webp 1280w" sizes="50vw">

Для предварительной загрузки картинки через link есть отдельный атрибут imagesizes, он разобран в этой же группе справочника чуть позже.

Как записать sizes: условия, ширина слота и запятые

Значение sizes это список через запятую. Каждый элемент включает необязательное условие в скобках и ширину, которую назовём слотом. Последний элемент обычно пишут без условия: он работает как запасной.

Устройство записи sizes
ЧастьЧто этоПример записи
УсловиеУсловие media в скобках, как в CSS(min-width: 800px)
СлотШирина картинки: число с единицей, vw или calc()50vw
Элемент спискаУсловие и слот через пробел(min-width: 800px) 50vw
Запасной элементСлот без условия, записывается последним100vw
РазделительЗапятая между элементами(min-width: 800px) 50vw, 100vw

Браузер читает список слева направо и берёт первый элемент, условие которого выполнено. Остальные он уже не смотрит. Если не подошло ни одно условие и запасного нет, берётся 100vw. В браузере, на котором я проверял, список (min-width: 600px) 300px на окне шириной 400 дал слот 400.

HTML
sizes="(min-width: 1200px) 600px,
       (min-width: 800px) 50vw,
       100vw"

Какие значения и единицы допустимы: vw, px, em и calc()

Слот записывают числом с единицей длины, как в CSS. Ниже результаты для файлов шириной 320, 640, 960 и 1280 пикселей на окне 800 при плотности 1.

Что делает браузер с разными слотами
ЗаписьСлот в пикселяхВыбранный файл
50vw400640
400px400640
20em320 (em равен 16 пикселям)320
20rem320320
100vh600 (высота окна)640
calc(100vw - 100px)700960
calc(50vw + 20px)420640
00320, наименьший из списка

Часть записей браузер отбрасывает и считает, что sizes записан неправильно. Тогда он берёт слот 100vw, то есть всю ширину окна, и выбирает самый большой файл.

Какие записи браузер отбрасывает
ЗаписьЧто показал браузерПример записи
ПроцентыОтброшено: слот 100vw, файл 960sizes="50%"
Отрицательная ширинаОтброшеноsizes="-100px"
Число без единицыОтброшено, кроме нуляsizes="300"
Проценты в calc()Отброшеноsizes="calc(100% - 40px)"
Пустое значениеОтброшено, валидатор показывает ошибкуsizes=""
Произвольный текстОтброшеноsizes="garbage"

Проценты стандарт не допускает: вместо них берут vw и calc(). Проверку записи делает валидатор: сообщение о пустом значении разобрано на странице Rocket Validator. Регистр единиц не важен: 100VW работает.

Пример: как браузер читает значение sizes

Выберите значение или впишите своё. Окно демонстрации узкое, поэтому слоты небольшие. Строка «Нужно пикселей» показывает слот, умноженный на плотность вашего экрана.

Результат

Файл выбирает ваш браузер, результат может отличаться от моих замеров. Единица vw считается от ширины окна самой демонстрации.

Условия media в sizes: ширина окна, ориентация и плотность

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

Результаты при дескрипторах 320w, 640w, 960w и 1280w
Окно и плотностьЗапись sizesСлотВыбранный файл
800, 1(min-width: 600px) 300px, 100vw300320
800, 1(max-width: 500px) 100vw, 300px300 (первое условие не выполнено)320
800, 1(min-width: 600px) 300px, (min-width: 300px) 500px, 100vw300 (первое подходящее)320
800, 1(min-width: 300px) 500px, (min-width: 600px) 300px500 (порядок изменил результат)640
800, 1100vw, 200px800 (запасной элемент записан первым)960
800, 1(orientation: landscape) 200px, 100vw200320
800, 1(min-resolution: 2dppx) 200px, 100vw800 (условие не выполнено)960
800, 2(min-width: 600px) 300px, 100vw300, нужно 600 пикселей640

Две строки таблицы нужно запомнить. Порядок важен: условие с меньшим порогом, записанное раньше, перекрывает более строгое после него. А элемент без условия работает только последним: если поставить его первым, остальные не сработают никогда.

HTML
sizes="(min-width: 1200px) 600px,
       (min-width: 800px) 50vw,
       100vw"

Пример: какое условие в sizes сработает

В демонстрации слоты записаны в пикселях, а файлы имеют ширину 150, 300, 600 и 1200. Строка «Сработал вариант» показывает, какой элемент списка сработал в вашем окне.

Результат

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

Как подобрать sizes под реальную ширину картинки

Значение sizes должно повторять вёрстку: сколько пикселей картинка занимает в каждом состоянии окна. Если записать неверное число, браузер доверится ему, а не реальной ширине, и выберет не тот файл. Типовые случаи собраны в таблице.

Как записать sizes для типовой вёрстки
Как картинка расположенаЗапись sizesПример записи
На всю ширину окнаВсё окноsizes="100vw"
В две колонки поровнуПоловина окнаsizes="50vw"
Колонка с отступами 20 пикселей по бокамОкно без отступовsizes="calc(100vw - 40px)"
Контейнер шириной 800 по центру, на узком окне отступы 20 пикселейДве ступениsizes="(min-width: 840px) 800px, calc(100vw - 40px)"
Миниатюра фиксированной шириныПикселиsizes="120px"

Практический путь такой: сначала сверстать картинку, затем записать sizes по получившейся ширине в нескольких состояниях окна. Для контроля прочитайте img.currentSrc и сравните выбранный файл с ожидаемым. Если файл оказывается слишком большим, проверьте, не пропущено ли условие для нужной ширины окна. Подробный разбор расчёта есть в серии статей Cloud Four о responsive images.

HTML
<style>
  .page { max-width: 800px; margin: 0 auto; padding: 0 20px; }
  img { max-width: 100%; height: auto; }
</style>

<img srcset="a-640.jpg 640w, a-1280.jpg 1280w"
  sizes="(min-width: 840px) 800px, calc(100vw - 40px)"
  width="800" height="600" alt="Кот">

Sizes="auto" и loading="lazy": ширина из вёрстки

Для картинок с отложенной загрузкой атрибута loading="lazy" есть особое значение sizes="auto". Браузер подставляет реальную ширину картинки из вёрстки, и вручную считать слот не нужно. Работает оно только у ленивых картинок: файл у них загружается позже, когда ширина уже известна.

Что показал браузер при sizes="auto"
ЗаписьЧто получилосьПример записи
auto с loading="lazy", ширина 300 из атрибутаСлот 300, файл 320<img loading="lazy" sizes="auto" width="300" ...>
auto с loading="lazy", ширина 150 из CSSСлот 150, файл 320style="width:150px"
auto, 100vw с loading="lazy", ширина 500 из CSSСлот 500, файл 640sizes="auto, 100vw"
auto без loading="lazy"Значение отброшено, слот 100vw, файл 960sizes="auto"

Это новая возможность, и не все программы её знают. Если значение не поддерживается, браузер поступит как с неверной записью и возьмёт 100vw. Поэтому на важных страницах auto лучше проверять в своём браузере, как в демонстрации ниже. Подробнее о самом атрибуте loading расскажет отдельная страница справочника.

HTML
<img src="cat-640.jpg"
  srcset="cat-640.jpg 640w, cat-1280.jpg 1280w"
  sizes="auto"
  loading="lazy"
  width="300" height="200" alt="Кот">

Пример: sizes="auto" у ленивой и обычной картинки

В демонстрации четыре файла шириной 100, 200, 400 и 800 пикселей. Сравните, как выбор зависит от ширины картинки и от атрибута loading.

Результат

Если ваш браузер значение auto не поддерживает, во всех вариантах выбор будет как при 100vw.

Sizes у source и у img внутри picture

Внутри <picture> у каждого <source> может быть свой sizes. Он действует только на тот srcset, рядом с которым записан. Атрибут sizes у самого img работает, лишь когда браузер выбрал его, то есть ни один source не подошёл.

HTML
<picture>
  <source media="(min-width: 700px)"
    srcset="wide-320.jpg 320w, wide-960.jpg 960w"
    sizes="300px">
  <img src="cat-640.jpg" alt="Кот">
</picture>

В браузере, на котором я проверял, при окне 800 сработал source и слот 300 дал файл шириной 320. Когда я записал sizes только у img, а source подошёл, значение было проигнорировано и слот стал равен 100vw.

Частые ошибки в атрибуте sizes

Большинство ошибок связано с тем, что sizes принимают за размер картинки, а не за подсказку, или записывают значения, которые браузер молча отбрасывает.

ОшибкаЧто происходитКак исправить
sizes без srcsetНичего не меняется, остаётся адрес из srcДобавить srcset с дескрипторами w
sizes с дескрипторами xАтрибут игнорируется, валидатор показывает ошибкуПерейти на дескрипторы w или убрать sizes
sizes="50%"Проценты отбрасываются, слот становится 100vwПисать 50vw
sizes="300"Число без единицы отбрасываетсяДописать единицу: 300px
sizes=""Пустое значение отбрасывается, валидатор показывает ошибкуЗаписать слот или убрать атрибут
calc(100% - 40px)Проценты в calc() отбрасываютсяИспользовать calc(100vw - 40px)
sizes="100vw, (min-width: 800px) 50vw"Первый элемент без условия перекрывает остальныеЗапасной слот записывать последним
(min-width: 300px) 500px, (min-width: 600px) 300pxПорог 300 срабатывает раньше, до порога 600 дело не доходитСначала записывать самое строгое условие
Условие без запасного слотаЕсли условие не выполнено, берётся 100vwДописать запасной слот в конце
sizes="100vw" для узкой колонкиБраузер выбирает лишний большой файлЗаписать реальную ширину колонки
sizes="auto" без loading="lazy"Значение отбрасывается, слот 100vwДобавить loading="lazy" или записать слот
sizes у img внутри picture, когда подошёл sourceЗначение игнорируетсяЗаписать sizes у нужного source

Шпаргалка по атрибуту sizes

Всё главное из статьи в одной таблице.

Атрибут sizes: что и как писать
ЗадачаКак записатьПример записи
Картинка на всю ширину окнаСлот 100vwsizes="100vw"
Картинка в половину окнаСлот 50vwsizes="50vw"
Колонка с отступамиcalc() с vwsizes="calc(100vw - 40px)"
Другой слот на широком окнеУсловие и запасной слотsizes="(min-width: 800px) 50vw, 100vw"
Фиксированная ширинаПикселиsizes="300px"
Ширина из вёрсткиauto и loading="lazy"<img sizes="auto" loading="lazy" ...>
Другой слот для sourcesizes у source<source srcset="..." sizes="300px">
Нельзя в sizesПроценты, числа без единицы, пустое значениеsizes="50%"
Проверить результатСвойство currentSrcimg.currentSrc
Категория
Поделиться в социальных сетях

Отправить комментарий

0 Комментарии

Отправить комментарий (0)

#buttons=(Хорошо) #days=(20)

Мы используем файлы cookie для улучшения работы сайта. Подробнее
Хорошо
×