Руководство по поддержке CSS в браузерах
Опубликовано: 2022-03-10Мы никогда не будем жить в мире, где все, кто просматривает наши сайты, имеют одинаковый браузер и версию браузера, точно так же, как мы никогда не будем жить в мире, где у всех одинаковый размер экрана и разрешение. Это означает, что работа со старыми браузерами — или браузерами, которые не поддерживают то, что мы хотим использовать — является частью работы веб-разработчика. Тем не менее, сейчас все намного лучше, чем в прошлом, и в этой статье я собираюсь рассмотреть различные типы проблем с поддержкой браузеров, с которыми мы можем столкнуться. Я собираюсь показать вам несколько способов справиться с ними, а также посмотреть на вещи, которые могут появиться в ближайшее время и которые могут помочь.
Почему у нас есть эти различия?
Даже в мире, где большинство браузеров основаны на Chromium, не все эти браузеры используют ту же версию Chromium, что и Google Chrome. Это означает, что браузер на основе Chromium, такой как Vivaldi, может отставать от Google Chrome на несколько версий.
И, конечно же, пользователи не всегда быстро обновляют свои браузеры, хотя в последние годы ситуация улучшилась, поскольку большинство браузеров автоматически обновляют себя.
Существует также способ, которым новые функции попадают в браузеры в первую очередь. Дело не в том, что новые функции для CSS разрабатываются Рабочей группой CSS, а полная спецификация передается производителям браузеров с инструкциями по ее реализации. Довольно часто только при экспериментальной реализации могут быть проработаны все более тонкие детали спецификации. Следовательно, разработка функций — это итеративный процесс , требующий, чтобы браузеры реализовывали эти спецификации в процессе разработки. Хотя реализация в наши дни чаще всего происходит за пределами браузера или доступна только в ночной или предварительной версии, как только браузер получит полную функцию, он, вероятно, включит ее для всех, даже если ни один другой браузер еще не поддерживает.
Все это означает, что — как бы нам этого ни хотелось — мы никогда не будем существовать в мире, где функции волшебным образом доступны на каждом компьютере и телефоне одновременно. Если вы профессиональный веб-разработчик, то ваша работа заключается в том, чтобы иметь дело с этим фактом.
Ошибки против отсутствия поддержки
Есть три проблемы, с которыми мы сталкиваемся в отношении поддержки браузеров:
- Нет поддержки функции
Первая проблема (с которой проще всего справиться) — это когда браузер вообще не поддерживает эту функцию. - Работа с «ошибками» браузера
Во-вторых, когда браузер утверждает, что поддерживает эту функцию, но делает это не так, как другие браузеры поддерживают эту функцию. Такую проблему мы склонны называть «ошибкой браузера», потому что конечным результатом является непоследовательное поведение. - Частичная поддержка свойств CSS
Этот становится все более распространенным; ситуация, когда браузер поддерживает функцию, но только в одном контексте.
Когда вы видите разницу между браузерами, полезно понимать, с чем вы имеете дело, поэтому давайте рассмотрим каждую из этих проблем по очереди.
1. Нет поддержки функции
Если вы используете свойство или значение CSS, которое браузер не понимает, браузер проигнорирует его. Это то же самое, если вы используете функцию, которая не поддерживается, или создаете функцию и пытаетесь ее использовать. Если браузер не понимает эту строку CSS, он просто пропускает ее и переходит к следующей вещи, которую понимает.
Этот принцип проектирования CSS означает, что вы можете с радостью использовать новые функции, зная, что ничего плохого не произойдет с браузером, который не поддерживает их. Для некоторых CSS, используемых исключительно в качестве расширения, это все, что вам нужно сделать. Используйте эту функцию, убедитесь, что, когда эта функция недоступна, опыт остается хорошим, и все. Этот подход является основной идеей прогрессивного улучшения с использованием этой функции платформы, которая позволяет безопасно использовать новые вещи в браузерах, которые их не понимают.
Если вы хотите проверить, поддерживается ли используемая вами функция браузерами, вы можете посетить веб-сайт Can I Use. Еще одним хорошим местом для поиска подробной информации о поддержке является страница для каждого свойства CSS в MDN. Данные о поддержке браузера там, как правило, очень подробные.
Новый CSS понимает старый CSS
По мере разработки новых функций CSS особое внимание уделяется тому, как они взаимодействуют с существующим CSS. Например, в спецификации Grid и Flexbox подробно описано, как display: grid
и display: flex
работают с такими сценариями, как плавающий элемент становится элементом сетки или контейнер с несколькими столбцами превращается в сетку. Это означает, что определенные действия игнорируются, что позволяет просто перезаписать CSS для неподдерживающего браузера. Эти переопределения подробно описаны на странице «Прогрессивное улучшение и макет сетки» в MDN.
Обнаружение поддержки с помощью функциональных запросов
Вышеупомянутый метод работает только в том случае, если CSS, который вам нужно использовать, не нуждается в других свойствах. Возможно, вам потребуется добавить дополнительные свойства в свой CSS для старых браузеров, которые затем также будут интерпретироваться браузерами, поддерживающими эту функцию.
Хороший пример этого можно найти при использовании Grid Layout. В то время как плавающий элемент, который становится элементом сетки, теряет все плавающие свойства, вполне вероятно, что если вы пытаетесь создать запасной вариант для макета сетки с плавающим элементом, вы добавите процентную ширину и, возможно, поля для элементов.
.grid > .item { width: 23%; margin: 0 1%; }

