Spec-Zone.ru › CSS

@starting-style

Ограниченное использование

Эта функция не является Baseline, так как она не работает во всех распространённых браузерах.

  • Подробнее
  • Полная совместимость
  • Отправить отзыв

Правило @starting-style CSS at-правило используется для определения начальных значений свойств элемента, от которых необходимо перейти при первом обновлении стиля элемента, то есть при первом отображении элемента на ранее загруженной странице.

Синтаксис

Правило @starting-style может использоваться двумя способами:

  1. В виде самостоятельного блока, в котором содержатся одно или несколько наборов правил, определяющих начальные объявления стилей и элементы, к которым они применяются:

    @starting-style {
      rulesets
    }
    
  2. Вложенным внутри существующего набора правил, в котором содержатся одно или несколько объявлений, определяющих начальные значения свойств для элементов, уже выбранных этим набором правил:

    selector { /* existing ruleset */
      /* ... */
    
      @starting-style {
        declarations
      }
    }
    

Описание

Чтобы избежать неожиданного поведения, переходы CSS по умолчанию не запускаются при первом обновлении стиля элемента или при изменении типа display с none на другое значение. Для активации переходов при первом обновлении стиля необходимы правила @starting-style. Они задают начальные стили для элементов, у которых нет предыдущего состояния, определяя значения свойств, от которых должен произойти переход.

@starting-style особенно полезно при создании переходов при входе и выходе элементов, отображаемых в верхнем слое (например, поп-уведомлений и модальных <dialog>), элементов, меняющих состояние с display: none, а также элементов, впервые добавленных в или удаленных из DOM.

Примечание: @starting-style применимо только к переходам CSS. При использовании анимаций CSS для реализации таких эффектов, @starting-style не требуется. См. Использование анимаций CSS для примера.

Существует два способа использования @starting-style: как самостоятельное правило или вложенное внутри набора правил.

Рассмотрим пример, где мы хотим анимировать поп-уведомление при его отображении (то есть, при добавлении в верхний слой). «Оригинальное правило», определяющее стили для открытого поп-уведомления, может выглядеть примерно так (см. пример поп-уведомления ниже):

[popover]:popover-open {
  opacity: 1;
  transform: scaleX(1);
}

Для задания начальных значений свойств поп-уведомления, которые будут анимированы с помощью первого метода, включите самостоятельный блок @starting-style в ваш CSS:

@starting-style {
  [popover]:popover-open {
    opacity: 0;
    transform: scaleX(0);
  }
}

Примечание: Правило @starting-style и «оригинальное правило» имеют одинаковую specificity. Чтобы убедиться, что начальные стили применяются, включите правило @starting-style после «оригинального правила». Если вы укажете правило @starting-style перед «оригинальным правилом», исходные стили перекроют начальные стили.

Чтобы задать начальный стиль для поп-уведомления с помощью вложенного метода, можно вложить блок @starting-style в «оригинальное правило»:

[popover]:popover-open {
  opacity: 1;
  transform: scaleX(1);

  @starting-style {
    opacity: 0;
    transform: scaleX(0);
  }
}

Когда именно используются начальные стили?

Важно понимать, что элемент перейдёт от своих @starting-style стилей, когда он впервые будет отображён в DOM, или когда он перейдёт от display: none к видимому значению. Когда он вернётся в исходное видимое состояние, он больше не будет использовать @starting-style стили, так как он теперь виден в DOM. Вместо этого он вернётся к стилям, установленным для его стандартного состояния.

По сути, в этих ситуациях необходимо управлять тремя состояниями стиля: начальным состоянием, состоянием перехода и стандартным состоянием. В таких случаях «конечный» и «начальный» переходы могут быть разными. Это можно увидеть в нашем примере Демонстрация использования начальных стилей ниже.

Формальный синтаксис

Ошибка: не удалось найти синтаксис для этого элемента

Примеры

Базовое использование @starting-style

Переход цвета фона элемента background-color от прозрачного к зелёному при его первоначальном отображении:

#target {
  transition: background-color 1.5s;
  background-color: green;
}

@starting-style {
  #target {
    background-color: transparent;
  }
}

Переход opacity элемента при изменении значения его display на или с none:

#target {
  transition-property: opacity, display;
  transition-duration: 0.5s;
  display: block;
  opacity: 1;
  @starting-style {
    opacity: 0;
  }
}

#target.hidden {
  display: none;
  opacity: 0;
}

Демонстрация использования начальных стилей

В этом примере кнопка используется для создания элемента <div>, присвоения ему class showing, и добавления его в DOM.

showing получает @starting-style background-color: red и стиль background-color: blue для перехода. Стандартное div правило содержит background-color: yellow, и именно там задаётся transition.

Когда <div> впервые добавляется в DOM, вы увидите переход фона от красного к синему. После таймаута мы удаляем класс showing из элемента <div> с помощью JavaScript. В этот момент происходит переход от синего к жёлтому, а не к красному. Это доказывает, что начальные стили используются только при первом отображении элемента в DOM. После того, как элемент появился, он переходит к стилю, установленным по умолчанию.

