Картинки: место заранее, alt и щель под строчной картинкой
Здесь будет встроен видео-разбор темы (5–7 минут, YouTube / RuTube / VK Видео) — тем, кто лучше воспринимает на слух, текст ниже не обязателен.
Страница открылась, вы начали читать — и абзац уехал вниз, потому что над ним догрузилась картинка. Знакомая ситуация: палец уже нажал ссылку, а под ним оказался другой текст. Браузер здесь не виноват. Размер картинки записан в её файле, а файл приходит позже разметки, и до его прихода браузер не знает, сколько места оставить. Разберём, что происходит с коробкой картинки, файла которой ещё нет, как двумя атрибутами отложить под неё место, что писать в alt — и откуда под картинкой берётся щель, которую никто не задавал.
Разметка приходит первой, картинки — следом, каждая отдельным запросом, и на медленной сети между ними проходят секунды. Браузер не ждёт: он показывает текст сразу, а картинки вставляет по мере прихода. Сколько места оставить под картинку, файл которой ещё в пути? Размер записан в самом файле, и если разметка о нём молчит — нисколько. Файл пришёл, коробка выросла, и всё, что ниже, съехало. Человек в этот момент дочитывал абзац или тянулся пальцем к кнопке, а попал в соседнюю.
Проверим на примере. В песочнице файлу неоткуда прийти, поэтому у картинок вовсе нет адреса src — и для коробки это ровно то же состояние, что и файл в пути: браузер строит её, ничего не зная о размере. Ниже две карточки шириной 200 пикселей, в каждой картинка и подпись. У первой картинки есть атрибуты width="400" и height="300" — размер её файла в пикселях, у второй их нет. Зачем обеим пустой alt="", станет ясно в разделе про alt.
<style> здесь уже не только для вида, поэтому прочитаем его. Правило стиля начинается с адреса элементов — такого же, как в вызовах прибора, — а за ним в фигурных скобках идут пары «свойство: значение». .box { width: 200px; } даёт элементам с классом box ширину 200 пикселей: точка в адресе означает класс. Правило для img растягивает картинку на всю ширину карточки (width: 100%), высоту оставляет вычислить браузеру (height: auto) и ставит картинку отдельной полосой (display: block — зачем, покажет раздел о щели). Язык стилей целиком разбирает вторая глава пролога.
Замер отвечает числом по каждому найденному элементу, в порядке разметки: height — высота, y — расстояние от верхнего края области, куда легла разметка. Прогноз: какой высоты окажутся две картинки и как высоко встанут обе подписи? Все числа назовёт разбор под примером — строка вывода в этой статье спрятана, ответ читается там.
aspect-ratio: у первой картинки он стал auto 400 / 300, у второй остался auto, то есть «узнаю из файла».Сдвиг вёрстки измеряют: в Lighthouse и в отчётах Google о скорости сайта он называется CLS, и картинки без размеров — одна из частых его причин.
Отсюда привычка, которая закрывает тему сдвигов: у каждой картинки в разметке стоят width и height — настоящие размеры файла, — а то, какого она будет размера на экране, решает стиль. Две строки в таблице стилей, max-width: 100% и height: auto, есть почти в любом современном сбросе именно поэтому. Записанные в атрибуты числа при этом не мешают: они дают пропорцию, а масштаб берёт на себя стиль.
Атрибуты width и height браузер превращает в свойство стиля — aspect-ratio, «соотношение сторон». В <style> примера такого свойства нет, и всё же третья строка разбора его показывает: у картинки с атрибутами там пропорция парой чисел, у картинки без них — просто auto, то есть «узнаю из файла».
Слово auto перед парой чисел — оговорка: «пока файла нет, держи 400 к 300, а когда он придёт, возьми пропорции самого файла». Поэтому в атрибуты пишут настоящий размер файла. Ошибётесь — прыжок всё равно случится, только позже: место отложено под 4 : 3, а пришёл, скажем, квадрат, и коробка вытянется до 200 на 200.
Без всякого стиля атрибуты задают и сам размер: <img width="200" height="150"> займёт 200 на 150 пикселей. Но колонка на телефоне бывает уже картинки, поэтому ширину обычно отдают стилю — и тут легко попасть в ловушку. Ниже у обеих картинок width: 100%, а height: auto есть только у второй: его даёт класс fit. Прогноз для двух строк разбора: какой ширины и какой высоты окажется каждая картинка?
width: 100% перебило ширину, высоту никто не трогал. Файл 400 на 300, когда придёт, сожмётся по ширине вдвое, в коробку 200 на 300. У второй картинки height: auto отменил высоту из атрибута, и в дело вступила пропорция — 150.Атрибуты width и height работают как самый слабый стиль: любое правило CSS их перебивает, но только в том свойстве, которое в правиле названо. А height: auto отменяет высоту из атрибута — и в дело вступает пропорция.
Поэтому в стилях почти любого сайта для картинок стоят две строки: ширина не больше колонки и height: auto. Вместо width: 100% там часто пишут max-width: 100% — «не шире родителя»: большая картинка сжимается до колонки, а маленькая остаётся своего размера и не расплывается. Разницу проверите в третьей задаче.
Соотношение сторон можно задать и самому, без атрибутов, — например, рамке под видео: aspect-ratio: 16 / 9. У свойства статус Baseline Widely available с 20 марта 2024 года — пишите. А узнать из скрипта, что файл картинки наконец пришёл, можно по событию load: его разбирает часть II в статье про порядок загрузки страницы.
Картинку видят не все. Программа чтения с экрана произносит вместо неё текст из alt. Тот же текст браузер показывает на месте картинки, файл которой получить не удалось, а поисковик по нему понимает, что на картинке. Поэтому alt — не подпись и не имя файла, а замена: какой текст поставить на это место, чтобы человек, который картинку не видит, ничего не потерял.
| Картинка | alt | Почему так |
|---|---|---|
| фото товара | alt="Пять красных роз в крафтовой бумаге" | того, что видно на фото, в тексте рядом нет |
| логотип внутри ссылки на главную | alt="Ромашка — на главную" | другого текста у ссылки нет, и alt становится её именем |
| волнистая линия между разделами | alt="" | ничего не сообщает: пустой alt просит программу чтения её пропустить |
| график, числа которого стоят в таблице ниже | alt="Продажи за год, числа — в таблице ниже" | пересказывать таблицу незачем, достаточно сказать, где данные |
Пустой alt="" и отсутствие alt — разные сообщения. Пустой значит «украшение, пропусти». Без атрибута программа чтения не знает, важна ли картинка, и нередко читает вместо неё имя файла — что-нибудь вроде «IMG_2044.jpg»: человек услышит его вслух и не поймёт ничего. Разницу видно и в разметке. Квадратные скобки в адресе проверяют атрибут: img[alt] — картинки, у которых alt есть, img[alt=''] — у которых он есть и пуст; кавычки вокруг пустого значения одинарные, чтобы не спутаться с двойными вокруг всего адреса. Прогноз: сколько картинок найдёт каждый из трёх адресов?
img[alt] нашёл две картинки: пустой alt — тоже alt. Без атрибута осталась только третья.Картинки без alt первыми ищут проверки доступности. Такой поиск вы соберёте сами в конце второй главы, в проекте с проверкой разметки на селекторах.
Чаще всего сомнение вызывает не фотография, а мелочь: иконка в кнопке, разделитель-завитушка, флажок страны. Правило одно — спрашивайте, что потеряет человек, который этого не увидит. Иконка корзины рядом со словом «Корзина» не добавляет ничего, значит alt="". Картинка-разделитель не несёт смысла — тоже alt="". А вот скриншот с текстом или график, из которого читается вывод, требует настоящего пересказа: «график: посещаемость выросла вдвое после переноса на статику», а не «график.png».
Теперь посмотрите в рамку. Файлы logo.png и остальные браузер даже не запрашивал: у документа песочницы адрес about:srcdoc, и полный адрес файла от него не достроить. Как относительный путь достраивается от адреса обычной страницы, объясняет статья про относительные адреса. Файла не будет — и на месте первой картинки браузер написал её alt. Две другие в Chrome и Firefox следа в рамке не оставили, но для программы чтения третья так и осталась картинкой без имени.
Отсюда и alt="" в первом примере статьи. Картинка без адреса для браузера — картинка, файла которой не будет, и текст из alt он выводит на её место. С текстом в alt замер получил бы высоту строки вместо нуля. Пустой alt оставляет голую коробку — такую же, как у картинки, файл которой ещё в пути: пока файл идёт, текст alt не показывается. Проверьте: впишите второй картинке первого примера alt="Букет" и запустите его снова.
alt не начинают словами «картинка» или «фото»: программа чтения сама сообщит, что перед ней изображение.
Последняя странность — щель в несколько пикселей под картинкой, которая стоит в блоке одна. Ни отступов, ни рамок, а блок выше картинки. Дело в том, что <img> по умолчанию строчный элемент: display у него inline, и он встаёт в строку текста, как слово, а не занимает свою полосу, как абзац. Всё в строке выравнивается по базовой линии — той, на которой стоят буквы, а под ней оставлено место для хвостов у «у», «р» и «д». Картинка садится нижним краем на базовую линию, и место для хвостов остаётся под ней пустым, даже если букв в строке нет.
В примере два блока, в каждом картинка 100 на 50 пикселей. Длинный src, который начинается с data:, — это сам файл, записанный прямо в адресе: крошечная картинка, которой не нужна сеть, иначе пример зависел бы от загрузки. Пробел в адресе значит «внутри»: .fixed img — картинки внутри элемента с классом fixed, и стиль даёт им display: block; запись .plain, .plain img через запятую означает сам блок и картинку в нём. Высота щели зависит от шрифта, поэтому в пикселях числа у разных читателей разошлись бы, и здесь работает сравнение: same отвечает «одинаково» или «по-разному» для всех найденных элементов. Прогноз для каждого блока: одинаковы ли высоты блока и его картинки?
display: block подходит картинке, которая стоит отдельно: в карточке, над подписью. Если картинка должна остаться в строке, щель убирает vertical-align — свойство, которое говорит строчному элементу, по чему выравниваться. Со значением top или bottom картинка встаёт по верхнему или нижнему краю строки, а не на базовую линию, и пустое место под ней пропадает.
С этой щелью связан «почти стандартный» режим из статьи о скелете страницы: от старых правил в нём осталась как раз высота строки, в которой одна картинка и нет текста, и щели там нет. В стандартном режиме, который включает <!doctype html>, щель есть, и убирать её — дело вашего стиля.
Щель редко мешает в одиночку, зато в карточках её видно сразу: сетка из трёх карточек, в каждой картинка и подпись, и у всех карточек подпись отстоит от картинки на три-четыре лишних пикселя. Пустяк, из-за которого карточки выглядят неровно, а высоты в сетке перестают совпадать. Второй частый случай — иконка в строке текста: она стоит на базовой линии и растягивает строку. Лечат оба одним из двух способов: display: block, если картинка стоит отдельно, или vertical-align, если она обязана остаться в строке.
Ещё два атрибута картинки держатся на сети, поэтому в песочнице их не проверить — о них достаточно знать.
loading="lazy" откладывает загрузку, пока до картинки далеко: файл начнёт скачиваться, когда читатель долистает близко. На длинной странице с галереей это экономит трафик и время. У ленивой загрузки картинок и фреймов статус Baseline Widely available с 19 июня 2026 года — пишите. Условий два. Картинкам первого экрана lazy не ставят: они нужны сразу, а ленивая загрузка их задержит. И ленивой картинке width и height нужнее, чем любой другой: пока до неё не долистали, файла нет наверняка.
srcset перечисляет файлы одной картинки разного размера, например srcset="rose-400.jpg 400w, rose-800.jpg 800w", и браузер сам выбирает, какой скачать: телефону с узким экраном незачем тянуть фото шириной 2400 пикселей. Рядом пишут sizes — подсказку, какой ширины картинка будет на странице: файл выбирается раньше, чем страница разложена. src при этом остаётся файлом по умолчанию. У srcset и sizes статус Baseline Widely available с 27 сентября 2019 года.
Проверяют и то и другое на настоящей странице: во вкладке Network инструментов разработчика видно, какие файлы скачались и в какой момент.
- Файл картинки приходит позже разметки. Без
widthиheightкоробка до его прихода нулевая, и всё, что ниже, прыгает, когда файл придёт. - Атрибуты
widthиheightбраузер превращает вaspect-ratio: из 400 и 300 получаетсяauto 400 / 300. Сwidth: 100%илиmax-width: 100%иheight: autoместо откладывается в нужной пропорции при любой ширине колонки. В атрибуты пишут настоящий размер файла: когда он придёт, верх возьмут его пропорции. - Атрибуты — самый слабый стиль: CSS перебивает их по одному свойству. Забытый
height: autoоставляет высоту из атрибута, и картинка сожмётся только по ширине. alt— замена картинки текстом: осмысленный у содержательной картинки, пустойalt=""у украшения. Без атрибута программа чтения может прочитать имя файла.<img>— строчный элемент и стоит на базовой линии, а щель под ним — место для хвостов букв. Её убираетdisplay: blockили, у картинки в строке,vertical-align: topилиbottom.loading="lazy"(Baseline Widely available с 19 июня 2026 года) не ставят картинкам первого экрана и не пишут без размеров.srcsetдаёт браузеру выбрать файл под экран. В песочнице ни то ни другое не проверить: сети там нет.
1/4Колонка шириной 300 пикселей, у картинки width="600" height="400", в стиле img { width: 100%; height: auto; }. Какой высоты её коробка, пока файл не пришёл?
2/4В стиле сайта img { width: 100%; }, у картинки width="400" height="300", колонка 200 пикселей. Что увидит читатель, когда файл придёт?
3/4Между разделами статьи стоит декоративная волнистая линия — картинка. Какой alt ей нужен?
4/4Картинка стоит в блоке одна, отступов и рамок нет, а блок на несколько пикселей выше неё. Почему?
Карточка, которая прыгает
Карточка букета шириной 200 пикселей: фото и подпись. Файл фото — 800 на 600 пикселей, адреса в примере нет: в песочнице файл всё равно не придёт. Сейчас место под фото не отложено, и подпись стоит там, куда фото потом упадёт.
Исправьте разметку и стиль: место под фото должно резервироваться заранее, щели под фото быть не должно, а программа чтения должна знать, что на нём. Когда всё получится, прибор напечатает img → height: 150px и .cap → y: 164px.
Правок три. Атрибуты width="800" height="600" дают пропорцию 4 : 3, а height: auto в стиле её включает: при ширине 200 высота 150. display: block убирает строку, в которой стояла картинка, а с ней и щель. alt описывает фото.
Вывод: img → height: 150px и .cap → y: 164px. В исходном варианте подпись стояла на 35, хотя высота картинки была 0: пустая строчная картинка всё равно занимала строку текста в 21 пиксель, и к ней добавлялся отступ абзаца 14. Если вписать alt, но забыть display: block, высота будет не 150, а высотой текста: картинка без адреса, стоящая в строке, выводит свой alt как слова.
alt для витрины
На витрине магазина три картинки: логотип внутри ссылки на главную, волнистая линия-украшение и фото букета, о котором рядом написаны только название и цена. alt расставлен как попало. Исправьте так, чтобы каждая картинка сообщала программе чтения то, что нужно, и ни одна не осталась без атрибута.
Проверка считает только атрибуты, смысл решаете вы. В исправленной версии вывод такой: img[alt] → 3 и img[alt=''] → 1.
Логотип — единственное содержимое ссылки, и его alt становится её именем: без него программа чтения скажет только «ссылка» и может прочитать адрес или имя файла. Линия ничего не сообщает — ей пустой alt, а не описание. У фото в alt стояло имя файла, а нужен текст о том, что на фото видно.
Вывод: img[alt] → 3 и img[alt=''] → 1.
Маленькая картинка расплылась
В колонке шириной 200 пикселей две картинки: фото 400 на 300 и значок 120 на 90. Стиль растягивает обе на всю ширину, и значок, растянутый почти вдвое, расплывётся. Замените в стиле одно свойство так, чтобы большая картинка сжималась до колонки, а маленькая оставалась своего размера. Нужный вывод: img → width: 200px, 120px и img → height: 150px, 90px.
width: 100% меняется на max-width: 100%. Ширину тогда задают атрибуты, а стиль только не пускает её дальше колонки: 400 урезается до 200, 120 остаётся 120. Высоту по-прежнему считает пропорция — за это отвечает height: auto.
Вывод: img → width: 200px, 120px и img → height: 150px, 90px.