На просторах сети немало сайтов, и у значительной их части на главной странице находится ОН — Самый Главный Слайдер.

Как правило, у него есть некоторый набор отличительных черт: он большой, у него красивые картинки, он содержит очень важную информацию!

А самое главное — зачастую, часть его слайдов... нечитаема. И это очень коварная проблема, ведь поначалу ничто не предвещает беды. Дизайнер делает красивый дизайн, верстальщик - качественную вёрстку. Всё идёт отлично!

А спустя время заказчик начинает менять текст, загружает новую картинку, иии... Оказывается, что картинка подходит совсем не любая. На самом деле, даже не любая картинка зачастую тоже не подходит!

А ещё есть разные... кхм... разрешения... кхм... экрана... Простите, слеза в горле застряла.

Надеюсь, слайд с Вашим уникальным торговым предложением не похож на этот.
Надеюсь, слайд с Вашим уникальным торговым предложением не похож на этот.

Что же делать!!?

Разумеется, решение есть! Достаточно просто... заказать у дизайнера картинку, на которой заранее будет написан нужный текст. Ну... лучше бы, конечно, хотя бы три картинки - Desktop, Tablet, Mobile... Хотя для надёжности лучше, чтобы их было побольше - а то мало ли, как они растянутся под все остальные десятки разрешений...

Оппа... Кажется, Photoshop подвезли!
Оппа... Кажется, Photoshop подвезли!

Итак, драматическое вступление - всё.

Давайте разберёмся с тем, как решить эту проблему - что сделать, чтобы повысить читаемость текста?

Возможно, немного поможет использование CSS-свойства text-shadow с контрастным цветом (чёрный текст - белая тень, белый текст - чёрная тень), позволив чуть выделить текст. Однако, такое решение крайне ограниченное.

Было бы здорово, если можно было бы размыть фон под текстом, прямо как на скриншоте из Photoshop'а выше...

И на данный момент существует несколько способов, как это сделать:

  • Использовать графические редакторы - можно, но долго.

  • Использовать SVG-фильтры - можно, но текст внутри SVG ведёт себя не так, как мы привыкли, да и других проблем с ним хватает.

  • Использовать Canvas & JavaScript - можно, но тоже есть немало проблемных нюансов.

  • Использовать CSS-фильтры - звучит круто, а справятся?

На самом деле, использование SVG и CSS фильтров похоже, и имеет общую же проблему: фон отлично размывается... Прямоугольниками.

Перебор...
Перебор...

В целом, читается неплохо, да и в чей-то дизайн отлично впишется... Но такой вариант явно не для всех.

А раз так, остаётся только одно...

Вносите сюда JavaScript! Только не уроните, а то сайт развалится...

План действий:

  1. Находим нужный контейнер с текстом

  2. Разбираем его на буквы

  3. Каждой букве добавляем псевдоэлемент размером с букву, добавляем к нему фильтр.

  4. Радуемся.

Красивое...
Красивое...

Ладно, возможно радоваться пока рановато.

Проблема в том, что у букв разный размер.

В плане ширины нас это не беспокоит - по странному стечению обстоятельств, ширина каждого блока автоматически подстраивается под ширину единственной буквы, которая в нём находится.

А вот с высотой явно нужно что-то делать. К сожалению или к счастью, но высота блока зависит от размера шрифта, а не от того, какие буквы в нём находятся... Так что высота у блоков одинаковая.

Проблема решается просто: для каждой буквы зададим её тип (всего типов 6):

  • tallUp - все заглавные буквы и буквы, у которых хвост идёт вверх (например: б, k);

  • tallDown - буквы с хвостом вниз (например: р, q);

  • low - маленькие буквы - сюда пойдёт большинство строчных букв и некоторые знаки (например: н,а,п,и,м,е, :);

  • smallUp - очень маленькие буквы, смещённые вверх (например: *, ^);

  • smallCenter - очень маленькие буквы, смещённые по центру (например: =, ~);

  • smallDown - очень маленькие буквы, смещённые вниз (например: .,,);

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

Итак, дополним наш план действий:

  1. Находим нужный контейнер с текстом

  2. Разбираем его на буквы

  3. Каждой букве добавляем псевдоэлемент (размером с букву) и добавляем к нему фильтр.

  4. Каждой букве присваиваем класс, в зависимости от её типа, с заданными параметрами высоты и смещения.

  5. Повторно радуемся (на всякий пожарный, не очень сильно).

Ну... стало лучше...
Ну... стало лучше...

Да, всё же чего-то не хватает. Хорошо, что на этот раз не сильно радовались, а то было бы обидно.

Итак. Теперь высота букв лучше соответствует их реальному размеру (здесь блоки увеличены по высоте для лучшей демонстрации), однако нужно как-то сделать прямоугольники менее... прямоугольными.

Свойство border-radius немного помогло, но не сильно.

К счастью, у нас есть... Свойство mask-image! Сделаем так, чтобы в центре прямоугольник был полностью не прозрачным, активно заблюривая фон под собой, но чем дальше к краям, тем более прозрачным становился эффект, пока на самом крае полностью не пропадёт.

mask-image: 
  linear-gradient(to top, transparent 0%, black var(--blur-text-mask-sharpness, 25%)),
  linear-gradient(to bottom, transparent 0%, black var(--blur-text-mask-sharpness, 25%)),
  linear-gradient(to left, transparent 0%, black var(--blur-text-mask-sharpness, 25%)),
  linear-gradient(to right, transparent 0%, black var(--blur-text-mask-sharpness, 25%));
mask-composite: intersect;

Как (примерно) выглядит такая маска, можно увидеть ниже. Главное не смотрите ей в глаза, а то она может начать приближаться... Не беспокойтесь об этом слишком сильно, я её хорошо зафиксировал... Вроде бы.

Примерный вид маски.
Примерный вид маски.

Там, где маска полностью чёрная, эффект заблюривания работает полностью, а там, где она полностью белая - эффект полностью пропадает.

С помощью соответствующей переменной (--blur-text-mask-sharpness), можно регулировать, с какого места (в %) маска будет становиться полупрозрачной.

С помощью других переменных (--blur-text-padding и --blur-height-multiplier) можно регулировать ширину (минимально она равна ширине буквы) и высоту псевдоэлемента (тут минимума нет).

И вот, после столько перипетий и обходных манёвров.... Оно работает!

Оказывается, это был не Photoshop!
Оказывается, это был не Photoshop!

Важно учитывать, что:

  • На скриншотах специально показана одна из наиболее сложных ситуаций.

  • Данное решение не панацея, но закроет множество проблемных мест. В комбинации с другими методами (например, тенью), решение может стать более универсальным.

  • Необходимо продумать, какие параметры будут наилучшими для большинства изображений, используемых в конкретном случае (тестируйте!)

Для удобства всех желающих воспользоваться данным эффектом, загрузил библиотеку на GitHub (либо можно взять файлы из демки).

В css доступны переменные для настройки всех важных свойств. Для подключения достаточно передать в функцию класс контейнера.

ВАЖНО! Убедитесь, что в Ваших стилях у контейнера НЕ стоит что-то вроде display:flex, а то всё поедет.

Посмотреть демку можно тут. Она крутая, с кучей функций - в том числе можно менять текст на карточках, и загружать свою картинку.

GitHub репозиторий можно увидеть тут. Он не такой крутой, но там есть исходники, а также уже скомпилированный css.

Для тех, кому важно - лицензия MIT.

---

Всем спасибо за внимание! =))

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