Веб-шрифти ламають верстку: де саме виникає зсув
Зсув макета від веб-шрифтів майже ніколи не пов'язаний із самим файлом гарнітури — він виникає в момент підміни шрифту. Поки браузер завантажує накреслення, він або ховає текст (невидимий текст), або одразу малює системним запасним варіантом, а потім перемальовує завантаженим.
У цих двох гарнітур різна ширина знаків, висота рядка та метрики, тому абзац, зверстаний під одну, при підміні шрифту перерозбивається на іншу кількість рядків.
Далі спрацьовує ланцюгова реакція. Рядок, який був одним, стає двома — весь контент нижче зсувається вниз. Кнопки, поля форми, блоки з фіксованою висотою та прилипла навігація стрибають на десятки пікселів, а користувач у цей момент уже почав читати або цілитися в елемент.
Показник зсуву макета фіксує кожне таке зміщення як окрему подію, і саме шрифтова підміна дає левову частку цих подій на типовій сторінці.
Окремий випадок — невидимий текст. Якщо період приховування виставлений занадто довго, користувач бачить порожні блоки замість заголовка, а потім різкий стрибок рядків, коли гарнітура нарешті підвантажилася.
Це гірше, ніж миттєвий показ запасним шрифтом: сторінка виглядає зламаною рівно в той момент, коли відвідувач вирішує, чи залишатися на ній.
Корінь проблеми — у розсинхронізації: браузер не знає метрик ще не завантаженого накреслення і не може заздалегідь зарезервувати місце. Отже, закривати це потрібно на рівні налаштування завантаження та опису метрик, а не підбором «схожого» шрифту на око. Розбираємо, як це влаштовано і що саме налаштовується.
Що дає кероване завантаження шрифтів
Кероване завантаження шрифтів — це коли ми заздалегідь вирішуємо, що браузер покаже в перші мілісекунди і як підмінить накреслення, коли файл довантажиться.
Без цього рішення макет «дихає»: текст відрендерився системним шрифтом, потім підмінився веб-шрифтом з іншими метриками, і весь блок нижче стрибнув. Нижче — що саме змінюється, коли завантаженням керують усвідомлено.
- Стабільний макет. Ми підбираємо метрики резервного накреслення під цільове — збігаються ширина символу, висота рядка і положення базової лінії. Підміна відбувається без зсуву блоків, показник стрибків макета прямує до нуля.
- Передбачуваний рендеринг першого екрана. Критичні накреслення оголошуються заздалегідь і вантажаться в пріоритеті, решта — у міру потреби. Перший екран збирається в одному й тому ж вигляді при кожному заході, а не «як пощастить».
- Відсутність стрибків тексту. Для кожного накреслення задано свій період підміни: короткий — щоб не миготів системний шрифт, але достатній, щоб не блокувати рендеринг. Текст не перебудовується посеред читання.
- Стійкість на повільних каналах. При обриві або таймауті завантаження браузер залишається на резервному накресленні з тими самими метриками — сторінка читається, верстка не розсипається.
- Передбачуваність на всьому парку пристроїв. Ми перевіряємо поведінку на різних роздільних здатностях, мовах і режимах економії трафіку, а не лише на своєму ноутбуці. Результат — однакова поведінка тексту в усіх відвідувачів.
Ці пункти перевіряються: до і після заміряємо зсув макета і час до першого рендерингу тексту, і різницю видно в цифрах, а не на словах.
Способи підключення шрифтів: порівняння підходів
Вибір способу підключення веб-шрифтів визначає, скільки кілобайт критичного шляху завантажить браузер до першого відображення тексту, і чи станеться зсув верстки. Нижче — чотири робочі варіанти, між якими реально обирають на проєктах, з їхніми сильними сторонами та обмеженнями.
| Варіант | Коли підходить | Обмеження |
|---|---|---|
| Самохостинг | Брендовий шрифт, стабільний трафік, вимоги до приватності | Потрібно самим готувати підмножину знаків, стежити за оновленням файлів і кеш-заголовками |
| Зовнішній сервіс | Швидкий старт, багато мов і накреслень, немає часу на підготовку файлів | Залежність від чужого домену: зайве DNS-з'єднання, ризик блокування, обмеження ліцензії на самостійний хостинг |
| Системний стек | Інтерфейси, адмінки, контентні блоки, де важливий лише текст | Немає контролю над зовнішнім виглядом: на різних платформах гарнітура відрізняється, брендова типографіка втрачається |
| Підмножина знаків | Кирилиця + латиниця, один-два алфавіти, великі масиви тексту | Потребує розбивки на діапазони та перевірки, що рідкісні символи не випадають у підстановку |
Самохостинг дає повний контроль: файли лежать на своєму домені, версіонуються разом із релізом, а font-display: swap і передзавантаження ключового накреслення прибирають невидимий текст на старті.
Обмеження — супровід: при оновленні гарнітури потрібно перезібрати підмножину знаків і скинути кеш, інакше частина користувачів залишиться на старій версії.
Зовнішній сервіс знімає підготовку файлів і сам віддає потрібний діапазон під браузер, але додає зовнішній домен у критичний шлях. Якщо сервіс недоступний або заблокований, сторінка відрисується системним шрифтом — це допустимо як запасний варіант, але не як основний.
Системний стек не завантажує нічого: нульова вага і нульовий зсув верстки. Його розумно залишати як фінальний запасний варіант у font-family для будь-якого з перших трьох підходів — тоді при збої завантаження текст все одно читається одразу.
Як ми налаштовуємо завантаження: етапи робіт
Починаємо з аудиту: дивимося, звідки реально завантажуються веб-шрифти — власні файли, зовнішні каталоги, підключення через сторонні сервіси.
Часто на одній сторінці набирається 4-6 джерел, частина з них дублюється, а частина тягне зайві накреслення, які у верстці не використовуються. На цьому кроці фіксуємо, які гарнітури потрібні дизайну, а які залишилися «на згадку» з минулих ітерацій.
Далі вибудовуємо схему пріоритетів: критичні для першого екрана накреслення завантажуються раніше, декоративні — після основного контенту. Нижче — як виглядає процес загалом.
- Аудит підключень. Збираємо всі джерела шрифтів на сторінках, звіряємо з макетом і виявляємо зайві накреслення, дублі та зовнішні залежності.
- Схема пріоритетів. Визначаємо, які гарнітури потрібні для першого екрана, а які можна підвантажувати відкладено, і фіксуємо це в правилах.
- Налаштування завантаження. Прописуємо формати, попереднє завантаження критичних файлів і запасні варіанти, щоб текст не «стрибав» при підміні шрифту.
- Резервування місця. Задаємо метрики запасного шрифту так, щоб блоки займали фінальний розмір до підвантаження — це і прибирає зсув верстки.
- Перевірка на реальних умовах. Прогоняємо сторінки на повільному з'єднанні та мобільних пристроях, заміряємо зсув макета і швидкість відрисовки тексту.
- Правки за результатами. Якщо зсув залишився, коригуємо метрики або набір накреслень і повторюємо замір.
- Передача. Віддаємо конфігурацію, правила підключення і коротку інструкцію, як додавати нові гарнітури без регресу.
Після передачі у замовника залишається відтворювана схема: будь-який новий шрифт підключається за тими самими правилами, а не «як вийде». Опишіть вашу задачу — повернемося з оцінкою та планом робіт.
Що замовник отримує на руки
Комплект зібрано так, щоб шрифтову частину можна було передати будь-якому інженеру або підряднику й не втратити поведінку сторінки. Нижче — що саме йде в репозиторій і в документацію.
- Конфігурації підключення: файли шрифтів у WOFF2,
@font-faceзfont-display: swap,unicode-rangeза наборами знаків і preload лише для накреслень першого екрана. - Правила підстановки: ланцюжок
font-familyіз системними запасними, метрикиsize-adjustіascent-override, підібрані під основний шрифт, — підміна не зсуває рядки. - Набори знаків: розділення на латиницю, кирилицю та службові символи, щоб браузер не тягнув зайву вагу на сторінках без них.
- Схема завантаження: порядок preload, кеш-заголовки для шрифтових файлів, поведінка при повільній мережі та при вимкнених веб-шрифтах.
- Документація: які накреслення використовуються, де лежать вихідники, як перевірити зсув макета після правок.
- Регламент додавання нових накреслень: хто готує файл, які перевірки проходять вага й метрики, як оновлюється конфігурація і хто підтверджує викатку.
- Чек-ліст приймання: замір зсуву до і після, перевірка на мобільних і в режимі економії трафіку.
Такий комплект знімає залежність від однієї людини: правку вносить будь-який інженер команди, а поведінка тексту на сторінці залишається передбачуваною.
Кейс: усунення зсуву макета на порталі послуг
Портал послуг — каталог з особистим кабінетом, де користувач порівнює тарифи та оформлює заявки. Шрифт підключався через зовнішній сервіс: п'ять накреслень, весь набір гліфів, включно з кирилицею та символами, які на сторінках не зустрічалися.
Браузер підвантажував файли після розбору розмітки, і до їх появи текст перемальовувався запасним накресленням з іншими метриками.
Заміри до правок: зсув макета на картках тарифів і в шапці кабінету, час до читабельного тексту — помітна пауза на мобільних мережах. Найгірше було на повільних каналах: користувач починав читати, і рядки «стрибали» під курсором.
Що змінили
Розділили накреслення за призначенням: два залишилися для основного тексту та заголовків, решту прибрали. Зібрали підмножини гліфів під реальні мови порталу — зайві символи вирізали.
Основне накреслення попередньо завантажили з високим пріоритетом, решту віддали на розсуд браузера з font-display: swap.
Ключове — метрики. Для запасного накреслення задали size-adjust, ascent-override і descent-override через @font-face, щоб висота рядка збігалася з цільовим шрифтом. Плюс зарезервували місце під блоки з великим текстом.
Що стало
Зсув макета на ключових екранах зник — метрики збігаються, перемальовування не рухає блоки. Час до читабельного тексту скоротився: запасне накреслення показується одразу і не змінює геометрію.
Кількість завантажуваних накреслень зменшилася більш ніж удвічі, вага шрифтів на першому завантаженні — у рази.
У підтримці залишилося правило: нове накреслення додаємо лише після заміру метрик і перевірки на мобільних. Підхід переносимо на інші проєкти — веб-шрифти перестають бути джерелом зсуву, коли метрики запасного варіанта виставлені заздалегідь.
Чим відрізняється попереднє завантаження від відкладеного завантаження шрифтів
Попереднє завантаження — це коли браузер отримує вказівку завантажити файл шрифту в першу чергу, ще до того, як парсер дійде до правил, де цей шрифт оголошено.
Інженерно це виглядає так: на початку документа стоїть посилання з атрибутом rel="preload", типом ресурсу font і обов'язковим crossorigin — без останнього браузер завантажить файл двічі, тому що шрифти завжди запитуються в режимі анонімного CORS.
Такий режим виправданий для одного-двох накреслень, якими набрано заголовок і перший екран: поки триває розбір розмітки, файл уже лежить у кеші, і критичний текст відмальовується одразу потрібною гарнітурою, без підміни системної.
Відкладене завантаження працює навпаки: шрифт оголошується в правилах, але підключається неблокуюче. Браузер спочатку малює текст системним накресленням, а коли файл довантажився — замінює його.
Тут і народжується зсув: метрики системного й цільового шрифту різняться, рядок змінює ширину, і весь блок під ним стрибає вниз.
Лікується це не відмовою від відкладеного завантаження, а підгонкою метрик — властивістю size-adjust і перевизначенням ascent-override у правилі @font-face, щоб запасний шрифт займав рівно ту саму площу. Тоді підміна відбувається без зміщення макета.
Вибір між режимами — це вибір між часом до першого показу тексту та стабільністю верстки.
Попереднє завантаження прискорює появу потрібної гарнітури, але конкурує за канал із критичними ресурсами: якщо попередньо завантажити п'ять накреслень, вони відберуть пропускну здатність у стилів і скриптів, і перший екран покажеться пізніше.
Відкладене завантаження не гальмує відмальовування, але вимагає, щоб запасне накреслення було метрично сумісним із цільовим.
На практиці режими комбінують. Основне накреслення для першого екрана йде через попереднє завантаження, решта — відкладено, з font-display: swap і підібраними метриками запасного шрифту.
Додатково шрифти віддаються у форматі woff2 і хешуються в імені файлу, щоб кеш не віддавав стару версію після оновлення гарнітури. Підсумок — критичний текст видно одразу, а зсув залишається в межах, яких не помічає ні користувач, ні метрика стабільності макета.
Часті технічні сумніви
Шрифти рідко живуть у вакуумі: зазвичай це зовнішній сервіс, кілька мов і рідкісні знаки на кшталт тире, лапок-ялинок або символів валют. Нижче — відповіді на те, з чим стикаємося найчастіше.
У нас уже підключено зовнішній сервіс шрифтів — доведеться все переробляти?
Ні. Зовнішній сервіс віддає файли та стилі, але не керує тим, як браузер їх показує. Ми залишаємо підключення, додаємо font-display: swap і метричні фолбеки — тимчасовий системний шрифт із підібраними size-adjust та ascent-override, щоб підміна не зсувала текст.
Далі вирішуємо за ситуацією: якщо сервіс гальмує на першому екрані, переносимо критичні накреслення до себе й віддаємо їх із довгим кешем, а решту залишаємо як є.
Як бути з кількома мовами та рідкісними знаками?
Розбиваємо набір за діапазонами символів: латиниця, кирилиця, іврит, знаки пунктуації — кожен у своєму файлі з unicode-range.
Браузер підтягує лише ті діапазони, які реально зустрілися на сторінці, тому англомовний відвідувач не завантажує кирилицю, а рідкісний знак не тягне за собою весь шрифт.
Для символів, яких немає в основному наборі, задаємо явний фолбек у font-family, щоб замість «квадратика» підставився системний гліф.
Що буде, якщо шрифт не завантажиться взагалі?
Сторінка залишиться читабельною: текст покажеться системним шрифтом, верстка не поїде завдяки метричним фолбекам. Це усвідомлений вибір на користь доступності — відвідувач бачить контент одразу, а накреслення підставляється в міру завантаження.
Перевіряємо сценарій вимкненням мережі в інструментах розробника й звіряємо зсув макета до і після підміни.
Наскільки це складно підтримувати далі?
Правила описуються один раз у конфігурації: які накреслення, які діапазони, який кеш. Далі це частина збірки — при додаванні мови або знака достатньо розширити діапазон, а не переписувати стилі. Ми фіксуємо метрики до і після, щоб зсув макета залишався нульовим при кожному оновленні.
Обговоримо ваше завдання зі шрифтами
Щоб повернутися з оцінкою та планом, а не із загальними словами, нам потрібні вхідні дані щодо вашого проєкту. Шрифтова тема майже завжди впирається в конкретику: які гарнітури вже підключені, звідки завантажуються, де саме «стрибає» верстка. Чим точніші вихідні дані, тим менше ітерацій на узгодження.
Що надіслати для оцінки:
- список гарнітур і накреслень, які використовуються зараз, із зазначенням, де вони хостяться;
- посилання на робочий сайт або стенд, де відтворюється проблема зі зсувом контенту;
- скриншоти або запис метрик зсуву з панелі розробника на повільному з'єднанні;
- дані про те, які браузери та пристрої в пріоритеті за вашою аудиторією;
- вимоги дизайну: які накреслення критичні, які можна замінити системними;
- обмеження щодо хостингу, CDN і політики кешування, якщо вони є;
- контакт людини, яка ухвалює рішення щодо верстки та дизайну.
На виході ви отримаєте план впровадження: які гарнітури залишаємо, які переводимо в локальний хостинг, як налаштовуємо передзавантаження та підміну метрик, які перевірки ставимо у збірку. Плюс оцінку термінів за етапами та перелік правок, які потрібно внести на боці дизайну.
Опишіть завдання — повернемося з оцінкою та планом.







