Содержание статьи

Safari на macOS и Windows (до версии 5.1.7) использует движок WebKit, но с рядом специфичных особенностей, которые отличают его от Chrome или Firefox. По данным StatCounter за 2023 год, доля Safari среди настольных браузеров составляет около 10%, а среди пользователей macOS – более 50%. Игнорирование этих нюансов приводит к багам в верстке, некорректной работе скриптов и ухудшению производительности.
Основные проблемы адаптации связаны с поддержкой CSS-свойств, обработкой JavaScript и особенностями рендеринга. Например, Safari до сих пор не полностью поддерживает CSS Grid Level 2 (поддержка появилась только в версии 16.4), а свойство gap для flex-контейнеров работает с ошибками в версиях до 14.1. Для проверки совместимости используйте инструмент Can I Use с фильтром по Safari или встроенный в браузер Web Inspector (Cmd + Option + I).
Ключевые шаги адаптации включают тестирование на реальных устройствах с macOS, а не только в эмуляторах. Safari на Windows устарел, но если целевая аудитория включает пользователей старых версий, проверяйте сайт в Safari 5.1.7 через виртуальную машину или сервисы вроде BrowserStack. Особое внимание уделите:
- Flexbox и Grid: используйте вендорные префиксы (
-webkit-) для свойств вродеflex-wrapилиgrid-template-areas. - Шрифты: Safari не поддерживает формат
woff2в версиях до 10.1, поэтому подключайте резервные форматы (woff,ttf). - JavaScript: избегайте методов
Array.prototype.at()иString.prototype.replaceAll()без полифилов – они не работают в Safari до версии 15.4.
Для отладки производительности используйте вкладку Timelines в Web Inspector. Safari часто тормозит на анимациях с transform и opacity, если они не оптимизированы. Рекомендуется:
- Заменять
requestAnimationFrameнаsetTimeoutдля сложных анимаций в старых версиях. - Отключать аппаратное ускорение для элементов с
position: fixedчерезwill-change: transform. - Тестировать загрузку ресурсов с медленным соединением через режим Network Link Conditioner в macOS.
Не забывайте про специфичные для Safari баги: например, position: sticky не работает внутри overflow: hidden до версии 13.1, а background-clip: text требует вендорного префикса. Для автоматического добавления префиксов используйте Autoprefixer с настройкой "safari >= 10" в конфигурации.
Проверка поддержки CSS-свойств в Safari

Safari – единственный браузер на движке WebKit, который регулярно отстаёт в поддержке современных CSS-свойств. Версии до 15.4 не поддерживают aspect-ratio, gap для flex-контейнеров и subgrid. Проверяйте актуальные данные на Can I Use, фильтруя по Safari и macOS/iOS.
, gap для flex-контейнеров и subgrid. Проверяйте актуальные данные на Can I Use, фильтруя по Safari и macOS/iOS.»>
Для тестирования используйте инструмент @supports с явными проверками. Пример: @supports (aspect-ratio: 1/1) { ... }. Safari игнорирует правила внутри блока, если свойство не поддерживается, но не всегда корректно обрабатывает сложные условия с логическими операторами and/or.
В Safari 16.4+ появилась поддержка container queries, но с багом: вложенные контейнеры не обновляют стили при изменении размеров родителя. Решение – добавлять явный resize: both на родительский элемент или использовать полифилл container-query-polyfill.
Свойство backdrop-filter работает в Safari с префиксом -webkit-, но вызывает артефакты при анимации или наложении нескольких фильтров. Ограничьте область применения с помощью will-change: transform и тестируйте на реальных устройствах – симулятор Xcode не всегда воспроизводит баги.
Для проверки поддержки scroll-snap используйте JavaScript: CSS.supports('scroll-snap-align', 'start'). Safari поддерживает синтаксис, но игнорирует scroll-snap-stop: always и некорректно обрабатывает scroll-margin на flex-элементах. Альтернатива – библиотека scroll-snap.
Свойство accent-color поддерживается с Safari 15.4, но не работает с кастомными радиокнопками и чекбоксами, стилизованными через appearance: none. Для совместимости дублируйте цвет вручную через background-color и border-color.
Проверяйте поддержку CSS-переменных в медиазапросах: Safari до версии 16.4 не поддерживает @media (min-width: calc(var(--breakpoint) + 1px)). Используйте фиксированные значения или препроцессоры для генерации медиазапросов.
Для тестирования Grid Layout используйте display: grid с явным указанием grid-template-areas. Safari некорректно рендерит неявные треки при отсутствии grid-auto-rows или grid-auto-columns. Всегда задавайте их явно, даже если используете auto.
Исправление проблем с шрифтами и рендерингом текста

