От автора: вы можете встретить компонент пользовательского интерфейса, у которого есть текст над изображением. В некоторых случаях текст будет трудно прочитать в зависимости от используемого изображения. Есть несколько различных решений, таких как добавление наложения градиента или тонированного фонового изображения, тени текста и других.
В этой статье я исследую различные подходы и решения проблемы обработки текста, а также то, как передать пользовательский интерфейс разработчику, и убедиться, что он реализован в соответствии с макетом дизайна, поскольку некоторые детали могут быть легко упущены в CSS.
Введение
Каждое решение должно решать проблему. Давайте рассмотрим проблему в нашем случае. При разработке компонента, который имеет текст над изображением, мы должны позаботиться о том, чтобы текст был легко читаемым.
Обратите внимание, что версия без наложения градиента плохо читается. Это не хорошо для пользователя. Чтобы решить эту проблему, нам нужно добавить слой под текстом, чтобы его было легко читать. Добавление этого уровня может быть сложной задачей, и я видел многих, кто внедряет такое решение, без учета доступности.
Обзор возможных решений
Есть разные решения для облегчения чтения текста. Давайте рассмотрим их.
Как видите, есть разные решения проблемы. Те, которые требуют большего внимания, — это градиентные решения. Почему? Потому что можно добавить слой градиента, и текст станет недоступен.
Решения
Наложение градиента
Вообще говоря, наложение градиента — это наиболее распространенное решение, позволяющее сделать текст на изображении более чётким. Учитывая это, я остановлюсь на нем немного подробнее. При реализации наложения градиента у нас есть два варианта:
Использовать отдельный элемент для градиента (псевдо-элемент или пустой div)
Применить градиент как фоновое изображение.
У каждого из вышеперечисленных есть свои плюсы и минусы, давайте рассмотрим их. Элемент содержимого позиционируется абсолютно, и у него есть градиент в качестве фонового изображения. Это означает, что размер градиента равен высоте элемента.
1 2 3 4 5 |
.card__content { position: absolute; /* other styles (left, top, right, and padding) */ background: linear-gradient(to top, rgba(0, 0, 0, 0.85), transparent); } |
С первого взгляда может показаться, что градиент хорош и работает. Это не так. Я протестировал тот же градиент с большим количеством изображений, и вот результат.
Обратите внимание, что контраст между белым текстом и изображениями не всегда четкий. В некоторых случаях текст может быть плохо читаемым, и использовать такой градиент — огромная ошибка.
Причина в том, что градиент должен охватывать больше места по вертикали, поэтому он должен быть больше по высоте. Наличие градиента, равного размеру содержимого, не сработает во всех случаях. Чтобы решить эту проблему, мы можем использовать min-height как показано ниже:
min-height к элементу .card__content.
Flexbox для перемещения содержимого вниз.
1 2 3 4 5 6 7 8 |
.card__content { position: absolute; /* other styles (left, top, right, and padding) */ display: flex; flex-direction: column; justify-content: flex-end; background: linear-gradient(to top, rgba(0, 0, 0, 0.85), transparent); } |
Другое решение — использовать большой размер padding-top, и нам не нужны min-height и flexbox.
1 2 3 4 5 |
.card__content { position: absolute; padding-top: 60px; background: linear-gradient(to top, rgba(0, 0, 0, 0.85), transparent); } |
Обратите внимание на разницу между левой и правой картинкой. Уклон больше по высоте.
Выглядит хорошо. Можем ли мы сделать лучше? Да, безусловно!
Сглаживание градиентов
Если вы присмотритесь, то заметите где заканчивается градиент, что приводит к тому, что называется жестким краем.
Чтобы улучшить, мы можем применить концепцию сглаживания к градиенту. Таким образом, градиент будет казаться более естественным, и вы не заметите резких краев в конце.
В CSS нам нужно иметь несколько точек градиента для достижения плавности. Хорошая новость заключается в том, что разработчики CSS обсуждают возможность реализации сглаживания в градиентах CSS, но неясно, когда это произойдет.
К счастью, г-н Андреас Ларсен создал удобные плагины PostCSS и Sketch, которые помогают преобразовывать обычный градиент в сглаженный. Вот градиент CSS для приведенного выше примера:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
.card__content { background-image: linear-gradient( 0deg, hsla(0, 0%, 35.29%, 0) 0%, hsla(0, 0%, 34.53%, 0.034375) 16.36%, hsla(0, 0%, 32.42%, 0.125) 33.34%, hsla(0, 0%, 29.18%, 0.253125) 50.1%, hsla(0, 0%, 24.96%, 0.4) 65.75%, hsla(0, 0%, 19.85%, 0.546875) 79.43%, hsla(0, 0%, 13.95%, 0.675) 90.28%, hsla(0, 0%, 7.32%, 0.765625) 97.43%, hsla(0, 0%, 0%, 0.8) 100% ); } |
Вот сравнение обычного градиента и сглаженного.
Горизонтальные градиенты
Обработка текста поверх изображения не может быть только вертикальной, но мы также можем использовать их как горизонтальный градиент. Рассмотрим пример, когда нужен горизонтальный градиент.
Вот градиент CSS для примера выше. Я использовал упомянутый ранее инструмент для создания ослабленного градиента.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
background: linear-gradient( to right, hsl(0, 0%, 0%) 0%, hsla(0, 0%, 0%, 0.964) 7.4%, hsla(0, 0%, 0%, 0.918) 15.3%, hsla(0, 0%, 0%, 0.862) 23.4%, hsla(0, 0%, 0%, 0.799) 31.6%, hsla(0, 0%, 0%, 0.73) 39.9%, hsla(0, 0%, 0%, 0.655) 48.2%, hsla(0, 0%, 0%, 0.577) 56.2%, hsla(0, 0%, 0%, 0.497) 64%, hsla(0, 0%, 0%, 0.417) 71.3%, hsla(0, 0%, 0%, 0.337) 78.1%, hsla(0, 0%, 0%, 0.259) 84.2%, hsla(0, 0%, 0%, 0.186) 89.6%, hsla(0, 0%, 0%, 0.117) 94.1%, hsla(0, 0%, 0%, 0.054) 97.6%, hsla(0, 0%, 0%, 0) 100% ); |
Смешивание сплошного цвета и градиента
Я узнал об этом шаблоне на сайте Netflix. На домашней странице для незарегистрированного пользователя есть заголовок с большим фоновым изображением.
Мне это нравится, но он скрывает многие детали изображения. Убедитесь, что вы используете такой способ только в том случае, если изображение должно быть декоративным (не приносит реальной пользы конечному пользователю).
1 2 3 4 5 6 7 |
<div class="hero"> <img src="cover.jpg" alt="" /> <div class="hero__content"> <h2>Unlimited movies, TV shows, and more.</h2> <p>Watch anywhere. Cancel anytime.</p> </div> </div> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
.hero:after { content: ""; position: absolute; left: 0; top: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.4); background-image: linear-gradient( to top, rgba(0, 0, 0, 0.8), rgba(0, 0, 0, 0) 60%, rgba(0, 0, 0, 0.8) 100% ); } |
Вот наглядное объяснение того, как работает этот паттерн.
Наложение градиента и тень текста
Есть небольшая полезная деталь, которая может сделать текст поверх изображений еще лучше. Все дело в добавлении к тексту text-shadow. Даже если это может быть нелегко заметить, но очень полезно, если изображение не загружается. Рассмотрим следующий пример.
1 2 3 |
.whatever-text { text-shadow: 0 2px 3px rgba(0, 0, 0, 0.3); } |
Наложение градиента, тень текста и непрозрачность
Это закономерность, которую я заметил в видеоплеере Facebook*. Мне нравится, что они использовали несколько техник, чтобы сделать текст (и другие элементы пользовательского интерфейса) понятным. При работе с видеопроигрывателем очень важно убедиться, что элемент поверх него должен быть заметен.
1 2 3 4 5 6 7 8 |
.player__icon { opacity: 0.9; } .player__time { color: #fff; text-shadow: 0 0 5px #fff; } |
Что нового в этом, так это то, что у нас есть метки и плеер имеет opacity: 0.9. Это поможет им смешаться с фоном под ними. Создается ощущение, что элементы управления смешаны.
Кроме того, использование белой тени для белого текста — эффективный способ сделать текст более четким. Вы хотите доказательства того, что все вышесказанное будет работать, даже если фон представляет собой полностью белое изображение? Ну вот:
Youtube делает то же самое со своими видео.
Вот что мне понравилось в подходе Youtube:
Использование темной рамки для каждого значка, чтобы он лучше выделялся.
Использование черной тени вместо белой для времени видео.
Радиальный градиент
Интересное решение, о котором я узнал от Netflix — это использование радиального градиента. Вот как это работает:
Установите базовый цвет заднего фона.
Поместите изображение в верхний правый угол с шириной 75%.
Наложение должно соответствовать размеру и положению изображения.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
.hero { background-color: #000; min-height: 300px; } .hero__image { position: absolute; right: 0; top: 0; width: 75%; height: 100%; object-fit: cover; } .hero:after { content: ""; position: absolute; right: 0; top: 0; width: 75%; height: 100%; background: radial-gradient( ellipse 100% 100% at right center, transparent 80%, #000 ); } |
Тем не менее, команда Netflix использовала изображение в формате PNG. Я не уверен в причине. Это может быть проблема с кроссбраузерностью или что-то в этом роде, так как я не тестировал решение радиального градиента.
Выбор доступного цвета наложения
Это отличный инструмент, который помогает нам выбрать правильную непрозрачность наложения в зависимости от изображения. Проверьте это на Codepen. Интересная задача — обеспечить доступность градиента.
В общем, если вы убедитесь, что наложение градиента правильно заполняет текст и имеет приличный цветовой контраст, все в порядке.
Тестирование
Решение нельзя считать хорошим, пока оно не протестировано, верно? Один из способов, который я использую для проверки наложения градиента — это добавить под ним белый фон. Если текст читабельный, то градиент будет работать с любым изображением, которое вы используете. Если нет, вам нужно настроить и улучшить его.
В приведенном выше примере я выбрал сплошной цвет под заголовком, а коэффициент контрастности составляет 4,74, что считается хорошим.
Использование Firefox DevTools
Спасибо Гийсу Вейфейкену за то, что он сообщил мне о том, что Firefox может проводить тест цветового контраста на градиентах. Это отличная функция.
Автор: Ahmad Shadeed
Источник: ishadeed.com
Редакция: Команда webformyself.
Читайте нас в Telegram, VK, Яндекс.Дзен
* Признана экстремистской организацией и запрещена в Российской Федерации.