Сайт отлично выглядит в вашем любимом браузере, но у клиента кнопка уехала, шрифт другой, а форма вообще не отправляется. Знакомая история? Кроссбраузерность никогда не была простой задачей, и хотя современные браузеры сильно сблизились в поддержке стандартов, различия по-прежнему остаются: в отрисовке форм, обработке отступов, поддержке новых возможностей CSS и JavaScript.
Разберём подходы, которые экономят нервы и время, и покажем, как строить вёрстку, устойчивую к различиям.
Откуда берутся различия
Прежде чем бороться с проблемой, полезно понимать её природу. Различия возникают по нескольким причинам.
- Стили по умолчанию. У каждого браузера свои отступы заголовков, списков, форм и таблиц.
- Разная скорость внедрения. Новые свойства CSS появляются в разных движках не одновременно.
- Нестандартное поведение элементов форм. Поля, выпадающие списки и переключатели отрисовываются средствами системы.
- Особенности мобильных браузеров. Адресная строка, динамическая высота экрана, жесты.
- Старые версии. У части аудитории стоят устаревшие браузеры, которые не знают современных возможностей.
Первое, что нужно сделать на проекте, — определить, какие браузеры действительно важны. Посмотрите статистику в Яндекс.Метрике: какие движки и версии используют ваши посетители. Нет смысла тратить недели на поддержку браузера, которым пользуются доли процента.
Сброс и нормализация стилей
Первый шаг к одинаковому отображению — выровнять стартовые условия. Есть два подхода:
- Reset — полностью обнуляет отступы и оформление всех элементов, после чего вы задаёте всё сами.
- Normalize — аккуратно исправляет только реальные различия между браузерами, сохраняя полезные умолчания.
Многие команды пишут свой минимальный набор правил. Вот пример, который почти всегда оправдан:
*,
*::before,
*::after {
box-sizing: border-box;
}
html {
-webkit-text-size-adjust: 100%;
}
body {
margin: 0;
line-height: 1.5;
}
img, video {
max-width: 100%;
height: auto;
}
button, input, select, textarea {
font: inherit;
}
Модель box-sizing: border-box делает расчёт ширины предсказуемым: padding и border входят в заданный размер. Без неё блок шириной в сто процентов с внутренним отступом вылезает за пределы родителя.
Современная раскладка: flexbox и grid
Эпоха вёрстки на плавающих блоках и таблицах прошла. Flexbox и Grid поддерживаются всеми актуальными браузерами и решают большинство задач без хитростей.
.cards {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
gap: 16px;
}
.toolbar {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 8px;
}
Что стоит учитывать:
- У flex-элементов по умолчанию минимальный размер равен размеру содержимого. Длинное слово без переносов может растянуть блок. Лечится правилом
min-width: 0. - Свойство
gapдля flexbox появилось позже, чем для grid, поэтому в старых браузерах вместо него используют отступы у элементов. - Для сложных сеток задавайте запасной вариант раскладки на случай отсутствия поддержки.
Префиксы и автоматизация
Некоторые свойства требуют вендорных префиксов: -webkit-, -moz-. Писать их вручную долго и ненадёжно. Используйте инструмент автоматической расстановки префиксов, который берёт список целевых браузеров и добавляет всё необходимое при сборке. Так вы пишете чистый CSS, а совместимость обеспечивает конвейер.
Задайте список поддерживаемых браузеров в одном месте проекта, чтобы им пользовались и инструмент префиксов, и транспилятор скриптов. Это гарантирует единое понимание, что считается поддерживаемым.
Прогрессивное улучшение вместо костылей
Главная идея устойчивой вёрстки — сначала сделать базовый вариант, работающий везде, а потом добавлять улучшения для современных браузеров. Сайт не обязан выглядеть абсолютно одинаково повсюду. Он должен быть удобным и функциональным.
Практический инструмент — условные правила проверки возможностей:
.layout {
display: block;
}
@supports (display: grid) {
.layout {
display: grid;
grid-template-columns: 1fr 3fr;
}
}
Браузер, не знающий grid, получит простую колонку, а современный — полноценную сетку. То же верно для скриптов: проверяйте наличие возможности, а не название браузера.
if ('IntersectionObserver' in window) {
// ленивая загрузка через наблюдатель
} else {
// загружаем изображения сразу
}
Определение браузера по строке User-Agent ненадёжно и считается плохой практикой. Проверка возможностей надёжнее и честнее.
Формы и интерактивные элементы
Формы — главный источник расхождений. Несколько рекомендаций:
- Наследуйте шрифт у полей через
font: inherit, иначе они выглядят по-разному. - Для кнопок задавайте явный
appearanceи собственное оформление, если нужен единый вид. - Размер шрифта в полях на мобильных устройствах делайте не меньше шестнадцати пикселей, иначе некоторые браузеры приближают страницу при фокусе.
- Используйте правильные типы полей: email, tel, number. Они вызывают подходящую клавиатуру.
- Не полагайтесь только на встроенную проверку. Дублируйте валидацию на сервере.
- Для выпадающих списков, где важен дизайн, лучше применять проверенные доступные компоненты, а не рисовать с нуля.
Мобильные особенности
На смартфонах свои сюрпризы. Обязательно добавьте в страницу метатег viewport, иначе мобильный браузер покажет уменьшенную версию десктопного сайта:
<meta name="viewport" content="width=device-width, initial-scale=1">
Не используйте высоту 100vh для полноэкранных блоков без запасного варианта: на мобильных устройствах адресная строка то появляется, то скрывается, и блок прыгает. Применяйте новые единицы, учитывающие динамический размер экрана, с запасным значением для старых браузеров. Также проверяйте поведение при наведении: на сенсорных экранах hover работает иначе, поэтому ключевые действия не должны зависеть от него.
Тестирование: как проверять
Без проверки на реальных устройствах кроссбраузерность остаётся предположением.
- Составьте матрицу проверки: основные браузеры на настольных и мобильных платформах плюс одна-две устаревшие версии из вашей статистики.
- Используйте инструменты разработчика с эмуляцией устройств, но помните, что это лишь приближение.
- Проверьте хотя бы на нескольких реальных телефонах: разных производителей и разных размеров экрана.
- Воспользуйтесь облачными сервисами проверки, которые запускают страницы на множестве реальных устройств.
- Автоматизируйте сравнение скриншотов для ключевых страниц, чтобы замечать регрессии после изменений.
- Проверяйте отключение скриптов и медленное соединение: сайт должен оставаться понятным.
Частые ошибки
- Разработка в одном браузере и проверка в конце проекта, когда исправлять дороже всего.
- Использование новых возможностей без запасного варианта.
- Хаки и трюки под конкретные версии вместо чистых решений.
- Фиксированные размеры в пикселях там, где нужна гибкость.
- Игнорирование доступности: фокус, клавиатурная навигация, контраст.
- Подключение тяжёлых библиотек ради одной функции.
Заключение
Кроссбраузерность — это не борьба с каждым браузером по отдельности, а дисциплина. Определите реальную аудиторию, выровняйте базовые стили, пользуйтесь flexbox и grid, автоматизируйте префиксы, проверяйте возможности вместо угадывания браузера и тестируйте на настоящих устройствах. Такой подход даёт сайт, который не рассыплется у случайного посетителя, а вам сэкономит часы отладки в самый неподходящий момент.