В веб-разработке не так просто добиться идеально масштабируемого дизайна для разных браузеров и устройств. Трудности могут возникать везде: от настройки стиля для экранов разных устройств до переопределения стилей, попавших в наш код неизвестно откуда.

Распространённая причина переопределения стилей — это конфликты специфичности. В этом случае можно просто добавить в стиль свойство !important,  повысив его приоритет по сравнению с остальными стилями. Но мир CSS не стоит на месте: появляются новые подходы к решению этих проблем. Один из вариантов — каскадные слои CSS.

В этой статье мы рассмотрим каскадные слои CSS и, в частности, ключевое слово revert-layer, с помощью которого можно усовершенствовать работу со стилями. Разберёмся в принципе действия каскадных слоёв, узнаем, когда и для чего их стоит использовать, и когда применять ключевое слово revert-layer.

Немного о каскадных слоях CSS

Каскадные слои вводят новую директиву @layer. Эта директива отлично подходит для работы с несколькими источниками CSS, когда автору разрешается определять и упорядочивать правило или схему расположения слоёв CSS, чтобы избежать конфликтов специфичности.

Как только вы решили применить свойство !important в настройках CSS, пора использовать каскадные слои, так как эта функция идеально сюда подходит. Другая ситуация, в которой имеет смысл применять каскадные слои — это конфликт селекторов и специфичности CSS.

Мы ещё вернёмся к сценариям использования cascade-layers, а пока что давайте рассмотрим пример. В этом коде у нас два каскадных слоя:

@layer base, special;

@layer special {
    .item {
        color: red;
    }
}

@layer base {
    .item {
        color: blue;
    }
}

Мы определили схему наслоения двух слоёв — base и special. Также мы определённым образом упорядочили слои: слой special оказывается важнее и приоритетнее слоя base.

Это значит, что мы можем использовать несколько источников CSS или разные слои. Но вместо использования специфичности селекторов или свойства !important можно определить порядок слоёв и переопределить стиль, который нам нужен.

Цель этой статьи — изучить ключевое слово каскадного стиля revert-layer, а заодно рассмотреть некоторые сценарии его использования. В статье будем оперировать некоторыми терминами CSS:

  • User-agent (пользовательский агент) — браузер;

  • User (пользователь) — посетитель сайта;

  • Author (автор) — разработчик, то есть вы;

  • User-agent origin (стили браузера) — стиль браузера или стили, по умолчанию применяемые в браузере;

  • User origin (пользовательские стили) — стиль в CSS, добавленный пользователем или посетителем сайта;

  • Author origin (авторские стили) — стиль, добавленный разработчиком (то есть все стили из внешней таблицы стилей).

Вы всегда можете вернуться и посмотреть здесь терминологию. А мы углубляемся дальше в тему.

Что такое revert-layer в CSS

revert-layer — это ключевое слово или значение CSS, которое позволяет откатить назад каскадный слой, вернувшись к значению соответствующего свойства предыдущего каскадного слоя. Иными словами, это откат к исходному значению, заданному автором.

Но если для этого свойства не задан соответствующий набор стилей, произойдёт возврат к стилям браузера по умолчанию.

Ключевое слово revert-layer можно применить к любому свойству, включая собирательное свойство all. В качестве примера приведу этот код:

/* index.html */

<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta
            name="viewport"
            content="width=device-width, initial-scale=1.0"
        />
        <title>Understanding CSS revert-layer</title>
        <link
            rel="stylesheet"
            href="style.css"
        />
    </head>
    <body>
        <h1>Hello World</h1>
        <ul>
            <li class="item feature">Item one</li>
            <li class="item">Item two</li>
            <li class="item">Item three</li>
        </ul>
    </body>
</html>

В этом коде у нас есть заголовочный элемент и список элементов. Теперь давайте напишем наш CSS:

/* style.css */

@layer base, special;

@layer special {
    .item {
        color: red;
    }
}

@layer base {
    .item {
        color: blue;
    }
    .feature {
        color: green;
    }
}

Как и в предыдущем примере, здесь у нас два слоя. Все элементы будут красными (red), потому что в схеме слоя special — с максимальным приоритетом — для свойства color задано значение red.

