Підкреслення, яке не обходило літери
Наш власний сайт підкреслює кожне посилання й дозволяє браузеру вирізати
проміжок там, де хвостик літери перетинає лінію, — g, p, кома. У Safari
цього не відбувалося. Лінія йшла просто крізь них. І так було на англійських та
данських сторінках відтоді, як сайт став
багатомовним.
Причиною були три оголошення шрифту для абетки, яку ті сторінки ніколи не завантажують.
Що браузер має робити
text-decoration-skip-ink — це властивість, яка піднімає підкреслення над
нижнім виносним елементом. Вона ввімкнена за замовчуванням, і роками відповіддю
на «моє підкреслення має неправильний вигляд» було взятися за
text-underline-offset і посунути лінію нижче. Це хибний рефлекс: зсув лінії
змінює дизайн, а бракувало насправді саме проміжку.
Перш ніж дійти до цікавого, ми знайшли дві справжні причини, і обидві варті уваги.
- Підкреслення завтовшки
1pxотримує проміжок розміром1px. Розрив, який вирізає рушій, пропорційний товщині лінії, що його вирізає. Наш стиль зафіксував товщину на одному пікселі, і це лишало близько 0,6px повітря з кожного боку штриха — технічно проміжок, візуально лінія просто крізь літеру.text-decoration-thickness: autoзмасштабував обидві величини разом і збільшив проміжок з 3,5px до 12,4px, не зсунувши підкреслення ані на піксель. from-font— не той безпечний варіант, яким здається. Він читає товщину, яку оголошує сам шрифт, а Ubuntu оголошує 0,056em для Light, 0,020em для Medium і 0,120em для Bold — родина, у якої лінія Medium важить менше за половину лінії Light. На великих розмірах це шестипіксельна лінія поряд із двопіксельною на одній сторінці.
Це виправило Chrome. Safari й далі вів лінію крізь усе.
Частина, яка забрала найбільше часу
Ми виміряли це як належить: запустити справжній Safari, перефарбувати підкреслення, зробити знімок екрана у восьмикратному масштабі й порахувати пікселі, де лінія уривається й починається знову.
| намальована товщина | проміжок навколо виносного елемента | |
|---|---|---|
| Chrome | 2,00px | 5,8 / 12,5 / 6,3px |
| Safari | 1,38px | 1,8 / 1,0 / 1,0px |
Отже, Safari таки вирізав проміжок. Просто вшестеро вужчий за Chrome, а в розмірі для читання проміжок в один піксель — це не проміжок. Гірше: звичний важіль лише погіршував справу. За товщини 3px Safari падав із трьох проміжків до одного, за 4px — до жодного, бо він не масштабує проміжок разом із лінією. Він фіксує його приблизно на 0,07em за будь-якого розміру, тоді як Chrome дає 0,6em.
Ми перебрали проти нього близько двадцяти оголошень — skip-ink: all, обидва
застарілі написання властивості, кожну товщину від половини пікселя до чотирьох,
text-underline-position, font-smoothing, text-rendering, paint-order.
Ніщо не розширило проміжок. Чесний висновок на той момент був такий: WebKit
просто обмежує проміжок, і зі стилів більше нічого не вдіяти.
Той висновок виявився хибним, а зламав його звіт про ваду проти шрифтового проєкту: Safari ігнорує skip-ink, коли шрифт завантажено з нелатинською підмножиною.
Справжня причина
Сайт віддає Ubuntu шістьма частинами — три накреслення латиницею, три кирилицею, — щоб українська сторінка була набрана тим самим шрифтом, що й англійська, а не відкочувалася до того, що запропонує система. Кожна частина оголошує діапазон символів, який покриває, і браузер завантажує лише ті частини, які сторінці справді потрібні.
Усі шість були оголошені під однією назвою родини — це найочевидніший спосіб це записати. І саме він є спусковим гачком, зафіксованим як вада WebKit 255159: коли одне накреслення в родині оголошує нелатинський діапазон символів, Safari погіршує skip-ink для кожного символу цієї родини — зокрема для латинського тексту на сторінці, яка ніколи не завантажує той інший файл.
Англійська сторінка малювала свої підкреслення погано, бо десь у стилях існувало українське оголошення шрифту. Коли ми видалили ті три рядки під час виконання й не змінили більше нічого, проміжки зросли з 1,8/1,0/1,0px до 4,5/11,0/5,0px.
Виправлення
Дайте другій системі письма власну назву родини й назвіть її у стеку шрифтів після першої:
@font-face {
font-family: UbuntuCyrillic; /* було: Ubuntu */
src: url(ubuntu_300_cyrillic.woff2) format('woff2');
unicode-range: U+0400-045F, U+0490-0491;
}
:root {
--body-font: Ubuntu, UbuntuCyrillic, system-ui, sans-serif;
}
Латинська літера знаходиться в першій родині й ніколи не доходить до другої. Кирилична проминає першу, де такого гліфа немає, і потрапляє в другу, а не в системний шрифт. Діапазони символів і далі вирішують, що завантажується, тож в завантаженні не змінюється нічого: англійські та данські сторінки беруть три латинські файли й жодного кириличного, українські — навпаки.
Три перейменовані оголошення й один запис у стеку. Проміжки в Safari зросли до 4,5/11,0/5,0px, Chrome лишився недоторканим, підкреслення не зрушило з місця, а українська й далі набирається в Ubuntu з тими самими ширинами.
Що ми сказали б наступному
- Вимірювання skip-ink справедливе лише для того рушія, який його дав. Ми мали таблицю чисел, правильний діагноз і справжнє виправлення — і все це було Chromium. Знімок екрана, який відкрив справу наново, надійшов від людини, яка подивилася на сторінку.
- Беріться за товщину раніше, ніж за зсув. Ширший проміжок зберігає дизайн; зсув лінії вниз його замінює.
- Ділити шрифт за системами письма — правильно, але поділ має бути й у назві родини. Одна назва на кілька систем письма читається краще й коштує вам skip-ink у Safari. Злити їх назад має вигляд прибирання, а є регресом.
- Завантаження ніколи не було проблемою. Будь-яка інтуїція підказує, що сторінка, яка малюється погано через кириличний шрифт, мусить завантажувати щось зайве. Вона не завантажувала. Досить було самого оголошення.
Джерела
Саме такі задачі ми розплутуємо для клієнтів. Зв'язатися з нами.