%
. (Большой превью)Эти значения ширины и полей будут по-прежнему применяться, когда плавающий элемент является элементом сетки. Ширина становится процентом от дорожки сетки, а не полной ширины контейнера; затем будет применено любое поле, а также зазор, который вы, возможно, указали.
.grid > .item { width: 23%; margin: 0 1%; } .grid { display: grid; grid-template-columns: 1fr 1fr 1fr 1fr; column-gap: 1%; }

К счастью, есть функция, встроенная в CSS и реализованная в современных браузерах, которая помогает нам справиться с этой ситуацией. Запросы функций позволяют нам напрямую запрашивать у браузера, что он поддерживает, а затем действовать в соответствии с ответом. Точно так же, как Media Query, который проверяет некоторые свойства устройства или экрана, Feature Queries проверяет поддержку свойства и значения CSS.
Тест на поддержку
Тестирование поддержки — самый простой случай, мы используем @supports
, а затем проверяем свойство и значение CSS. Контент внутри Feature Query будет работать только в том случае, если браузер ответит true, т. е. он поддерживает эту функцию.
Тест на отсутствие поддержки
Вы можете запросить браузер, если он не поддерживает функцию. В этом случае код внутри Feature Query будет выполняться только в том случае, если браузер указывает, что он не поддерживается.
@supports not (display: grid) { .item { /* CSS from browsers which do not support grid layout */ } }
Тест на несколько вещей
Если вам нужно поддерживать более одного свойства, используйте and
.
@supports (display: grid) and (shape-outside: circle()){ .item { /* CSS from browsers which support grid and CSS shapes */ } }
Если вам нужна поддержка того или иного свойства, используйте or
.
@supports (display: grid) or (display: flex){ .item { /* CSS from browsers which support grid or flexbox */ } }
Выбор свойства и значения для тестирования
Вам не нужно тестировать каждое свойство, которое вы хотите использовать — достаточно того, что укажет на поддержку функций, которые вы планируете использовать. Поэтому, если вы хотите использовать Grid Layout, вы можете протестировать display: grid
. В будущем (и как только поддержка подсетки появится в браузерах) вам, возможно, придется быть более конкретным и протестировать функциональность подсетки. В этом случае вы должны проверить grid-template-columns: subgrid
, чтобы получить истинный ответ только от тех браузеров, которые реализовали поддержку подсетки.
Если мы теперь вернемся к нашему примеру с плавающим запасным вариантом, мы увидим, как функциональные запросы упорядочат его для нас. Что нам нужно сделать, так это запросить у браузера, поддерживает ли он сетку. Если это так, мы можем установить ширину элемента обратно на auto
и margin на 0
.