Safari на macOS использует движок WebKit, который по-разному обрабатывает шрифты по сравнению с Blink (Chrome) или Gecko (Firefox). Основные проблемы возникают с кастомными шрифтами, загружаемыми через @font-face, и рендерингом системных шрифтов, таких как San Francisco. Проверьте поддержку форматов: Safari до версии 14 не поддерживает WOFF2 без дополнительных полифилов, а в версиях 14+ возможны артефакты при использовании переменных шрифтов (variable fonts).
Для диагностики откройте инструменты разработчика (Cmd+Opt+I) и перейдите во вкладку «Fonts». Если шрифт отображается как «Last Resort» или системный fallback, добавьте явное правило font-display: swap в @font-face. Это ускорит загрузку текста, но может вызвать FOIT (Flash of Invisible Text) – используйте font-display: block с таймаутом в 3 секунды для критически важных шрифтов.
Safari часто рендерит текст с размытием или некорректным кернингом из-за особенностей субпиксельного сглаживания. Отключите его принудительно через CSS: -webkit-font-smoothing: antialiased. Для моноширинных шрифтов (например, в коде) добавьте font-variant-ligatures: none, чтобы избежать слипания символов. Если текст выглядит «жирнее» чем в других браузерах, уменьшите font-weight на 100 единиц для Safari через медиа-запрос @supports (-webkit-touch-callout: none).
Проблемы с рендерингом китайских, японских или корейских символов (CJK) в Safari решаются указанием конкретных шрифтовых семейств. Вместо font-family: sans-serif используйте явный список: «Hiragino Sans», «PingFang SC», «Microsoft YaHei», sans-serif. Для вертикального текста (writing-mode: vertical-rl) Safari требует дополнительного свойства text-orientation: mixed, иначе символы могут отображаться горизонтально.
Если кастомный шрифт «скачет» при загрузке страницы, предзагрузите его через . Safari игнорирует атрибут crossorigin для шрифтов без него, что приводит к двойной загрузке. Проверьте заголовки CORS на сервере: Access-Control-Allow-Origin должен быть настроен для домена, с которого загружается шрифт.
Для системного шрифта San Francisco в macOS/iOS используйте -apple-system или system-ui в font-family. Safari некорректно обрабатывает font-weight для этих значений – задавайте вес явно (например, font-weight: 500 вместо medium). Избегайте использования font-stretch: Safari до версии 16 не поддерживает это свойство, что может сломать отображение переменных шрифтов.
Тестируйте рендеринг текста на реальных устройствах: симулятор Xcode не передает все нюансы субпиксельного сглаживания и цветопередачи Retina-дисплеев. Для проверки используйте инструмент «Color Picker» в macOS, чтобы сравнить оттенки текста в Safari и других браузерах. Если разница критична, скорректируйте цвет через цветовые профили (например, Display P3 для широкого охвата).
Настройка отображения flexbox и grid-макетов

Safari на macOS и iOS поддерживает flexbox и CSS Grid, но с нюансами. Для flexbox добавьте -webkit- префиксы к свойствам flex-direction, flex-wrap и align-items, если версия браузера ниже 14.1 (2021 год). Grid-макеты требуют явного указания grid-template-areas или grid-template-columns с фиксированными размерами – Safari до 16.4 (2023) игнорирует minmax() в авторазмерах. Проверяйте рендеринг через Responsive Design Mode (Cmd+Opt+R) с эмуляцией устройств iPhone/iPad, так как Safari на iOS использует другой движок.
Используйте display: -webkit-box для горизонтального выравнивания в старых версиях Safari (до 10.1), но избегайте его в современных проектах – замените на display: flex с gap: 1rem и проверкой через caniuse. Для Grid добавляйте grid-auto-flow: dense, чтобы Safari корректно обрабатывал пустые ячейки. Тестируйте макеты на реальных устройствах: Safari на macOS и iOS по-разному интерпретирует fr-единицы и выравнивание по subgrid (поддержка с версии 16.0).
Обработка специфичных багов JavaScript в Safari

