Как сделать текст на картинке в HTML: контейнер, слой и плашка
Как сделать текст на картинке в HTML: почему подпись падает под фото, какие свойства CSS кладут её сверху и как сделать надпись читаемой на светлом снимке.
Андрей
Преподаватель, научный редактор
6 мин чтения
Первая попытка почти у всех одинаковая: тег картинки, сразу за ним абзац с подписью — и подпись послушно встаёт под фото, а не на него. Ошибки в коде нет. Просто браузер делает ровно то, что ему сказали.
Как сделать текст на картинке в HTML, если коротко: положить картинку и подпись в общий контейнер, контейнеру дать относительное позиционирование, подписи — абсолютное, растянуть её на всю картинку и выровнять по центру. А чтобы надпись читалась на светлом фото, подложить под неё полупрозрачную тёмную плашку.
Я задал LibraChat два вопроса: про ошибку — почему подпись падает вниз, и про читаемость — как сделать, чтобы её было видно на светлом фото. Разбираю оба ответа так, как разбираю работу студента.
Почему подпись падает под картинку
Запрос про ошибку я так и начал, потому что с неё начинают все:
Почему надпись оказывается под картинкой, а не поверх неё, если я просто написал тег p после тега img? Объясни ученику без опыта, какие свойства CSS это исправляют и зачем каждое нужно.
Первая фраза ответа — то объяснение, которое я засчитал бы на зачёте:
Надпись оказывается под картинкой, потому что браузер выстраивает теги друг за другом в обычном потоке страницы.
Поток — ключевое слово. Его стоит понять один раз, и половина загадок вёрстки исчезнет. Элементы на странице идут один за другим, как строки в тетради. Чтобы что-то легло поверх, его нужно из этого потока вынуть. Ответ так и формулирует задачу:
Чтобы текст лёг на картинку, его нужно вынуть из этого потока и привязать к рамке самой картинки.
Это хорошее место: сначала причина, потом способ. Ученик, который понял причину, не будет подбирать свойства наугад.
Дальше ответ шёл по шагам, и каждый шаг объяснён словом «зачем».
Сначала контейнер — общий блок, в котором лежат и картинка, и подпись. В ответе он назван обёрткой. Без него браузеру не к чему привязать надпись:
Без этой обёртки браузеру не к чему привязать надпись: он будет считать координаты от всей страницы, а не от картинки.
Контейнеру ставят свойство position со значением relative. Сам он от этого почти не сдвигается, но становится «системой координат» для всего, что внутри. Подписи ставят position со значением absolute: она выходит из потока и перестаёт занимать место под картинкой. Четыре свойства — top, bottom, left и right — говорят, где именно её положить: прижать к низу, растянуть по ширине или отступить от угла.
Отдельно стоит деталь, которая крадёт у новичков больше всего времени. У картинки по умолчанию остаётся щель снизу в несколько пикселей, потому что браузер считает её строчным элементом. Свойство display со значением block эту щель убирает, и подпись ложится ровно на край фото. Эту деталь я бы отметил отдельно: о ней обычно узнают, когда уже полчаса двигают подпись на один пиксель.
Собранный вместе, образец выглядит так. В разметке — блок-контейнер с классом card, внутри картинка и подпись. Дальше правила CSS, записанные строками.
Для контейнера card: position: relative; display: inline-block.
Для картинки внутри card: display: block; width: 100%; height: auto.
Свойство inset: 0 — короткая запись для top, right, bottom и left, равных нулю: подпись растягивается на всю картинку. А три строки с flex ставят текст ровно в центр.
Запрос про ошибку можно отправить как есть. Он хорош тем, что спрашивает не «как сделать», а «почему не получается». Такой вопрос даёт объяснение, а не только код. Если у тебя не абзац, а заголовок или кнопка, замени «тег p» на свой тег.
Как сделать, чтобы текст читался на светлом фото
Это часть, на которой спотыкаются даже те, у кого подпись уже стоит на месте. Запрос про читаемость был таким:
Я учусь вёрстке. Объясни по шагам, как в HTML и CSS поставить текст поверх картинки по центру и сделать так, чтобы он читался даже на светлом фото. Сначала логика, потом короткий пример.
Ответ начал с главного вывода всей задачи:
Текст кладётся не «внутрь» картинки, а поверх неё: картинка и подпись живут в одном блоке, а читаемость даёт не цвет букв, а тёмный слой между фото и текстом.
Вот это я и считаю ядром темы. Новичок меняет цвет шрифта, жирность, размер — а белый текст на небе всё равно пропадает. Ответ говорит прямо:
Белый текст на светлом участке пропадает.
Решение — полупрозрачный тёмный фон у подписи. В ответе это background: rgba(0, 0, 0, 0.45): чёрный цвет, прозрачный больше чем наполовину. Если нужен тёмный только низ, вместо сплошного фона ставят градиент: background: linear-gradient(transparent, rgba(0, 0, 0, 0.7)), а текст прижимают к низу. Тень у букв, свойство text-shadow, — дополнение, а не замена: как точно замечено в ответе, одна тень на очень светлом кадре не спасает. Центр по горизонтали и вертикали в этом ответе сделан через flex — так короче, чем считать отступы вручную.
Что я засчитал бы, а что попросил бы переделать
Засчитал бы оба, но не одинаково. Ответ про ошибку объяснил каждое свойство и даже щель под картинкой. Ответ про читаемость дал хороший код, но строку inset: 0 объяснил тремя словами в скобках — «растягивание на весь контейнер». Новичку этого мало: не сказано, что она заменяет четыре свойства сразу. Это место я бы вернул на доработку с вопросом «а что именно она растягивает и откуда».
Попросил бы одного: не копировать пример целиком. В ответах был готовый код, и его легко вставить и забыть. Я бы предложил ученику другое упражнение: убрать по одному свойству и посмотреть, что сломается. Убрал relative — подпись улетела к краю окна. Убрал absolute — снова встала под фото. Так за десять минут понимаешь больше, чем за час чтения.
Проверку надписи я бы делал на трёх фото: тёмном, пёстром и почти белом. Если надпись читается на всех трёх, плашка подобрана верно. Если на белом пропадает — плашку темнее. Если на тёмном выглядит грязно — плашку прозрачнее или градиентом только снизу.
И последнее. Подпись на картинке — тоже текст, и его должны прочитать все, в том числе программы для незрячих. Поэтому у картинки в ответе заполнено описание в атрибуте alt. Мелочь? Нет, это часть грамотной вёрстки. Хорошая привычка — заполнять описание сразу, а не «потом»: потом обычно не наступает.