После ещё одного таймаута мы удаляем <div> из DOM полностью, восстанавливая начальное состояние примера, чтобы его можно было запустить снова.

HTML

<button>Display <code>&lt;div&gt;</code></button>

CSS

div {
  background-color: yellow;
  transition: background-color 3s;
}

div.showing {
  background-color: skyblue;
}

@starting-style {
  div.showing {
    background-color: red;
  }
}

JavaScript

const btn = document.querySelector("button");

btn.addEventListener("click", () => {
  btn.disabled = true;
  const divElem = document.createElement("div");
  divElem.classList.add("showing");
  document.body.append(divElem);

  setTimeout(() => {
    divElem.classList.remove("showing");

    setTimeout(() => {
      divElem.remove();
      btn.disabled = false;
    }, 3000);
  }, 3000);
});

Результат

Код отображается следующим образом:

END_OF_DOCUMENT_MARKER

Анимация всплывающего окна

В этом примере всплывающее окно (popover) анимируется с помощью CSS-переходов. Базовая анимация появления и исчезновения обеспечивается свойством transition.

HTML

HTML содержит элемент <div>, объявленный как всплывающее окно с помощью атрибута popover, и элемент <button>, назначенный элементом управления отображением всплывающего окна с помощью атрибута popovertarget.

<button popovertarget="mypopover">Show the popover</button>
<div popover="auto" id="mypopover">I'm a Popover! I should animate.</div>

CSS

В данном примере мы хотим анимировать два свойства: opacity и transform (в частности, горизонтальное масштабирование), чтобы всплывающее окно появлялось и исчезало с плавным затемнением и горизонтальным ростом/уменьшением.

html {
  font-family: Arial, Helvetica, sans-serif;
}

[popover]:popover-open {
  opacity: 1;
  transform: scaleX(1);
}

[popover] {
  font-size: 1.2rem;
  padding: 10px;

  /* Final state of the exit animation */
  opacity: 0;
  transform: scaleX(0);

  transition:
    opacity 0.7s,
    transform 0.7s,
    overlay 0.7s allow-discrete,
    display 0.7s allow-discrete;
  /* Equivalent to
  transition: all 0.7s allow-discrete; */
}

/* Include after the [popover]:popover-open rule */
@starting-style {
  [popover]:popover-open {
    opacity: 0;
    transform: scaleX(0);
  }
}

/* Transition for the popover's backdrop */
[popover]::backdrop {
  background-color: rgb(0 0 0 / 0%);
  transition:
    display 0.7s allow-discrete,
    overlay 0.7s allow-discrete,
    background-color 0.7s;
  /* Equivalent to
  transition: all 0.7s allow-discrete; */
}

[popover]:popover-open::backdrop {
  background-color: rgb(0 0 0 / 25%);
}

/* Nesting (&) is not supported for pseudo-elements
so specify a standalone starting-style block. */
@starting-style {
  [popover]:popover-open::backdrop {
    background-color: rgb(0 0 0 / 0%);
  }
}

Для этого мы установили начальное состояние этих свойств в скрытом состоянии всплывающего окна по умолчанию (выбранное через [popover]) и конечное состояние в открытом состоянии всплывающего окна (выбранное через псевдокласс :popover-open).

Затем мы установили свойство transition для анимации между этими двумя состояниями. Начальное состояние для анимации включено в правило @starting-style для активации анимации появления.

Поскольку анимируемый элемент поднимается на верхний слой при показе и удаляется с верхнего слоя при скрытии (с помощью display: none), необходимы дополнительные шаги для обеспечения работы анимации в обоих направлениях:

  • display добавляется в список анимируемых элементов, чтобы гарантировать видимость анимируемого элемента (установленное значение display: block или другое видимое значение display ) во время обеих анимаций (появления и исчезновения). Без этого анимация исчезновения не будет видна; по сути, всплывающее окно просто исчезнет. Обратите внимание, что значение transition-behavior: allow-discrete также установлено в сокращённой записи, чтобы активировать анимацию.
  • overlay добавляется в список анимируемых элементов, чтобы обеспечить отсрочку удаления элемента с верхнего слоя до завершения анимации. Это не сильно влияет на такие анимации, как эта, но в более сложных случаях, если этого не сделать, элемент может быть удалён из слоя слишком рано, что означает, что анимация не будет плавной или эффективной. И снова, transition-behavior: allow-discrete требуется в этом случае для выполнения анимации.

Примечание: Мы также включили переход для ::backdrop, который появляется за всплывающим окном при его открытии, чтобы обеспечить приятную анимацию затемнения. [popover]:popover-open::backdrop используется для выбора фона, когда всплывающее окно открыто.

Результат

Код отображается следующим образом:

Примечание: Поскольку всплывающие окна изменяют состояние с display: none на display: block каждый раз, когда они отображаются, всплывающее окно переходит от своих стилей @starting-style к своим стилям [popover]:popover-open каждый раз, когда происходит анимация появления. При закрытии всплывающего окна оно переходит от своего состояния [popover]:popover-open к состоянию по умолчанию [popover].