Safari – единственный браузер, где Date.parse() может возвращать NaN для строк в формате ISO 8601 с миллисекундами (например, "2024-05-20T12:34:56.789Z"). Обходной путь: парсить дату вручную через new Date() с разбиением строки или использовать библиотеку date-fns.
Метод Array.prototype.at() появился в Safari только с версии 15.4. Для обратной совместимости замените его на array[array.length - 1] или используйте полифилл через core-js. Проверяйте поддержку через 'at' in Array.prototype.
window.scrollTo({ behavior: 'smooth' })игнорируется в Safari до версии 15.2. Альтернатива:element.scrollIntoView({ behavior: 'smooth' })или библиотекаsmoothscroll-polyfill.- В Safari 14 и ниже
IntersectionObserverможет срабатывать с задержкой до 300 мс. Установитеthreshold: 0.01и проверяйтеisIntersectingв колбэке.
Ошибка TypeError: 'undefined' is not a function при работе с Intl возникает, если локаль не поддерживается (например, ru-RU в старых версиях). Проверяйте доступность через Intl.DateTimeFormat.supportedLocalesOf(['ru-RU']).length и подставляйте резервную локаль.
Safari некорректно обрабатывает fetch() с заголовком Accept: application/json при ответе с кодом 204. Сервер должен возвращать Content-Type: application/json даже для пустого тела. Альтернатива: использовать XMLHttpRequest для таких запросов.
- Проблема с
WeakMapиWeakSet: в Safari до версии 14.1 они не поддерживают примитивы (string,number) в качестве ключей. ИспользуйтеMapили оборачивайте значения в объекты. - Метод
String.prototype.replaceAll()отсутствует в Safari до 13.1. Полифилл:str.split(search).join(replace)илиcore-js. - Ошибка
SecurityErrorпри доступе кlocalStorageв приватном режиме. Оберните вызов вtry-catchи используйте резервное хранилище (например,sessionStorage).
Safari не поддерживает AbortController для fetch() в версиях до 12.1. Для отмены запросов используйте XMLHttpRequest.abort() или библиотеку axios с полифиллом. Проверяйте поддержку через 'signal' in new Request('').
В Safari 13 и ниже Promise.allSettled() отсутствует. Полифилл: реализуйте вручную через Promise.all() с оберткой для каждого промиса в Promise.resolve() и обработкой ошибок. Пример:
Promise.allSettled = (promises) =>
Promise.all(promises.map(p =>
Promise.resolve(p).then(
v => ({ status: 'fulfilled', value: v }),
e => ({ status: 'rejected', reason: e })
)
));
Тестирование медиазапросов и адаптивности под Retina-дисплеи

Retina-дисплеи Apple используют плотность пикселей 220 PPI и выше, что требует проверки медиазапросов с учетом -webkit-min-device-pixel-ratio: 2. В Safari откройте инструменты разработчика (Cmd + Opt + I) и переключитесь на режим эмуляции устройств. В разделе «Device» выберите «Responsive» и вручную задайте разрешение, например, 1440×900 с плотностью 2x. Это позволит выявить проблемы с размытием шрифтов или растровых изображений, которые не масштабируются корректно.
Для тестирования адаптивных изображений используйте атрибут srcset с дескрипторами 2x. Пример: <img src="image-1x.jpg" srcset="image-1x.jpg 1x, image-2x.jpg 2x">. В Safari проверьте загрузку версии 2x через панель «Network» в инструментах разработчика – фильтруйте запросы по типу «Img» и ищите файл с суффиксом @2x. Если браузер игнорирует srcset, убедитесь, что сервер отдает корректные заголовки Content-Type: image/jpeg.
Шрифты на Retina-дисплеях должны рендериться с субпиксельным сглаживанием. В Safari включите отладку рендеринга через Cmd + Opt + R и активируйте опцию «Show Compositing Borders». Если текст выглядит размытым, замените системные шрифты на векторные (например, font-display: swap с @font-face) или увеличьте font-weight на 100 единиц для компенсации сглаживания. Избегайте text-rendering: optimizeLegibility – на Retina он может ухудшать четкость.
CSS-градиенты и тени на Retina-дисплеях требуют повышенной детализации. Увеличьте разрешение градиентов в 2 раза: background: linear-gradient(to right, #fff 0%, #000 200%); вместо стандартных 100%. Для теней используйте box-shadow: 0 0 2px rgba(0,0,0,0.5); с удвоенным радиусом размытия. Проверяйте результат в режиме «Zoom: 100%» – Safari на Retina автоматически масштабирует элементы, но при зуме 200% артефакты становятся заметнее.
Интерактивные элементы (кнопки, иконки) должны иметь минимальный размер 44×44 пикселя в физических координатах. На Retina это соответствует 22×22 CSS-пикселям. Используйте @media (-webkit-min-device-pixel-ratio: 2) для подмены SVG-иконок на версии с удвоенной детализацией. В инструментах разработчика Safari включите «Show Layer Borders» – если слой элемента меньше 44×44 пикселя, Safari может игнорировать касания на Retina-дисплеях.
Для финальной проверки используйте реальное устройство с macOS и Retina-экраном. В Safari откройте сайт и выполните команду Cmd + Shift + 4, затем выделите область экрана – в скриншоте будут видны реальные пиксели. Сравните результат с эмуляцией в браузере: если на скриншоте элементы выглядят четче, чем в инструментах разработчика, скорректируйте медиазапросы или ресурсы под реальное разрешение.