Если мы поменяем порядок слоёв и сделаем приоритетным *@layer* special, base;, то все элементы станут синими, за исключением первого элемента, который будет зелёным. Это произойдёт из-за приоритета специфичности, так как стиль .feature следует после стиля .item:

Чтобы использовать ключевое слово revert-layer, давайте добавим эти стили:

/* style.css */

@layer base, special;

@layer special {
    .item {
        color: red;
    }
    .feature {
        color: revert-layer;
    }
}

@layer base {
    .item {
        color: blue;
    }
    .feature {
        color: green;
    }
}

Внутри нашего слоя special мы задаём значение цвета, равное revert-layer в селекторе элемента .feature.

В результате весь список элементов становится красным, а элемент .feature — зелёным, потому что происходит откат к соответствующему свойству предыдущего каскадного слоя, для которого мы задали значение green.

Дополню это объяснение:

  • В соответствии с порядком наших слоёв @layer special имеет приоритет над @layer base, так как стили в @layer special идут до @layer base.

  • Значение цвета для селектора .feature — revert-layer указано в @layer special.

  • Так как у нас есть значение  revert-layer, свойство «цвет» для .feature отсылается к предыдущему слою, чтобы использовать прописанное в нём значение. В нашем случае предыдущий слой — это @layer base.

  • Внутри @layer base есть соответствующий селектор .feature, у которого тоже есть свойство color: green, и именно оттуда он берёт это значение.

Если удалить соответствующий селектор .feature из @layer base, элемент становится синим: происходит откат к стилям браузера, в которых задан чёрный, но у нас есть другой класс item со свойством color: blue.

Наоборот, если для соответствующего селектора это свойство не задано, происходит возврат или откат к стилям браузера. Вот HTML-код:

<ul>
    <li class="feature">Item one</li>
    <li class="item">Item two</li>
    <li class="item">Item three</li>
  </ul>

А вот CSS:

@layer base, special;
@layer special {
    .item {
        color: red;
    }
    .feature {
        color: revert-layer;
    }
}
@layer base {
    .item {
        color: blue;
    }
}

Исходя из вышесказанного, какого цвета будет каждый элемент списка? Давайте посмотрим:

Сценарии использования revert-layer в CSS

Хотя revert-layer появился относительно недавно и используется ещё не очень активно, у него есть свои преимущества для ряда сценариев.

Модульные стили

Первый сценарий использования revert-layer — модульные стили. Это как раз то, что мы рассматривали в первой части статьи. Ключевое слово revert-layer помогает выполнить откат к стилям модуля или элемента:

@layer base, special;

@layer base {
    .button {
        background-color: #4caf50;
        color: white;
        padding: 10px 30px;
        border: none;
        border-radius: 5px;
        cursor: pointer;
    }
}

@layer special {
    .button {
        background-color: revert-layer;
        color: revert-layer;
        border: revert-layer;
        border-radius: revert-layer;
        cursor: revert-layer;
        padding: 8px 20px;
    }
}

Здесь мы сохранили все остальные свойства и изменили только внутренние отступы. Вот как выглядит результат:

Сброс глобального стиля

Если вы использовали ключевое слово revert, то знаете, что оно удаляет авторские стили и выполняет откат к пользовательским стилям или стилям браузера.

Чтобы лучше понять этот сценарий использования, давайте на примерах ниже рассмотрим разницу между revert и revert-layer.

Разберём пример с ключевым словом revert:

@layer base, special;

@layer special {
    .item {
        color: red;
    }
    .feature {
        color: revert;
    }
}
@layer base {
    .item {
        color: blue;
    }
}

В этом сценарии:

  • Все элементы будут красными, поскольку для селектора .item задано свойство color: red.

  • Но у селектора .feature, имеющего более высокий приоритет в силу специфичности, будет указанный цвет. В этом случае мы применяем ключевое слово revert.

  • Далее оно возвращается к пользовательскому стилю или стилю браузера. Получаем чёрный цвет, так как в стиле браузера по умолчанию все элементы чёрные.

