В прошлом году передо мной стояла интересная задача: сделать символ сердечка частью заголовка страницы. Мы организовывали конференцию «Я Люблю Фронтенд», а слово «Люблю» для большей эмоциональности хотели заменить символом сердечка.
Казалось бы, какие могут быть проблемы?
Если у вас есть заголовок «Я ❤ Фронтенд», он рендерится по-разному в разных браузерах в разных операционных системах. Например, на Android и iOS сердечко выглядит как эмоджи. И это огромная проблема, если вам нужно этот заголовок стилизовать.
Юникод Скопировать ссылку
Всё дело в рендеринге. Никита Прокопов описал этот нюанс в своей подробной статье про эмоджи.
Каждый символ, который вы используете, имеет свою UTF-8 последовательность, свой код. Например, английская буква A имеет код U+0041
, буква Z — U+005A
, символ $ — U+0024
и так далее. То же касается и эмоджи: ❤ имеет код U+2764
.
Вы можете вставлять символы в свой HTML как Юникод-последовательность, а не готовыми символами.
<span>Я ❤ Фронтенд</span>
или
<span>Я ❤ Фронтенд</span>
&#x
— префикс для указания Юникод-последовательности.
Но что делать, если текущий указанный шрифт не содержит внутри себя глифа, который может отрендерить ваш UTF-8 символ? Операционная система пытается найти любой шрифт, который содержит такой глиф. Для iOS это будет Apple Color Emoji, для Android — Noto Color Emoji. Но, кажется, мы можем контролировать этот процесс.
Шрифты Скопировать ссылку
Первое решение — иметь в наличии шрифт, который содержит все необходимые нам глифы. Например, Arial. Или какой-то кастомный шрифт. Вам нужно добавить его в фолбеки внутри CSS.
body {
font-family: 'Text Font', 'Custom Glyphs Font', sans-serif;
}
Но мне не нравятся подобные решения, потому что у меня обычно нет полного контроля над всеми глифами в тексте. Особенно если разработка подразумевает какую-то админку для наполнения контентом. Больно пересобирать шрифт каждый раз, когда мне понадобится новый глиф.
Селекторы варианта начертания Скопировать ссылку
К счастью, есть другое решение. В UTF есть специальные символы для управления рендерингом — селекторы варианта начертания (англ. variation selectors). Символ U+FE0E
просит ОС и браузер отрендерить предыдущий глиф в виде текста, а U+FE0F
— в виде эмоджи.
Давайте попробуем.
<ul>
<li>☀ может отрендериться по-разному.</li>
<li>☀️ должен выглядеть как эмоджи солнца.</li>
<li>☀︎ должен выглядеть как текстовый символ солнца.</li>
</ul>
- ☀ может отрендериться по-разному.
- ☀️ должен выглядеть как эмоджи солнца.
- ☀︎ должен выглядеть как текстовый символ солнца.
Получается, если вам нужно выключить эмоджи в тексте, нужно сконвертировать выбранный символ в последовательность UTF-8 или UTF-16 (например, при помощи symbol.codePointAt(0).toString(16)
в JS), потом добавить к этому символу ︎
.
<span>Я ❤︎ Фронтенд</span>
И это всё не работает для эмоджи сердечка на Android. Я не знаю, почему. Когда мы тестировали это в прошлом году, всё было хорошо, но… Вы можете поиграть с различными символами в песочнице. Но как по мне, что-то лучше, чем ничего.
Доступность Скопировать ссылку
Помните, что все эмоджи имеют своё текстовое представление. Например, ⭐︎ — это «белая средняя звезда», ► — «чёрная стрелка, указывающая вправо». И скринридеры будут использовать эти тексты.
В итоге наш заголовок «Я ❤ Фронтенд» зачитывается утилитой VoiceOver как «Я Красное сердце Фронтенд». Кажется, это не то, что мы хотели сказать.
Чтобы починить это, используйте глифы правильно.
<span role="img" aria-label="Люблю">
❤
</span>
Итоговый результат, который мы использовали на сайте конференции, ниже.
<h1>
Я <span role="img" aria-label="Люблю">
❤︎
</span> Фронтенд!
</h1>