.grid > .item { width: 23%; margin: 0 1%; } @supports(display: grid) { .grid { display: grid; grid-template-columns: 1fr 1fr 1fr 1fr; column-gap: 1%; } .grid > .item { width: auto; margin: 0; } }
См. Pen Feature Queries and Grid (Рэйчел Эндрю) на CodePen.
Обратите внимание, что, хотя я включил весь код сетки в свой запрос функции, мне это не нужно. Если браузер не понимает свойства сетки, он будет игнорировать их, чтобы они могли безопасно находиться за пределами запроса функции. В этом примере внутри запроса функции должны быть свойства поля и ширины, поскольку они необходимы для старого кода браузера, но также могут применяться поддерживающими браузерами.
Объятия Каскад
Очень простой способ предложить запасные варианты — использовать тот факт, что браузеры игнорируют CSS, который они не понимают, и тот факт, что там, где все остальное имеет одинаковую специфичность, исходный порядок учитывается с точки зрения того, какой CSS применяется к элементу. .
Сначала вы пишете свой CSS для браузеров, которые не поддерживают эту функцию. Затем проверьте поддержку свойства, которое вы хотите использовать, если браузер подтвердит, что он поддерживает, перезапишите резервный код новым кодом.
Это почти та же процедура, которую вы можете использовать при использовании медиа-запросов для адаптивного дизайна, следуя подходу, ориентированному на мобильные устройства. При таком подходе вы начинаете с макета для небольших экранов, а затем добавляете или перезаписываете что-то для больших по мере продвижения вверх по контрольным точкам.
Приведенный выше способ работы означает, что вам не нужно беспокоиться о браузерах, которые не поддерживают Feature Queries. Как вы можете видеть из Can I Use , Feature Queries имеют действительно отличную поддержку. Выдающиеся браузеры, которые не поддерживают их, являются любой версией Internet Explorer.
Однако вполне вероятно, что новая функция, которую вы хотите использовать, также не поддерживается в IE. Итак, в настоящее время вы почти всегда начинаете с написания CSS для браузеров без поддержки, а затем тестируете с помощью Feature Query. Этот запрос функции должен быть проверен на поддержку.
- Браузеры, поддерживающие Feature Queries, вернут true, если у них есть такая поддержка, поэтому будет использоваться код внутри запроса, перезаписывая код для более старых браузеров.
- Если браузер поддерживает запросы функций, но не поддерживает тестируемую функцию, он вернет false. Код внутри запроса функции будет проигнорирован.
- Если браузер не поддерживает Feature Queries, то все, что находится внутри блока Feature Query, будет проигнорировано, а это означает, что такой браузер, как IE11, будет использовать ваш старый код браузера, что, скорее всего, именно то, что вам нужно!
2. Работа с «ошибками» браузера
К счастью, вторая проблема с поддержкой браузера становится менее распространенной. Если вы прочтете «Чего мы желали» (опубликовано в конце прошлого года), вы сможете получить небольшую экскурсию по некоторым наиболее непонятным ошибкам браузера прошлого. Тем не менее, любое программное обеспечение может иметь ошибки, браузеры не являются исключением. И, если мы добавим к этому тот факт, что из-за циклического характера реализации спецификации иногда браузер что-то реализовывал, а затем спецификация менялась, поэтому теперь им нужно выпустить обновление. Пока это обновление не будет выпущено, мы можем оказаться в ситуации, когда браузеры делают что-то отличное друг от друга.
Feature Queries не может нам помочь, если браузер сообщает о поддержке чего-то, что плохо поддерживает его. Нет режима, с помощью которого браузер может сказать: « Да, но вам это, скорее всего, не понравится ». Когда появляется реальная ошибка взаимодействия, именно в этих ситуациях вам может потребоваться немного больше творчества.
Если вы думаете, что видите ошибку, первое, что нужно сделать, это подтвердить это. Иногда, когда нам кажется, что мы видим ошибочное поведение и браузеры делают разные вещи, вина лежит на нас. Возможно, мы использовали какой-то недопустимый синтаксис или пытаемся стилизовать искаженный HTML. В этих случаях браузер попытается что-то сделать; однако, поскольку вы не используете языки в том виде, в каком они были разработаны, каждый браузер может работать по-разному. Быстрая проверка правильности HTML и CSS — отличный первый шаг.
В этот момент я, вероятно, сделал бы быстрый поиск и посмотрел, была ли моя проблема уже широко понята. Есть несколько репозиториев известных проблем, например, Flexbugs и Gridbugs. Тем не менее, даже несколько хорошо подобранных ключевых слов могут привести к публикациям или статьям о переполнении стека, которые охватывают эту тему, и могут предоставить вам обходной путь.
Но предположим, что вы на самом деле не знаете, что вызывает ошибку, что затрудняет поиск решения. Итак, следующий шаг — создать сокращенный тестовый пример вашей проблемы, т. е. удалить все нерелевантное, чтобы помочь вам точно определить, что вызывает ошибку. Если вы думаете, что у вас есть ошибка CSS, можете ли вы удалить какой-либо JavaScript или воссоздать тот же стиль вне фреймворка? Я часто использую CodePen, чтобы собрать уменьшенный тестовый пример того, что я вижу; у этого есть дополнительное преимущество, заключающееся в том, что код предоставляется мне таким образом, что я могу легко поделиться с кем-то еще, если мне нужно спросить об этом.
В большинстве случаев после того, как вы изолировали проблему, можно придумать альтернативный способ достижения желаемого результата. Вы обнаружите, что кто-то еще придумал хитрый обходной путь, или вы можете написать где-нибудь, чтобы спросить предложения.
С учетом сказанного, если вы считаете, что у вас есть ошибка браузера, и не можете найти кого-либо еще, говорящего о той же проблеме, вполне возможно, что вы нашли что-то новое, о чем следует сообщить. Со всеми новыми CSS, появившимися в последнее время, иногда могут возникать проблемы, когда люди начинают использовать вещи в сочетании с другими частями CSS.
Прочтите этот пост от Леи Веру о сообщениях о таких проблемах: «Помогите сообществу! Сообщайте об ошибках браузера!». В статье также есть отличные советы по созданию сокращенного тестового примера.
3. Частичная поддержка свойств CSS
Третий тип проблем стал более распространенным из-за того, как разработаны современные спецификации CSS. Если мы подумаем о Grid Layout и Flexbox, обе эти спецификации используют свойства и значения Box Alignment Level 3 для выравнивания. Поэтому такие свойства, как align-items
, justify-content
и column-gap
, предназначены для использования как в Grid, так и во Flexbox, а также в других методах компоновки.
Однако на момент написания статьи свойства gap
работали в макете сетки во всех браузерах, поддерживающих сетку, а column-gap
работает в Multicol; однако только Firefox реализовал эти свойства для Flexbox.
Если бы я использовал поля для создания запасного варианта для Flexbox, а затем проверил column-gap
и удалил поля, между моими блоками не было бы пробела в браузерах, поддерживающих column-gap
в сетке или многоцветном, поэтому мой резервный интервал будет удаленный.
@supports(column-gap: 20px) { .flex { margin: 0; /* almost everything supports column-gap so this will always remove the margins, even if we do not have gap support in flexbox. */ } }
Это текущее ограничение функциональных запросов. У нас нет способа проверить поддержку функции в другой функции. В приведенной выше ситуации я хочу спросить браузер: «Есть ли у вас поддержка зазора между столбцами во Flexbox?» Таким образом, я могу получить отрицательный ответ, чтобы использовать запасной вариант.
Аналогичная проблема возникает со свойствами фрагментации CSS break-before
, break-after
и break-inside
. Поскольку они имеют лучшую поддержку при печати страницы, браузеры часто требуют поддержки. Однако, если вы проверяете поддержку в multicol, вы получаете то, что кажется ложным срабатыванием. Я поднял вопрос в Рабочей группе CSS по этому вопросу, однако решить его не так-то просто. Если у вас есть мысли, пожалуйста, добавляйте их туда.
Тестирование поддержки селекторов
В настоящее время запросы функций могут проверять только свойства и значения CSS. Еще одна вещь, которую мы хотели бы протестировать, — это поддержка новых селекторов, таких как те, что находятся на уровне 4 спецификации селекторов. Существует пояснительная записка, а также реализация за флагом в Firefox Nightly новой функции для запросов функций, которая позволит достичь этого.
Если вы посетите about:config
в Firefox и включите флаг layout.css.supports-selector.enabled
, вы сможете проверить, поддерживаются ли различные селекторы. Синтаксис в настоящее время очень прост, например, для проверки селектора : :has
:
@supports selector(:has){ .item { /* CSS for support of :has */ } }
Это спецификация находится в разработке, однако вы можете видеть, как добавляются функции, помогающие нам справляться с постоянными проблемами поддержки браузеров, пока мы говорим.
Дальнейшее чтение
Это может показаться разочаровывающим, когда вы хотите использовать функцию и обнаруживаете, что она не поддерживается одним основным браузером, или если кажется, что все работает по-разному. Я собрал некоторые практические дополнительные материалы, которые могут помочь.
- Параметры «Использование CSS Grid: поддержка браузеров без сетки» для работы со старыми браузерами и CSS Grid
- Справочная страница MDN «Feature Queries» для функциональных запросов
- Руководство MDN «CSS Grid And Progressive Enhancement» по прогрессивному улучшению Grid
- Руководство MDN «Обратная совместимость Flexbox» по поддержке Flexbox, включая сведения о более старых реализациях с префиксами
- «Сначала библиотека шаблонов» Как управлять резервным кодом с помощью библиотеки шаблонов