Примечание: Вы можете найти пример, демонстрирующий переход элемента <dialog> и его фона при отображении и скрытии на странице справки <dialog> — см. Переход элементов диалогового окна.

Анимация элементов при добавлении и удалении из DOM

В этом примере есть кнопка, которая при нажатии добавляет новые элементы в контейнер <section>. Каждый элемент, в свою очередь, содержит вложенную кнопку, которая при нажатии удаляет элемент. Этот пример демонстрирует, как использовать переходы для анимации элементов при добавлении или удалении из DOM.

HTML

<button>Create new column</button>
<section></section>

JavaScript

JavaScript позволяет добавлять и удалять элементы:

const btn = document.querySelector("button");
const sectionElem = document.querySelector("section");

btn.addEventListener("click", createColumn);

function randomColor() {
  function randomNum() {
    return Math.floor(Math.random() * 255);
  }

  return `rgb(${randomNum()} ${randomNum()} ${randomNum()})`;
}

function createColumn() {
  const divElem = document.createElement("div");
  divElem.style.backgroundColor = randomColor();

  const closeBtn = document.createElement("button");
  closeBtn.textContent = "✖";
  closeBtn.setAttribute("aria-label", "close");
  divElem.append(closeBtn);
  sectionElem.append(divElem);

  closeBtn.addEventListener("click", () => {
    divElem.classList.add("fade-out");

    setTimeout(() => {
      divElem.remove();
    }, 1000);
  });
}

При нажатии на кнопку "Создать новый столбец" вызывается функция createColumn(). Она создаёт элемент <div> с случайно сгенерированным цветом фона и элемент <button> для закрытия <div>. Затем она добавляет <button> к контейнеру <div> и <div> к контейнеру <section>.

Затем мы добавляем обработчик событий к кнопке закрытия с помощью addEventListener(). Нажатие кнопки закрытия выполняет два действия:

  • Добавляет класс fade-out к <div> . Добавление класса запускает анимацию выхода, заданную для этого класса.
  • Удаляет <div> после задержки 1000мс. Функция setTimeout() задерживает удаление <div> из DOM (с помощью Element.remove()) до тех пор, пока не закончится анимация.

CSS

Мы включаем transition, который анимирует opacity и scale каждого столбца при добавлении и удалении:

div {
  flex: 1;
  border: 1px solid gray;
  position: relative;
  background: linear-gradient(
    to right,
    rgb(255 255 255 / 0%),
    rgb(255 255 255 / 50%)
  );
  opacity: 1;
  scale: 1 1;

  transition:
    opacity 0.7s,
    scale 0.7s,
    display 0.7s allow-discrete,
    all 0.7s allow-discrete;
  /* Equivalent to
  transition: all 0.7s allow-discrete; */
}

/* Include after the `div` rule */
@starting-style {
  div {
    opacity: 0;
    scale: 1 0;
  }
}

.fade-out {
  opacity: 0;
  display: none;
  scale: 1 0;
}

div > button {
  font-size: 1.6rem;
  background: none;
  border: 0;
  text-shadow: 2px 1px 1px white;
  border-radius: 15px;
  position: absolute;
  top: 1px;
  right: 1px;
  cursor: pointer;
}

Для анимации opacity и scale каждого <div> при добавлении в DOM, а затем обратной анимации при удалении из DOM, мы:

  • Указываем конечное состояние свойств, которые мы хотим анимировать, в правиле div { ... }.
  • Указываем начальное состояние для перехода свойств в блоке @starting-style.
  • Указываем анимацию выхода в правиле .fade-out — это класс, который JavaScript присваивает элементам <div> , когда нажимаются их кнопки закрытия. Помимо установки конечных состояний opacity и scale , мы также устанавливаем display: none на <div> — мы хотим, чтобы они стали немедленно недоступны при удалении из пользовательского интерфейса.
  • Указываем список transition внутри правила div { ... } для анимации opacity, scale, и display. Обратите внимание, что для display, значение transition-behavior: allow-discrete также установлено в сокращённой записи, чтобы анимация происходила.

Результат

Конечный результат выглядит так:

Спецификации

Спецификация
CSS Transitions Level 2
# defining-before-change-style

Совместимость с браузерами

Рабочие столы Мобильные устройства
Chrome Edge Firefox Opera Safari Chrome Android Firefox for Android Opera Android Safari на IOS Samsung Internet WebView Android
@starting-style 117 117
129Пока не поддерживает анимацию от display: none
103 17.5 117
129Пока не поддерживает анимацию от display: none
78 17.5 24.0 117

См. также

  • Модуль CSS-переходов
  • overlay
  • transition-behavior
  • CSSStartingStyleRule
  • Четыре новых CSS-функции для плавной анимации появления и исчезновения на developer.chrome.com (2023)

© 2005–2024 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/CSS/@starting-style

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API