Будущие новинки из CSS Navigation Matching

• css

Вступление

В свежем Хроме 156 появился маленький кусочек из свежей спецификации, которая пока находится в “рабочем” статусе. А если заглянуть в неё, найдётся много интересного.

Давайте посмотрим на все (возможные) будущие новинки. Я не так часто описываю нереализованные штуки, поэтому предупреждение.

Всё перечисленное – экспериментальное АПИ, которое, быть может, никогда не доберётся до браузеров.

Директива @location

Новая директива позволяет задать имя, описывающее набор страниц.

@location --movie-list {
    pattern: url-pattern("/movies");
}

Именованный @location можно использовать в других АПИ (будет ниже). Также прилагается масса доступных способов указать location:

  • pattern
  • Набор из protocol, hostname, port, pathname, search, hash (все опциональные)
  • base-url
@location --movie-list {
    pathname: "/movies";
}

Достаточно давно у нас есть псевдокласс :link, который выбирает ссылки. :link-to(...) - похожий псевдокласс, он тоже выбирает ссылки, но только на конкретные страницы:

/* Ссылка на домашнюю страницу */
:link-to(url-pattern("/")) {
    font-weight: bold;
}

Или можно вынести урл в отдельный @location:

@location --homepage {
    pattern: url-pattern("/");
}
 
:link-to(--homepage) {
    font-weight: bold;
}

Внутри круглых скобок можно указывать и url-pattern, и именованный @location, и просто url(...).

Похожего эффекта можно добиться, если сделать селектор на атрибут:

a[href^="https://wikipedia.org"] {
    ...
}

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

Псевдокласс :navigation-source

Если до этого у нас был :target, который позволял выбрать “цель навигации”, то :navigation-source позволяет выбрать источник. Несмотря на схожесть, работает новый псевдокласс совсем по-другому. :target основан на якоре (хеше) в урле, а :navigation-source становится ясен в момент навигации – если кликнули по ссылке, то она и будет :navigation-source. Вариантов для источника навигации несколько: <a>, <area>, <form>, <input> или <button>.

Псевдокласс нужен в первую очередь View Transition не будет работать вне SPA (если страницы-источника нет, то и выбирать нечего).

И это именно та возможность, которую завезли в свежий Хром. Кроме того, этот же элемент можно получить через JS Navigation API: event.sourceElement.

a:navigation-source .thumb {
    view-transition-name: active-image;
}

Условные стили с @navigation

@navigation позволяет задать набор правил, похожий на @media или @supports, но позволяющий выбрать случай, когда страница соответствует урлу или моменту переходу между урлами.

@navigation (at: url-pattern("/")) {
    /* Стили домашней страницы */
    body {
        background: #fff;
    }
}

Тут тоже можно использовать @location. А для описания переходов есть два варианта:

@location --homepage {
    pattern: url-pattern("/");
}
 
@location --movie-list {
    pattern: url-pattern("/movies");
}
 
/* 1 */
@navigation (from: --homepage) and
            (to: --movie-list) {
    /* Переход между домашней страницей и списком фильмов,
       но не в обратную сторону! */
    ...
}
 
/* 2 */
@navigation (between: --homepage and --movie-list) {
    /* Переход между двумя страницами в любом направлении */
    ...
}

И опять же, часть функционала нацелена именно на View Transition. С помощью нового апи можно сделать отдельные анимации для конкретных переходов, в декларативном стиле.

Помимо простых вариантов с :at, :from, :to и :between, задуман :not, :history и :phase.

Функция navigation()

Помимо директивы @navigation, есть предложение добавить и CSS функцию. Такую можно использовать внутри if() или новой директивы @when (это такой обобщённый вариант @media, @supports и других условий):

.nav-item {
    font-weight: if(navigation(at: --homepage): normal; else: bold);
}
 
/* или */
 
.nav-item {
    font-weight: bold;
}
@when navigation(at: --homepage) {
    .nav-item {
        font-weight: normal;
    }
}

Итого

Новая спецификация предлагает абсолютно новый подход к тому, как мы обрабатываем навигации в CSS. Точнее, у нас раньше практически не было возможностей, а теперь они потихоньку будут появляться (вероятно).

Для View Transition это большой шаг вперёд. Там, где раньше нужно было использовать JS для определения типа перехода, теперь можно задать анимацию декларативно, через CSS. А там, где мы были вынуждены менять HTML для “объяснения” CSS, какое сейчас состояние, нам больше будет не нужно этого делать.

По-моему, это именно то апи, которое никогда не хотелось (потому что никто и подумать не мог), а при взгляде на него выглядит очень перспективно. А как вам? Напишите в комментарии.

Обсудить в Telegram

Почитать ещё посты

  • Поддержка фич, которые иначе отследить нельзя: named-feature
  • image-animation и контроль над анимацией
  • frame-sizing не решает проблемы размера ифреймов?
  • text-box-edge и text-box-trim: доступны во всех браузерах
  • CSS Link Parameters, что ты такое?