Ключевое слово revert не учитывает, есть ли другой слой с такой же стилизацией. Оно просто выполняет откат к пользовательскому стилю или стилю браузера.

Вот результат применения вышеприведённого кода:

Теперь давайте рассмотрим пример использования ключевого слова revert-layer:

@layer base, special;

@layer special {
    .item {
        color: red;
    }
    .feature {
        color: revert-layer;
    }
}
@layer base {
    .item {
        color: blue;
    }
}

В результате применения ключевого слова revert-layer элемент .feature станет синим из-за отката к стилям предыдущего слоя. В нашем случае для элемента задан стиль blue в @layer base. Откат к пользовательскому стилю и стилю браузера происходит, только если в предыдущем слое нет похожего селектора. Вот результат:

Идём дальше. Давайте на следующем примере посмотрим, как использовать revert-layer для глобального обнуления свойств:

&,
* {
    all: revert;
}

@layer base, special;

@layer special {
    .item {
        color: red;
    }
    .feature {
        color: revert-layer;
    }
}

@layer base {
    .item {
        color: blue;
    }
}

Результат исполнения этого кода показан на рисунке ниже. При использовании revert-layer он сбрасывает все настройки стиля к заданному по умолчанию стилю браузера:

А вот revert-layer оказывается очень кстати, потому что он выполняет откат к предыдущим настройкам стиля, и в некоторых случаях он удобнее, чем revert. Можно обновить код следующим образом:

&,
* {
    all: revert-layer;
}

...

Сброс стилей внутри слоёв

Ключевое слово revert-layer действительно можно использовать для выполнения отката к предыдущему заданному по умолчанию стилю браузера. Теперь давайте рассмотрим сценарий, когда нам нужно ввести новый слой стилизации.

Например, у нас есть большая база сложного кода, и мы не хотим допустить конфликты стилей, испортив дизайн. Чтобы эффективно решить эту проблему, можно переместить текущий дизайн в слой, а потом создать новый слой.

Давайте рассмотрим код:

@layer oldStyles, newStyles;

@layer oldStyles {
    .item {
        color: red;
    }
    .feature {
        color: #008000;
    }
}

@layer newStyles {
    &,
    * {
        all: revert-layer;
    }

    /* ... new styles here */
    .feature {
        color: purple;
    }
}

Мы переместили старые стили в слой под названием @layer oldStyles. Потом создали новый стиль, назвали его @layer newStyles и начали писать новые стили, которые нам нужны. Благодаря этой стратегии, можно выполнить откат к предыдущим авторским стилям и сохранить старый стиль у элементов, если нам это понадобится:

Такое решение подходит для управления стилями или версиями.

Поддержка revert-layer CSS в браузерах  

Каскадные слои CSS, включая ключевое слово revert-layer, открывают многообещающие перспективы для архитектуры CSS. Но при этом важно учитывать их совместимость с браузерами. Не так просто использовать полифилл (polyfill — код, который преобразует новые функции в читаемый код для старых браузеров) для revert-layer, что ещё больше усложняет внедрение последнего в проекты для широкого спектра браузеров.

Согласно официальной документации CanIUse, у revert-layer ограниченная совместимость с браузерами. Я решил проверить сам и могу сказать, что как минимум Chrome, Firefox, Opera и Brave его поддерживают. По идее, Safari тоже должен. 

Но всё же рекомендую сначала проверять его совместимость с нужным браузером.


Итак, мы разобрались, как работает revert-layer и как его применять. Надеюсь, чёткое представление о подходящих сценариях его использования и особенностях совместимости поможет вам эффективно применять новые возможности в своих проектах.

Ближайшие курсы по программированию:

Топ бесплатных занятий:

Комментарии (2)


  1. ZiZIGY
    28.04.2024 07:11

    Воу, очень полезная информация. Но судя по всему это нововведение в css.

    Насколько эта штука хорошо поддерживается?


    1. Metotron0
      28.04.2024 07:11

      Caniuse говорит, что в Firefox появилась в феврале 2022, а в других не появилась. А автор пишет иначе.

      Посмотрел в хроме — да, там есть. В файрфоксе тоже.