:first-letter и веселье

Sergii Lysenko

Sergii Lysenko

February 20, 2016

На днях столкнулся с одной очень интересной проблемой. Во время разработки темы для нашего продукта ко мне обратился один из разработчиков и попросил о помощи. Задача была очень простой: необходимо было вывести в нижнем регистре данные (в форме списка), которые хранятся в базе в верхнем регистре. Но было одно уточнение - первый символ каждого элемента списка должен быть в верхнем регистре. Казалось бы задача проста, и достаточно указать text-transform: lowercase; для каждого элемента списка, а после этого вывести первый символ в верхнем регистре с помощью псевдо-элемента ::first-letter. Но не тут то было.. Данный подход по каким то причинам не работал в Firefox последней версии (Firefox 44, на момент написания этой заметки). В первом приближении код был следующим:

Этот код отрабатывал корректно во всех современных (и не только 😏) браузерах (Safari, Chrome, даже IE10/11), но не в Firefox. После нескольких экспериментов я обнаружил, что причиной такого поведения является наличие в каждом элементе списка псевдо-элемента :before (он использовался с целью отображения разделителя между элементами списка). Видимо, Firefox, в отличие от других браузеров, “видит” этот псевдо-элемент :before и считает его частью контента, но при этом все равно не преобразовывает этот символ в верхний регистр. Проблему решить достаточно просто, но для этого необходимо заменить псевдо-элемент :before на :after:


Но и это еще не всё! Вот такое веселье меня ждало в схожем горизонтальном списке (кстати, воспроизводится только в светлой теме JSFiddle, потому как в темной после загрузки странным образом происходит повторный re-render контента):

Переключитесь в режим Result и попытайтесь навести курсор на любой элемент списка.

Скриншот на случай, если пофиксят 🙂: :first-letter issue

Эта проблема воспроизводилась уже в Google Chrome 48-ой версии (в том же Safari такой проблемы не было).

В данном случае проблема в обнуленном размере шрифта для тега списка ul (размер шрифта устанавливался только для span тега внутри каждого элемента списка li). Любой re-render страницы “чинит” данную проблему (достаточно изменить любое css свойство с помощью DevTools вашего браузера, или же навести курсор на любой из пунктов чтобы отработали стили :hover). Для решения проблемы достаточно изменить display: inline тега span на display: block или display: inline-block, также можно просто вынести указание размера шрифта в элементы списка li:

P.S. Front-end - это весело!