@starting-style
Ограниченное использование
Эта функция не является Baseline, так как она не работает во всех распространённых браузерах.
Правило @starting-style CSS at-правило используется для определения начальных значений свойств элемента, от которых необходимо перейти при первом обновлении стиля элемента, то есть при первом отображении элемента на ранее загруженной странице.
Синтаксис
Правило @starting-style может использоваться двумя способами:
-
В виде самостоятельного блока, в котором содержатся одно или несколько наборов правил, определяющих начальные объявления стилей и элементы, к которым они применяются:
@starting-style { rulesets } -
Вложенным внутри существующего набора правил, в котором содержатся одно или несколько объявлений, определяющих начальные значения свойств для элементов, уже выбранных этим набором правил:
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><div></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);
});
Результат
Код отображается следующим образом:
Анимация всплывающего окна
В этом примере всплывающее окно (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также установлено в сокращённой записи, чтобы анимация происходила.
Результат
Конечный результат выглядит так:
Спецификации
Совместимость с браузерами
| Рабочие столы | Мобильные устройства | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| 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-переходов
overlaytransition-behaviorCSSStartingStyleRule- Четыре новых 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