From e8a4c7f9121cd8d46950ae5dce60dc214cd7edbd Mon Sep 17 00:00:00 2001 From: estelle Date: Tue, 30 Dec 2025 16:52:29 +0100 Subject: [PATCH 01/15] New CSS reference: Keyframe selectors --- .../web/api/csskeyframerule/keytext/index.md | 2 +- .../api/csskeyframesrule/deleterule/index.md | 2 +- .../api/csskeyframesrule/findrule/index.md | 2 +- .../en-us/web/css/guides/animations/index.md | 1 + .../guides/scroll-driven_animations/index.md | 3 +- .../timelines/index.md | 2 +- files/en-us/web/css/guides/selectors/index.md | 3 + .../css/guides/syntax/error_handling/index.md | 2 +- .../reference/at-rules/@keyframes/index.md | 2 +- .../properties/animation-range/index.md | 2 +- .../css/reference/selectors/keyframe/index.md | 304 ++++++++++++++++++ 11 files changed, 317 insertions(+), 8 deletions(-) create mode 100644 files/en-us/web/css/reference/selectors/keyframe/index.md diff --git a/files/en-us/web/api/csskeyframerule/keytext/index.md b/files/en-us/web/api/csskeyframerule/keytext/index.md index e0993607a708a7f..affcb17c1a50d7c 100644 --- a/files/en-us/web/api/csskeyframerule/keytext/index.md +++ b/files/en-us/web/api/csskeyframerule/keytext/index.md @@ -8,7 +8,7 @@ browser-compat: api.CSSKeyframeRule.keyText {{APIRef("CSSOM") }} -The **`keyText`** property of the {{domxref("CSSKeyframeRule")}} interface represents the keyframe selector as a comma-separated list of percentage values. The from and to keywords map to 0% and 100%, respectively. +The **`keyText`** property of the {{domxref("CSSKeyframeRule")}} interface represents the [keyframe selector](/en-US/docs/Web/CSS/Reference/Selectors/Keyframe) as a comma-separated list of percentage values. The from and to keywords map to 0% and 100%, respectively. ## Value diff --git a/files/en-us/web/api/csskeyframesrule/deleterule/index.md b/files/en-us/web/api/csskeyframesrule/deleterule/index.md index e4f4520a37050ef..08d6e73fa3a4d7d 100644 --- a/files/en-us/web/api/csskeyframesrule/deleterule/index.md +++ b/files/en-us/web/api/csskeyframesrule/deleterule/index.md @@ -19,7 +19,7 @@ deleteRule(select) ### Parameters - `select` - - : A string which contains the keyframe selector of the rule to be deleted, which must be: + - : A string which contains the [keyframe selector](/en-US/docs/Web/CSS/Reference/Selectors/Keyframe) of the rule to be deleted, which must be: - a comma-separated list of percentage values between 0% and 100%; - or, the keywords `from` or `to` diff --git a/files/en-us/web/api/csskeyframesrule/findrule/index.md b/files/en-us/web/api/csskeyframesrule/findrule/index.md index 5c3bc17b62bd249..2181aa9881a4408 100644 --- a/files/en-us/web/api/csskeyframesrule/findrule/index.md +++ b/files/en-us/web/api/csskeyframesrule/findrule/index.md @@ -19,7 +19,7 @@ findRule(select) ### Parameters - `select` - - : A string which contains the keyframe selector of the rule to be found, which must be: + - : A string which contains the [keyframe selector](/en-US/docs/Web/CSS/Reference/Selectors/Keyframe) of the rule to be found, which must be: - a comma-separated list of percentage values between 0% and 100%; - or, the keywords `from` or `to` diff --git a/files/en-us/web/css/guides/animations/index.md b/files/en-us/web/css/guides/animations/index.md index b36b99e62feb5d8..6999726eb976f47 100644 --- a/files/en-us/web/css/guides/animations/index.md +++ b/files/en-us/web/css/guides/animations/index.md @@ -250,6 +250,7 @@ The CSS animations module level 2 also introduces the `animation-trigger`, `anim ### At-rules and descriptors - {{cssxref("@keyframes")}} +- [``](/en-us/web/css/reference/selectors/keyframe) ### Events diff --git a/files/en-us/web/css/guides/scroll-driven_animations/index.md b/files/en-us/web/css/guides/scroll-driven_animations/index.md index aef8f330dff69f8..94c97b5d2b9b64c 100644 --- a/files/en-us/web/css/guides/scroll-driven_animations/index.md +++ b/files/en-us/web/css/guides/scroll-driven_animations/index.md @@ -146,7 +146,8 @@ Scroll the element in the inline direction to see its background color change. S - [CSS animations](/en-US/docs/Web/CSS/Guides/Animations) module - {{cssxref("animation-timeline")}} - - {{cssxref("@keyframes")}} + - {{cssxref("@keyframes")}} at-rule + - {{cssxref("keyframe")}} selectors - [CSS overflow](/en-US/docs/Web/CSS/Guides/Overflow) module - {{glossary("Scroll container")}} - [Scrollport](/en-US/docs/Glossary/Scroll_container#scrollport) diff --git a/files/en-us/web/css/guides/scroll-driven_animations/timelines/index.md b/files/en-us/web/css/guides/scroll-driven_animations/timelines/index.md index 7c447b75f5df5dd..0d8ea0ff07286b0 100644 --- a/files/en-us/web/css/guides/scroll-driven_animations/timelines/index.md +++ b/files/en-us/web/css/guides/scroll-driven_animations/timelines/index.md @@ -320,7 +320,7 @@ The {{cssxref("view-timeline-inset")}} arguments specify insets (if positive) or Unlike the scroll timeline's `scroll()` function, there is no `` argument in the `view()` function, as the view timeline always tracks the subject within its nearest ancestor scroll container. -In this example, as we are using inset values, we can use the `from` and `to` keyframe selectors. +In this example, as we are using inset values, we can use the `from` and `to` [keyframe selectors](/en-US/docs/Web/CSS/Reference/Selectors/Keyframe). ```css live-sample___anon_view_args @keyframes action { diff --git a/files/en-us/web/css/guides/selectors/index.md b/files/en-us/web/css/guides/selectors/index.md index 3386f18fec30210..c2307dc61e1b57f 100644 --- a/files/en-us/web/css/guides/selectors/index.md +++ b/files/en-us/web/css/guides/selectors/index.md @@ -189,6 +189,9 @@ The CSS selectors module also introduces the {{CSSXref(":blank")}}, {{CSSXref(": - Other [pseudo-elements](/en-US/docs/Web/CSS/Reference/Selectors/Pseudo-elements) - {{CSSxRef("::cue")}} +- [CSS animations](/en-US/docs/Web/CSS/Guides/Animations) + - {{cssxref("keyframe")}} selectors + - {{CSSXref("@namespace")}} at-rule - {{cssxref("important", "!important")}} diff --git a/files/en-us/web/css/guides/syntax/error_handling/index.md b/files/en-us/web/css/guides/syntax/error_handling/index.md index e3b6466039af884..cf6806ca9ddc3a6 100644 --- a/files/en-us/web/css/guides/syntax/error_handling/index.md +++ b/files/en-us/web/css/guides/syntax/error_handling/index.md @@ -52,7 +52,7 @@ Different at-rules have different grammar rules, different (or no) descriptors, For example, the `@font-face` rule requires both a [`font-family`](/en-US/docs/Web/CSS/Reference/At-rules/@font-face/font-family) and [`src`](/en-US/docs/Web/CSS/Reference/At-rules/@font-face/src) descriptor. If either of these is omitted or invalid, the entire `@font-face` rule is invalid. Including an unrelated descriptor, any other valid font descriptor with an invalid value, or a property style declaration within the `@font-face` nested block will not invalidate the font declaration. As long as the font name and font source are included and valid, any invalid CSS within the at-rule is ignored, but the `@font-face` block is still parsed. -While the grammar of the `@keyframes` at-rule is very different from the `@font-face` rule grammar, the type of error still impacts what gets ignored. Important declarations (marked with the {{cssxref("important")}} flag) and properties that can't be animated are ignored in keyframe rules, but they don't impact other styles declared in the same keyframe selector block. Including an invalid keyframe selector (such as a percentage value less than `0%` or greater than `100%`, or a {{cssxref("number")}} omitting the `%`) invalidates the keyframe selector list and therefore the style block is ignored. An invalid keyframe selector only invalidates the invalid selector's style block; it does not invalidate the entire `@keyframes` declaration. Including styles between two keyframe selector blocks, on the other hand, will invalidate the entire `@keyframes` at-rule. +While the grammar of the `@keyframes` at-rule is very different from the `@font-face` rule grammar, the type of error still impacts what gets ignored. Important declarations (marked with the {{cssxref("important")}} flag) and properties that can't be animated are ignored in keyframe rules, but they don't impact other styles declared in the same [keyframe selector](/en-US/docs/Web/CSS/Reference/Selectors/Keyframe) block. Including an invalid keyframe selector (such as a percentage value less than `0%` or greater than `100%`, or a {{cssxref("number")}} omitting the `%`) invalidates the keyframe selector list and therefore the style block is ignored. An invalid keyframe selector only invalidates the invalid selector's style block; it does not invalidate the entire `@keyframes` declaration. Including styles between two keyframe selector blocks, on the other hand, will invalidate the entire `@keyframes` at-rule. Some at-rules are almost always valid. The {{cssxref("@layer")}} at-rule comes in both regular and nested forms. The `@layer` statement syntax contains just the prelude, ending with a semi-colon. Alternatively, the nested syntax has layer styles nested between curly braces coming after the prelude. Omitting a closing curly brace may be a logic error but is not a syntax error. In the case of a missing closing brace in `@layer`, any styles coming after where the closing brace should have been are parsed as being in the cascade layer defined in the at-rule's prelude. The CSS is valid as there are no syntax errors; nothing is discarded. A syntax error may cause the named or anonymous layer to be empty, but the layer is still created. diff --git a/files/en-us/web/css/reference/at-rules/@keyframes/index.md b/files/en-us/web/css/reference/at-rules/@keyframes/index.md index 31246eadc66ace8..a605cc331f7518d 100644 --- a/files/en-us/web/css/reference/at-rules/@keyframes/index.md +++ b/files/en-us/web/css/reference/at-rules/@keyframes/index.md @@ -37,7 +37,7 @@ The **`@keyframes`** [CSS](/en-US/docs/Web/CSS) [at-rule](/en-US/docs/Web/CSS/Gu ## Description -To use keyframes, create a `@keyframes` rule with a name that is then used by the {{ cssxref("animation-name") }} property to match an animation to its keyframe declaration. Each `@keyframes` rule contains a style list of keyframe selectors, which specify percentages along the animation when the keyframe occurs, and a block containing the styles for that keyframe. +To use keyframes, create a `@keyframes` rule with a name that is then used by the {{ cssxref("animation-name") }} property to match an animation to its keyframe declaration. Each `@keyframes` rule contains a style list of [keyframe selectors](/en-US/docs/Web/CSS/Reference/Selectors/Keyframe), which specify percentages along the animation when the keyframe occurs, and a block containing the styles for that keyframe. You can list the keyframe percentages in any order; they will be handled in the order they should occur. diff --git a/files/en-us/web/css/reference/properties/animation-range/index.md b/files/en-us/web/css/reference/properties/animation-range/index.md index 6b025b060169108..4c461710ac2350b 100644 --- a/files/en-us/web/css/reference/properties/animation-range/index.md +++ b/files/en-us/web/css/reference/properties/animation-range/index.md @@ -252,7 +252,7 @@ Scroll to see the element being animated. {{EmbedLiveSample("Examples", "100%", "480px")}} -Note how the `from`, or `0%`, keyframe property values are not applied to the animated element until the top block border edge is `10%` past the container's bottom edge; it is full size, fully opaque, and magenta. At that point, the animation is applied and it is styled with the values defined by the `0%` keyframe selector. When the `animation-range-end` is reached, 25% from the top of the scrollport, it jumps back to its original styling. +Note how the `from`, or `0%`, keyframe property values are not applied to the animated element until the top block border edge is `10%` past the container's bottom edge; it is full size, fully opaque, and magenta. At that point, the animation is applied and it is styled with the values defined by the `0%` [keyframe selector](/en-US/docs/Web/CSS/Reference/Selectors/Keyframe). When the `animation-range-end` is reached, 25% from the top of the scrollport, it jumps back to its original styling. Generally, you will want to set `animation-fill-mode: both` when creating [scroll-driven animations](/en-US/docs/Web/CSS/Guides/Scroll-driven_animations). The jump to the default state occurs because we did not set the {{cssxref("animation-fill-mode")}} property on the element, which can be used to apply an animation's styles to an element before and after the animation's execution. We initially omitted the property in this example to better enable visualizing the effects of `animation-range`. diff --git a/files/en-us/web/css/reference/selectors/keyframe/index.md b/files/en-us/web/css/reference/selectors/keyframe/index.md new file mode 100644 index 000000000000000..940613c9f2c826a --- /dev/null +++ b/files/en-us/web/css/reference/selectors/keyframe/index.md @@ -0,0 +1,304 @@ +--- +title: Keyframe selector +slug: Web/CSS/Reference/Selectors/Keyframe +page-type: css-selector +browser-compat: css.at-rules.keyframes.selectors +sidebar: cssref +--- + +CSS **keyframe selectors** identify specific points in an animation timeline where the keyframe's style should be applied. Defined in the [CSS animation module](/en-US/docs/Web/CSS/CSS_Animations), these selectors are used exclusively within the {{cssxref("@keyframes")}} at-rule. + +## Syntax + +```css +/* Keywords */ +from { +} +to { +} + +/* values */ +0% { +} +50% { +} +100% { +} + +/* Selector lists */ +0%, +50%, +100% { +} +from, +to { +} +``` + +### Values + +- `from` + - : Represents the start of the animation sequence. It is equivalent to `0%`. +- `to` + - : Represents the end of the animation sequence. It is equivalent to `100%`. +- {{cssxref("percentage")}} + - : A percentage between `0%` and `100%`, inclusive, representing the total progression through the animation sequence. + +## Description + +A `` can be the `to` or `from` keyword, a percentage between `0%` and `100%`, inclusive, or a comma-separated list of these keywords and/or percentages. When a comma-separated list of `` is used, the style block that follows applies to all the specified progression points. + +### Valid percentage values + +Percentage values must include the percent sign (`%`). A unitless `0` is invalid. Values outside the range `0%` to `100%` (such as `-10%` or `110%`) are invalid and will cause the keyframe block to be ignored. + +### Cascade, order, precedence, and importance + +Property values set by animation `@keyframes` are more important than all normal styles, meaning no matter the {{cssxref("specificity")}}, an animated value will override values that do not have an {{cssxref("important", "!important")}} flag set. Only important property values and values currently being transitioned take precedence over animated property values. + +All keyframe selectors have the same specificity. The order of keyframe selectors within the selector list does not matter. The source order only matters if a duplicate keyframe selector declares a different value for an already declared property on the same selector. + +The `!important` flag is not valid within an `@keyframes` definition. + +### Omitted start and end selectors + +If no `0%` (or `from`) or `100%` (or `to`) keyframe is specified, the browser will use the element's computed styles for those states, allowing the animation to transition smoothly from or to the element's non-animated property values. In other words, if a property is specified in a middle-of-the-timeline keyframe, without being set within a starting or ending keyframe selector block, the property will animate from it's original value to that value. + +For example, if an element has a `red` background color, and the following animation is applied: + +```css +@keyframes changeToPurple { + 25%, + 75% { + background-color: purple; + } +} +``` + +The background color will be `red` at the start of the animation, transitioning to `purple` a quarter of the way through the animation, remaining `purple` for half the animation, and transitioning back to `red`, the original background color, starting `75%` of the way through the {{cssxref("animation-timeline", "animation timeline", "", "nocode")}}. It will behave as if the following were set: + +```css +@keyframes changeToPurple { + 25%, + 75% { + background-color: purple; + } + 0%, + 100% { + background-color: var(--nonAnimatedColor); + } +} +``` + +Where `--nonAnimatedColor`, is the `background-color` of the element without the animation applied; in this case, `red`. + +#### Omitted property declarations + +When creating an `@keyframes` animation to animate multiple properties, you don't have to declare all the properties in all the keyframe selector blocks. + +For example, in the [basic usage](#basic_usage) example, the `opacity` is declared in all the keyframe selector blocks, but only starting and ending `transforms` values are set. In that case, the element will be fully opaque 50% of the way through the animation timeline, but the point at which the element is transformed `25vw` to the right depends on the {{cssxref("animation-timing-function")}}; being half the same as the `50%` in the case of `linear`, but not if `ease-in` is used, which was done in this case. + +### Cascade order + +If multiple keyframe blocks use the same ``, they [cascade](/en-US/docs/Web/CSS/Guides/Cascade/Introduction). This means that if the same property is defined in multiple blocks with the same selector, the last declaration in the rule takes precedence. If they define different properties, they are merged. + +This animation repeats non-changing values in multiple selector blocks, which is not necessary: + +```css +@keyframes uglyAnimation { + 0% { + transform: translatex(0); + opacity: 0; + background-color: purple; + } + 50% { + transform: translatex(0); + opacity: 1; + background-color: purple; + } + 75% { + transform: translatex(0); + opacity: 0; + background-color: green; + } + 100% { + transform: translatex(50vw); + opacity: 0; + background-color: purple; + } +} +``` + +We can use the cascade to group values in one selector block, then overriding them as necessary. The following is the equivalent to the previous animation, just with few lines of CSS: + +```css +@keyframes uglyAnimation { + 0%, + 50%, + 75%, + 100% { + transform: translatex(0); + opacity: 0; + background-color: purple; + } + 50% { + opacity: 1; + } + 75% { + background-color: green; + } + 100% { + transform: translatex(50vw); + } +} +``` + +Order is important! We can't ignore the cascade. If we reorder the above incorrectly, we lose the transitions. The following makes the element purple, fully opaque, and resets all the transforms during the entire time the animation is applied. The property values are applied and remain static because the last declaration overrides the declarations made in the previous keyframe selector blocks. + +```css +@keyframes makeItPurpleOnly { + 0% { + background-color: yellow; + } + 50% { + opacity: 0; + } + 75% { + background-color: green; + } + 100% { + transform: translatex(50vw); + } + 0%, + 50%, + 75%, + 100% { + transform: translatex(0); + opacity: 1; + background-color: purple; + } +} +``` + +## Examples + +### Basic usage + +This example demonstrates using keywords and percentages by creating a keyframe animation that uses these keyframe selector types. + +#### HTML + +We include an element that we will animate. + +```html +
I am animated
+``` + +#### CSS + +We provide some basic styling to our box: + +```css +div { + background-color: rebeccapurple; + color: white; + width: min-content; + padding: 10px; + font: 2rem sans-serif; +} +``` + +We create an {{cssxref("@keyframes")}} animation, applying styles to the `from`, `to`, and a middle percentage, animating the {{cssxref("opacity")}} and the {{cssxref("transform")}} properties. + +```css +@keyframes slide-and-fade { + from { + transform: translatex(0); + opacity: 0; + } + 50% { + opacity: 1; + } + to { + transform: translatex(50vw); + opacity: 0; + } +} +``` + +We apply our animation to the element using the {{cssxref("animation")}} shorthand property: + +```css +div { + animation: slide-and-fade 4s ease-in infinite; +} +``` + +#### Results + +{{EmbedLiveSample("Basic usage","100%","200")}} + +### Selector lists and initial values + +Using the same HTML and CSS as in the previous example, this example demonstrates using comma-separated selectors to group selectors, applying the same styles at multiple points in an animation. + +```html hidden +
I am animated
+``` + +#### CSS + +We create a `pulse` animation that changes the size of our element. We also declare a `background-color` in only one selector block. + +```css +div { + animation: pulse 4s linear infinite; +} + +@keyframes pulse { + 0%, + 75% { + transform: scale(1); + } + 50% { + transform: scale(1.2); + } + 25%, + 100% { + transform: scale(0.8); + background-color: black; + } +} +``` + +```css hidden +div { + background-color: rebeccapurple; + color: white; + width: min-content; + padding: 10px; + font: 2rem sans-serif; +} +``` + +#### Result + +{{EmbedLiveSample("Selector lists and initial values","100%","65")}} + +By using a selector list with multiple comma-separated keyframe selectors, the animation "pauses" from the `25%` keyframe until it reaches the `75%` keyframe. +The `black` is only set in the `25%, 75%` keyframe, so the element animates from and to `rebeccapurple`, it's original `background-color`. + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- {{cssxref("@keyframes")}} +- {{cssxref("animation")}} +- [Using CSS animations](/en-US/docs/Web/CSS/CSS_Animations/Using_CSS_animations) +- [CSS animations](/en-US/docs/Web/CSS/CSS_Animations) module From 69b282c9fc3d10d78099027c75588895b04b1147 Mon Sep 17 00:00:00 2001 From: estelle Date: Tue, 30 Dec 2025 16:56:48 +0100 Subject: [PATCH 02/15] make it plural --- files/en-us/web/css/reference/selectors/keyframe/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/en-us/web/css/reference/selectors/keyframe/index.md b/files/en-us/web/css/reference/selectors/keyframe/index.md index 940613c9f2c826a..2569d7f8168b7af 100644 --- a/files/en-us/web/css/reference/selectors/keyframe/index.md +++ b/files/en-us/web/css/reference/selectors/keyframe/index.md @@ -1,5 +1,5 @@ --- -title: Keyframe selector +title: Keyframe selectors slug: Web/CSS/Reference/Selectors/Keyframe page-type: css-selector browser-compat: css.at-rules.keyframes.selectors From b57ba3c067499aa5fed5e59866d4c0a34a3ee698 Mon Sep 17 00:00:00 2001 From: estelle Date: Fri, 2 Jan 2026 15:54:52 +0100 Subject: [PATCH 03/15] example height" --- files/en-us/web/css/reference/selectors/keyframe/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/en-us/web/css/reference/selectors/keyframe/index.md b/files/en-us/web/css/reference/selectors/keyframe/index.md index 2569d7f8168b7af..4be2e26cc00010b 100644 --- a/files/en-us/web/css/reference/selectors/keyframe/index.md +++ b/files/en-us/web/css/reference/selectors/keyframe/index.md @@ -283,7 +283,7 @@ div { #### Result -{{EmbedLiveSample("Selector lists and initial values","100%","65")}} +{{EmbedLiveSample("Selector lists and initial values","100%","125")}} By using a selector list with multiple comma-separated keyframe selectors, the animation "pauses" from the `25%` keyframe until it reaches the `75%` keyframe. The `black` is only set in the `25%, 75%` keyframe, so the element animates from and to `rebeccapurple`, it's original `background-color`. From c0fced288ab1e1fef4afa4ac1efa30e90bc81c2f Mon Sep 17 00:00:00 2001 From: estelle Date: Tue, 6 Jan 2026 00:01:51 +0100 Subject: [PATCH 04/15] force --- files/en-us/web/css/guides/animations/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/en-us/web/css/guides/animations/index.md b/files/en-us/web/css/guides/animations/index.md index 6999726eb976f47..3de63adf2704e1a 100644 --- a/files/en-us/web/css/guides/animations/index.md +++ b/files/en-us/web/css/guides/animations/index.md @@ -250,7 +250,7 @@ The CSS animations module level 2 also introduces the `animation-trigger`, `anim ### At-rules and descriptors - {{cssxref("@keyframes")}} -- [``](/en-us/web/css/reference/selectors/keyframe) +- [``](/en-US/docs/Web/CSS/Reference/Selectors/Keyframe) ### Events From 25861e51ca981c3314cb3bb2482eaf81e0b369ca Mon Sep 17 00:00:00 2001 From: estelle Date: Tue, 6 Jan 2026 00:01:55 +0100 Subject: [PATCH 05/15] force --- files/en-us/web/css/guides/scroll-driven_animations/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/en-us/web/css/guides/scroll-driven_animations/index.md b/files/en-us/web/css/guides/scroll-driven_animations/index.md index 94c97b5d2b9b64c..9137431a71ee810 100644 --- a/files/en-us/web/css/guides/scroll-driven_animations/index.md +++ b/files/en-us/web/css/guides/scroll-driven_animations/index.md @@ -147,7 +147,7 @@ Scroll the element in the inline direction to see its background color change. S - [CSS animations](/en-US/docs/Web/CSS/Guides/Animations) module - {{cssxref("animation-timeline")}} - {{cssxref("@keyframes")}} at-rule - - {{cssxref("keyframe")}} selectors + - [``](/en-US/docs/Web/CSS/Reference/Selectors/Keyframe) - [CSS overflow](/en-US/docs/Web/CSS/Guides/Overflow) module - {{glossary("Scroll container")}} - [Scrollport](/en-US/docs/Glossary/Scroll_container#scrollport) From 05c7b6fb38bad3caa03abcafcd02749b9c308fab Mon Sep 17 00:00:00 2001 From: estelle Date: Tue, 6 Jan 2026 00:02:00 +0100 Subject: [PATCH 06/15] force --- files/en-us/web/css/guides/selectors/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/en-us/web/css/guides/selectors/index.md b/files/en-us/web/css/guides/selectors/index.md index c2307dc61e1b57f..090eb195690dfc4 100644 --- a/files/en-us/web/css/guides/selectors/index.md +++ b/files/en-us/web/css/guides/selectors/index.md @@ -190,7 +190,7 @@ The CSS selectors module also introduces the {{CSSXref(":blank")}}, {{CSSXref(": - {{CSSxRef("::cue")}} - [CSS animations](/en-US/docs/Web/CSS/Guides/Animations) - - {{cssxref("keyframe")}} selectors + - [``](/en-US/docs/Web/CSS/Reference/Selectors/Keyframe) - {{CSSXref("@namespace")}} at-rule From 59f48a2b14b48a325882ef7c12eff8ef53ef114a Mon Sep 17 00:00:00 2001 From: estelle Date: Tue, 6 Jan 2026 00:37:58 +0100 Subject: [PATCH 07/15] ick --- .../css/reference/selectors/keyframe/index.md | 136 ++++++++++++++---- 1 file changed, 106 insertions(+), 30 deletions(-) diff --git a/files/en-us/web/css/reference/selectors/keyframe/index.md b/files/en-us/web/css/reference/selectors/keyframe/index.md index 4be2e26cc00010b..7e6ff7ff7e6faf9 100644 --- a/files/en-us/web/css/reference/selectors/keyframe/index.md +++ b/files/en-us/web/css/reference/selectors/keyframe/index.md @@ -6,7 +6,7 @@ browser-compat: css.at-rules.keyframes.selectors sidebar: cssref --- -CSS **keyframe selectors** identify specific points in an animation timeline where the keyframe's style should be applied. Defined in the [CSS animation module](/en-US/docs/Web/CSS/CSS_Animations), these selectors are used exclusively within the {{cssxref("@keyframes")}} at-rule. +CSS **keyframe selectors** identify specific points in an animation timeline where keyframe styles should be applied. These selectors are used exclusively within the {{cssxref("@keyframes")}} at-rule. ## Syntax @@ -25,6 +25,12 @@ to { 100% { } +/* With */ +entry 20% { +} +exit 80% { +} + /* Selector lists */ 0%, 50%, @@ -41,16 +47,18 @@ to { - : Represents the start of the animation sequence. It is equivalent to `0%`. - `to` - : Represents the end of the animation sequence. It is equivalent to `100%`. -- {{cssxref("percentage")}} - - : A percentage between `0%` and `100%`, inclusive, representing the total progression through the animation sequence. +- `` + - : A {{cssxref("percentage")}} between `0%` and `100%`, inclusive, representing the total progression through the animation sequence. +- ` ` + - : A {{cssxref("timeline-range-name")}} preceding a `` component represents a specific progress point within the named timeline range. ## Description -A `` can be the `to` or `from` keyword, a percentage between `0%` and `100%`, inclusive, or a comma-separated list of these keywords and/or percentages. When a comma-separated list of `` is used, the style block that follows applies to all the specified progression points. +A `` can be the `to` or `from` keyword, a percentage between `0%` and `100%`, inclusive, or a comma-separated list of these keywords and/or percentages. When the percentage is preceded by a {{cssxref("timeline-range-name")}}, it defines a timeline range if the animation timelines is a view progress timeline; otherwise, the selector is ignored. When a comma-separated `` list is used, the style block that follows applies to all the specified progression points. ### Valid percentage values -Percentage values must include the percent sign (`%`). A unitless `0` is invalid. Values outside the range `0%` to `100%` (such as `-10%` or `110%`) are invalid and will cause the keyframe block to be ignored. +Percentage values must include the percent sign (`%`). Unitless values (such as `0` and `20`) and values outside the range `0%` to `100%` (such as `-10%` or `110%`) are invalid and will cause the keyframe block to be ignored. ### Cascade, order, precedence, and importance @@ -62,7 +70,7 @@ The `!important` flag is not valid within an `@keyframes` definition. ### Omitted start and end selectors -If no `0%` (or `from`) or `100%` (or `to`) keyframe is specified, the browser will use the element's computed styles for those states, allowing the animation to transition smoothly from or to the element's non-animated property values. In other words, if a property is specified in a middle-of-the-timeline keyframe, without being set within a starting or ending keyframe selector block, the property will animate from it's original value to that value. +If no `0%` (or `from`) or `100%` (or `to`) keyframe is specified, the browser will use the element's computed styles for those states, allowing the animation to transition smoothly from or to the element's non-animated property values. In other words, if a property is specified in a middle-of-the-timeline keyframe without being set within a starting or ending keyframe selector block, the property will animate from its original value to that value. For example, if an element has a `red` background color, and the following animation is applied: @@ -75,28 +83,13 @@ For example, if an element has a `red` background color, and the following anima } ``` -The background color will be `red` at the start of the animation, transitioning to `purple` a quarter of the way through the animation, remaining `purple` for half the animation, and transitioning back to `red`, the original background color, starting `75%` of the way through the {{cssxref("animation-timeline", "animation timeline", "", "nocode")}}. It will behave as if the following were set: - -```css -@keyframes changeToPurple { - 25%, - 75% { - background-color: purple; - } - 0%, - 100% { - background-color: var(--nonAnimatedColor); - } -} -``` - -Where `--nonAnimatedColor`, is the `background-color` of the element without the animation applied; in this case, `red`. +The background color will be `red` at the start of the animation, transitioning to `purple` a quarter of the way through the animation, remaining `purple` for half the animation, and transitioning back to `red`, the original background color, starting `75%` of the way through the {{cssxref("animation-timeline", "animation timeline", "", "nocode")}}. See the example that [omits the `to` and `from`](#omitting_to_and_from). #### Omitted property declarations When creating an `@keyframes` animation to animate multiple properties, you don't have to declare all the properties in all the keyframe selector blocks. -For example, in the [basic usage](#basic_usage) example, the `opacity` is declared in all the keyframe selector blocks, but only starting and ending `transforms` values are set. In that case, the element will be fully opaque 50% of the way through the animation timeline, but the point at which the element is transformed `25vw` to the right depends on the {{cssxref("animation-timing-function")}}; being half the same as the `50%` in the case of `linear`, but not if `ease-in` is used, which was done in this case. +For example, in the [basic usage](#basic_usage) example, the `opacity` is declared in all the keyframe selector blocks, but only start and end `transform` values are set. In that case, the element will be fully opaque `50%` of the way through the animation timeline, but the point at which the element is transformed `25vw` to the right depends on the {{cssxref("animation-timing-function")}} — it will be `50%` in the case of `linear`, but not if `ease-in` is used (which it is in this case). ### Cascade order @@ -129,7 +122,7 @@ This animation repeats non-changing values in multiple selector blocks, which is } ``` -We can use the cascade to group values in one selector block, then overriding them as necessary. The following is the equivalent to the previous animation, just with few lines of CSS: +We can use the cascade to group values in one selector block, then override them as necessary. The following is equivalent to the previous animation, but with fewer lines of CSS: ```css @keyframes uglyAnimation { @@ -180,6 +173,33 @@ Order is important! We can't ignore the cascade. If we reorder the above incorre } ``` +### With named timeline ranges + +Originally defined in the [CSS animation module](/en-US/docs/Web/CSS/Guides/Animations), the [CSS scroll-driven animations](/en-US/docs/Web/CSS/Guides/Scroll-driven_animations) module expanded the keyframe selector for view progress ranges. A {{cssxref("timeline-range-name")}} can precede the `` component of the selector to attach keyframes to specific progress points within the named timeline range. The `` represents the selected predefined named timeline range, and the `` after it represents the percentage progress between the start and end of that named timeline range. This addition to the selector enables adding timeline range information directly in the `@keyframes` animation definition. + +```css +@keyframes in-and-out { + entry 0% { + opacity: 0; + transform: translateX(100%); + } + entry 100% { + opacity: 1; + transform: translateX(0); + } + exit 0% { + opacity: 1; + transform: translateX(0); + } + exit 100% { + opacity: 0; + transform: translateX(-100%); + } +} +``` + +If the element's animation timeline does not have a corresponding named timeline range, then any keyframes attached to points on that named timeline range are ignored. It is possible that these attachment points are outside the active interval of the animation. When this occurs, the automatic `from` (`0%`) and `to` (`100%`) keyframes are only generated for properties that don't have keyframes at or earlier than `0%` or at or after `100%`, respectively. + ## Examples ### Basic usage @@ -208,7 +228,7 @@ div { } ``` -We create an {{cssxref("@keyframes")}} animation, applying styles to the `from`, `to`, and a middle percentage, animating the {{cssxref("opacity")}} and the {{cssxref("transform")}} properties. +We create an {{cssxref("@keyframes")}} animation, applying styles to the `from` and `to` keywords and a middle percentage. We animate the {{cssxref("opacity")}} and the {{cssxref("transform")}} properties. ```css @keyframes slide-and-fade { @@ -238,9 +258,9 @@ div { {{EmbedLiveSample("Basic usage","100%","200")}} -### Selector lists and initial values +### Selector lists -Using the same HTML and CSS as in the previous example, this example demonstrates using comma-separated selectors to group selectors, applying the same styles at multiple points in an animation. +Using the same HTML and basic styling as in the previous example, this example demonstrates using comma-separated selectors to group selectors, applying the same styles at multiple points in an animation. ```html hidden
I am animated
@@ -248,7 +268,7 @@ Using the same HTML and CSS as in the previous example, this example demonstrate #### CSS -We create a `pulse` animation that changes the size of our element. We also declare a `background-color` in only one selector block. +We create a `pulse` animation that changes the size of our element. ```css div { @@ -266,7 +286,6 @@ div { 25%, 100% { transform: scale(0.8); - background-color: black; } } ``` @@ -286,7 +305,62 @@ div { {{EmbedLiveSample("Selector lists and initial values","100%","125")}} By using a selector list with multiple comma-separated keyframe selectors, the animation "pauses" from the `25%` keyframe until it reaches the `75%` keyframe. -The `black` is only set in the `25%, 75%` keyframe, so the element animates from and to `rebeccapurple`, it's original `background-color`. + +### Omitting `to` and `from` + +This example demonstrates how, if starting or ending styles are omitted when the `to` or `from` keyframe selectors are not included in a `@keyframes` animation definition. + +#### HTML + +We include a few elements. We will be animating all of them. + +```html +
I am animated
+
I am animated
+
I am animated
+``` + +#### CSS + +We provide basic styles to our elements, giving each a different {{cssxref("outline-width")}} and {{cssxref("background-color")}}. These are the properties we will be animating. + +```css +div { + background-color: magenta; + outline: 10px dashed black; + color: white; + width: min-content; + padding: 10px; + font: 2rem sans-serif; + margin: 35px auto; + + animation: changes 5s linear infinite; +} +div:first-of-type { + background-color: blue; + outline-width: 0; +} +div:last-of-type { + background-color: green; + outline-width: 20px; +} +``` + +We create an animation that sets an element's {{cssxref("border-width")}} and {{cssxref("background-color")}} at only the `30%` keyframe. + +```css +@keyframes changes { + 30%, 40% { + background-color: black; + outline-width: 15px; +} +``` + +#### Result + +{{EmbedLiveSample("Omitting to and from","100%","420")}} + +The `background-color` and `outline-width` properties are set in the `30%, 40%` keyframe, so the elements' background colors animate from and to `green`, `magenta`, and `blue` while their outline widths animate from `0px`, `10px`, and `20px` to `15px`, remain in that state for one-tenth of the animation, and then back again. ## Specifications @@ -300,5 +374,7 @@ The `black` is only set in the `25%, 75%` keyframe, so the element animates from - {{cssxref("@keyframes")}} - {{cssxref("animation")}} +- {{cssxref("animation-range")}} - [Using CSS animations](/en-US/docs/Web/CSS/CSS_Animations/Using_CSS_animations) - [CSS animations](/en-US/docs/Web/CSS/CSS_Animations) module +- [CSS scroll-driven animations](/en-US/docs/Web/CSS/Guides/Scroll-driven_animations) From 3c3158c7bffc57f47d463e9ffc801368ed4852ea Mon Sep 17 00:00:00 2001 From: Estelle Weyl Date: Tue, 6 Jan 2026 12:08:34 +0100 Subject: [PATCH 08/15] Apply suggestions from code review Co-authored-by: Dipika Bhattacharya Co-authored-by: Chris Mills --- .../css/reference/selectors/keyframe/index.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/files/en-us/web/css/reference/selectors/keyframe/index.md b/files/en-us/web/css/reference/selectors/keyframe/index.md index 7e6ff7ff7e6faf9..ff1ddd464842fde 100644 --- a/files/en-us/web/css/reference/selectors/keyframe/index.md +++ b/files/en-us/web/css/reference/selectors/keyframe/index.md @@ -2,7 +2,7 @@ title: Keyframe selectors slug: Web/CSS/Reference/Selectors/Keyframe page-type: css-selector -browser-compat: css.at-rules.keyframes.selectors +browser-compat: css.selectors.keyframe sidebar: cssref --- @@ -54,7 +54,7 @@ to { ## Description -A `` can be the `to` or `from` keyword, a percentage between `0%` and `100%`, inclusive, or a comma-separated list of these keywords and/or percentages. When the percentage is preceded by a {{cssxref("timeline-range-name")}}, it defines a timeline range if the animation timelines is a view progress timeline; otherwise, the selector is ignored. When a comma-separated `` list is used, the style block that follows applies to all the specified progression points. +A `` can be the `to` or `from` keyword, a percentage between `0%` and `100%`, inclusive, or a comma-separated list of these keywords and/or percentages. When the percentage is preceded by a {{cssxref("timeline-range-name")}}, it defines a timeline range if the animation timeline is a view progress timeline; otherwise, the selector is ignored. When a comma-separated `` list is used, the style block that follows applies to all the specified progression points. ### Valid percentage values @@ -175,7 +175,7 @@ Order is important! We can't ignore the cascade. If we reorder the above incorre ### With named timeline ranges -Originally defined in the [CSS animation module](/en-US/docs/Web/CSS/Guides/Animations), the [CSS scroll-driven animations](/en-US/docs/Web/CSS/Guides/Scroll-driven_animations) module expanded the keyframe selector for view progress ranges. A {{cssxref("timeline-range-name")}} can precede the `` component of the selector to attach keyframes to specific progress points within the named timeline range. The `` represents the selected predefined named timeline range, and the `` after it represents the percentage progress between the start and end of that named timeline range. This addition to the selector enables adding timeline range information directly in the `@keyframes` animation definition. +Originally defined in the [CSS animation module](/en-US/docs/Web/CSS/Guides/Animations), the [CSS scroll-driven animations](/en-US/docs/Web/CSS/Guides/Scroll-driven_animations) module expanded the keyframe selector to enable view progress timeline range information to be included directly in the `@keyframes` animation definition. A {{cssxref("timeline-range-name")}} can precede the `` component of the selector to attach keyframes to specific progress points within the named timeline range. The `` represents the selected predefined named timeline range, and the `` after it represents the percentage progress between the start and end of that named timeline range. ```css @keyframes in-and-out { @@ -198,7 +198,7 @@ Originally defined in the [CSS animation module](/en-US/docs/Web/CSS/Guides/Anim } ``` -If the element's animation timeline does not have a corresponding named timeline range, then any keyframes attached to points on that named timeline range are ignored. It is possible that these attachment points are outside the active interval of the animation. When this occurs, the automatic `from` (`0%`) and `to` (`100%`) keyframes are only generated for properties that don't have keyframes at or earlier than `0%` or at or after `100%`, respectively. +If the element's animation timeline does not have a corresponding named view timeline range, then any keyframes attached to points on that named timeline range are ignored. These attachment points may be outside the active interval of the animation. When this occurs, the automatic `from` (`0%`) and `to` (`100%`) keyframes are only generated for properties that don't have keyframes at or earlier than `0%` or at or after `100%`, respectively. ## Examples @@ -260,7 +260,7 @@ div { ### Selector lists -Using the same HTML and basic styling as in the previous example, this example demonstrates using comma-separated selectors to group selectors, applying the same styles at multiple points in an animation. +Using the same HTML and basic styling as in the previous example, this example demonstrates the use of comma-separated selectors to group keyframes, applying the same styles at multiple points in an animation. ```html hidden
I am animated
@@ -322,7 +322,7 @@ We include a few elements. We will be animating all of them. #### CSS -We provide basic styles to our elements, giving each a different {{cssxref("outline-width")}} and {{cssxref("background-color")}}. These are the properties we will be animating. +We provide basic styles to our elements, and give each one a different {{cssxref("outline-width")}} and {{cssxref("background-color")}}. We will animate these two properties. ```css div { @@ -346,7 +346,7 @@ div:last-of-type { } ``` -We create an animation that sets an element's {{cssxref("border-width")}} and {{cssxref("background-color")}} at only the `30%` keyframe. +We create an animation that sets an element's `background-color` and `outline-width` at `30%` and `40%` keyframes. ```css @keyframes changes { @@ -360,7 +360,7 @@ We create an animation that sets an element's {{cssxref("border-width")}} and {{ {{EmbedLiveSample("Omitting to and from","100%","420")}} -The `background-color` and `outline-width` properties are set in the `30%, 40%` keyframe, so the elements' background colors animate from and to `green`, `magenta`, and `blue` while their outline widths animate from `0px`, `10px`, and `20px` to `15px`, remain in that state for one-tenth of the animation, and then back again. +The `background-color` and `outline-width` properties are set in `30%` and `40%` keyframes. As a result, the elements' `background-color` values animate from `green`, `magenta`, and `blue` to `black` while their `outline-width` values animate from `0px`, `10px`, and `20px` to `15px`. They remain in that state for one-tenth of the animation — between `30%` and `40%` duration. After `40%` duration, these properties animate back to their initial values again. ## Specifications From 8fa3bfea28a5e62e78f42e3b752901b4eb7614fb Mon Sep 17 00:00:00 2001 From: Estelle Weyl Date: Tue, 6 Jan 2026 12:09:38 +0100 Subject: [PATCH 09/15] Update files/en-us/web/css/reference/selectors/keyframe/index.md --- files/en-us/web/css/reference/selectors/keyframe/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/en-us/web/css/reference/selectors/keyframe/index.md b/files/en-us/web/css/reference/selectors/keyframe/index.md index ff1ddd464842fde..7a126fd8339354d 100644 --- a/files/en-us/web/css/reference/selectors/keyframe/index.md +++ b/files/en-us/web/css/reference/selectors/keyframe/index.md @@ -62,7 +62,7 @@ Percentage values must include the percent sign (`%`). Unitless values (such as ### Cascade, order, precedence, and importance -Property values set by animation `@keyframes` are more important than all normal styles, meaning no matter the {{cssxref("specificity")}}, an animated value will override values that do not have an {{cssxref("important", "!important")}} flag set. Only important property values and values currently being transitioned take precedence over animated property values. +Property values set by animation `@keyframes` are more important than all normal styles, meaning no matter the [specificity](/en-US/docs/Web/CSS/Guides/Cascade/Specificity), an animated value will override values that do not have an {{cssxref("important", "!important")}} flag set. Only important property values and values currently being transitioned take precedence over animated property values. All keyframe selectors have the same specificity. The order of keyframe selectors within the selector list does not matter. The source order only matters if a duplicate keyframe selector declares a different value for an already declared property on the same selector. From 59f4ca0a569dd76f1c6b10b68a0058395d92fb07 Mon Sep 17 00:00:00 2001 From: Estelle Weyl Date: Tue, 6 Jan 2026 12:10:25 +0100 Subject: [PATCH 10/15] Update files/en-us/web/css/guides/scroll-driven_animations/index.md Co-authored-by: Dipika Bhattacharya --- files/en-us/web/css/guides/scroll-driven_animations/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/en-us/web/css/guides/scroll-driven_animations/index.md b/files/en-us/web/css/guides/scroll-driven_animations/index.md index 9137431a71ee810..dcd909538486f26 100644 --- a/files/en-us/web/css/guides/scroll-driven_animations/index.md +++ b/files/en-us/web/css/guides/scroll-driven_animations/index.md @@ -11,7 +11,7 @@ The **CSS scroll-driven animations** module provides functionality that builds o ## Scroll-driven animations in action -You can define the scroller that controls the animation either by naming the animation or with the {{cssxref("scroll")}} function. +You can define the scroller that controls the animation either by naming the animation or with the {{cssxref("animation-timeline/scroll", "scroll()")}} function. ```html hidden live-sample___scroll_animation
From ef35d7881552b80554214bdcf097ef902c7775e9 Mon Sep 17 00:00:00 2001 From: Estelle Weyl Date: Tue, 6 Jan 2026 12:10:56 +0100 Subject: [PATCH 11/15] Update files/en-us/web/css/guides/syntax/error_handling/index.md Co-authored-by: Dipika Bhattacharya --- files/en-us/web/css/guides/syntax/error_handling/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/en-us/web/css/guides/syntax/error_handling/index.md b/files/en-us/web/css/guides/syntax/error_handling/index.md index cf6806ca9ddc3a6..250c5cdfd03c264 100644 --- a/files/en-us/web/css/guides/syntax/error_handling/index.md +++ b/files/en-us/web/css/guides/syntax/error_handling/index.md @@ -37,7 +37,7 @@ After parsing each declaration, style rule, at-rule, and so on, the browser chec ### At-rule errors -The `@` symbol, known in CSS specifications as an ``, indicates the beginning of a CSS {{cssxref("at-rule")}}. Once an at-rule begins with the `@` symbol, nothing is considered invalid from the parser's standpoint. Everything up to the first semi-colon (`;`) or the opening curly brace (`{`) is part of the at-rule's prelude. The content of each at-rule is interpreted according to the grammar rules for that particular at-rule. +The `@` symbol, known in CSS specifications as an ``, indicates the beginning of a CSS [at-rule](/en-US/docs/Web/CSS/Reference/At-rules). Once an at-rule begins with the `@` symbol, nothing is considered invalid from the parser's standpoint. Everything up to the first semi-colon (`;`) or the opening curly brace (`{`) is part of the at-rule's prelude. The content of each at-rule is interpreted according to the grammar rules for that particular at-rule. Statement at-rules, such as {{cssxref("@import")}} and {{cssxref("@namespace")}} declarations, contain just a prelude. The semicolon ends the at-rule immediately for [statement at-rules](/en-US/docs/Web/CSS/Guides/Syntax/At-rules#statement_at-rules). If the contents of the prelude are invalid according to the grammar for that at-rule, the at-rule is ignored, with the browser continuing to parse CSS after it encounters the next semi-colon. For example, if an `@import` at-rule occurs after any CSS declaration other than `@charset`, `@layer` or other `@import` statements, the `@import` declaration is ignored. From 082907f62e68147b9ba166f47cf9bf46bab0e164 Mon Sep 17 00:00:00 2001 From: Estelle Weyl Date: Tue, 6 Jan 2026 12:11:20 +0100 Subject: [PATCH 12/15] Update files/en-us/web/css/guides/syntax/error_handling/index.md Co-authored-by: Dipika Bhattacharya --- files/en-us/web/css/guides/syntax/error_handling/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/en-us/web/css/guides/syntax/error_handling/index.md b/files/en-us/web/css/guides/syntax/error_handling/index.md index 250c5cdfd03c264..02bd4819f3bf0a3 100644 --- a/files/en-us/web/css/guides/syntax/error_handling/index.md +++ b/files/en-us/web/css/guides/syntax/error_handling/index.md @@ -60,7 +60,7 @@ Some at-rules are almost always valid. The {{cssxref("@layer")}} at-rule comes i There are many ways you might make a mistake writing a selector, but only invalid selectors cause a selector list to be invalid (See [invalid selector list](/en-US/docs/Web/CSS/Reference/Selectors/Selector_list#invalid_selector_list)). -If you include a {{cssxref("class_selectors", "class")}}, {{cssxref("id_selectors", "id")}}, or {{cssxref("type_selectors", "type")}} selector for a class, id, or element (or custom element) that doesn't exist, it may be a logic error but it's not a syntax error. However, if you have a typo in a pseudo-class or a pseudo-element, it might create an invalid selector, which is an error the parser needs to address. +If you include a [class selector](/en-US/docs/Web/CSS/Reference/Selectors/Class_selectors), an [id_selectors](/en-US/docs/Web/CSS/Reference/Selectors/ID_selectors), or a [type selector](/en-US/docs/Web/CSS/Reference/Selectors/Type_selectors) for a class, id, or element (or custom element) that doesn't exist, it may be a logic error but it's not a syntax error. However, if you have a typo in a pseudo-class or a pseudo-element, it might create an invalid selector, which is an error the parser needs to address. If a selector list contains any invalid selectors, then the entire style block is ignored. There are exceptions: if the invalid selector is within an {{cssxref(":is")}} or {{cssxref(":where")}} pseudo-class (which accept [forgiving selector lists](/en-US/docs/Web/CSS/Reference/Selectors/Selector_list#forgiving_selector_list)) or if the unknown selector is a [`-webkit-` prefixed pseudo-element](#-webkit-_exception), only the unknown selector is ignored as not matching anything. The selector list is not invalidated. From e00ae7826963aa7c7c89093578de84bf47139b8d Mon Sep 17 00:00:00 2001 From: Estelle Weyl Date: Tue, 6 Jan 2026 12:14:19 +0100 Subject: [PATCH 13/15] Update files/en-us/web/css/reference/selectors/keyframe/index.md --- files/en-us/web/css/reference/selectors/keyframe/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/en-us/web/css/reference/selectors/keyframe/index.md b/files/en-us/web/css/reference/selectors/keyframe/index.md index 7a126fd8339354d..179b35f385f55c5 100644 --- a/files/en-us/web/css/reference/selectors/keyframe/index.md +++ b/files/en-us/web/css/reference/selectors/keyframe/index.md @@ -308,7 +308,7 @@ By using a selector list with multiple comma-separated keyframe selectors, the a ### Omitting `to` and `from` -This example demonstrates how, if starting or ending styles are omitted when the `to` or `from` keyframe selectors are not included in a `@keyframes` animation definition. +This example demonstrates how, when the `to` or `from` keyframe selectors are not included in a `@keyframes` animation definition, the animated properties will animated to and from the original, non-animated property values. #### HTML From 4f2711b57883a875d1a5fd31298a525c309adff0 Mon Sep 17 00:00:00 2001 From: estelle Date: Tue, 6 Jan 2026 12:24:00 +0100 Subject: [PATCH 14/15] rename slug --- files/en-us/web/api/csskeyframerule/keytext/index.md | 2 +- files/en-us/web/api/csskeyframesrule/deleterule/index.md | 2 +- files/en-us/web/api/csskeyframesrule/findrule/index.md | 2 +- files/en-us/web/css/guides/animations/index.md | 2 +- files/en-us/web/css/guides/scroll-driven_animations/index.md | 2 +- .../web/css/guides/scroll-driven_animations/timelines/index.md | 2 +- files/en-us/web/css/guides/selectors/index.md | 2 +- files/en-us/web/css/guides/syntax/error_handling/index.md | 2 +- files/en-us/web/css/reference/at-rules/@keyframes/index.md | 2 +- .../en-us/web/css/reference/properties/animation-range/index.md | 2 +- .../selectors/{keyframe => keyframe_selectors}/index.md | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) rename files/en-us/web/css/reference/selectors/{keyframe => keyframe_selectors}/index.md (99%) diff --git a/files/en-us/web/api/csskeyframerule/keytext/index.md b/files/en-us/web/api/csskeyframerule/keytext/index.md index affcb17c1a50d7c..e85ad9aa1d7bd92 100644 --- a/files/en-us/web/api/csskeyframerule/keytext/index.md +++ b/files/en-us/web/api/csskeyframerule/keytext/index.md @@ -8,7 +8,7 @@ browser-compat: api.CSSKeyframeRule.keyText {{APIRef("CSSOM") }} -The **`keyText`** property of the {{domxref("CSSKeyframeRule")}} interface represents the [keyframe selector](/en-US/docs/Web/CSS/Reference/Selectors/Keyframe) as a comma-separated list of percentage values. The from and to keywords map to 0% and 100%, respectively. +The **`keyText`** property of the {{domxref("CSSKeyframeRule")}} interface represents the [keyframe selector](/en-US/docs/Web/CSS/Reference/Selectors/Keyframe_selectors) as a comma-separated list of percentage values. The from and to keywords map to 0% and 100%, respectively. ## Value diff --git a/files/en-us/web/api/csskeyframesrule/deleterule/index.md b/files/en-us/web/api/csskeyframesrule/deleterule/index.md index 08d6e73fa3a4d7d..693909907f9e59a 100644 --- a/files/en-us/web/api/csskeyframesrule/deleterule/index.md +++ b/files/en-us/web/api/csskeyframesrule/deleterule/index.md @@ -19,7 +19,7 @@ deleteRule(select) ### Parameters - `select` - - : A string which contains the [keyframe selector](/en-US/docs/Web/CSS/Reference/Selectors/Keyframe) of the rule to be deleted, which must be: + - : A string which contains the [keyframe selector](/en-US/docs/Web/CSS/Reference/Selectors/Keyframe_selectors) of the rule to be deleted, which must be: - a comma-separated list of percentage values between 0% and 100%; - or, the keywords `from` or `to` diff --git a/files/en-us/web/api/csskeyframesrule/findrule/index.md b/files/en-us/web/api/csskeyframesrule/findrule/index.md index 2181aa9881a4408..5a66e5c06e3304d 100644 --- a/files/en-us/web/api/csskeyframesrule/findrule/index.md +++ b/files/en-us/web/api/csskeyframesrule/findrule/index.md @@ -19,7 +19,7 @@ findRule(select) ### Parameters - `select` - - : A string which contains the [keyframe selector](/en-US/docs/Web/CSS/Reference/Selectors/Keyframe) of the rule to be found, which must be: + - : A string which contains the [keyframe selector](/en-US/docs/Web/CSS/Reference/Selectors/Keyframe_selectors) of the rule to be found, which must be: - a comma-separated list of percentage values between 0% and 100%; - or, the keywords `from` or `to` diff --git a/files/en-us/web/css/guides/animations/index.md b/files/en-us/web/css/guides/animations/index.md index 3de63adf2704e1a..bb746c51bb3e8b2 100644 --- a/files/en-us/web/css/guides/animations/index.md +++ b/files/en-us/web/css/guides/animations/index.md @@ -250,7 +250,7 @@ The CSS animations module level 2 also introduces the `animation-trigger`, `anim ### At-rules and descriptors - {{cssxref("@keyframes")}} -- [``](/en-US/docs/Web/CSS/Reference/Selectors/Keyframe) +- [``](/en-US/docs/Web/CSS/Reference/Selectors/Keyframe_selectors) ### Events diff --git a/files/en-us/web/css/guides/scroll-driven_animations/index.md b/files/en-us/web/css/guides/scroll-driven_animations/index.md index dcd909538486f26..8a5128a40f4ae11 100644 --- a/files/en-us/web/css/guides/scroll-driven_animations/index.md +++ b/files/en-us/web/css/guides/scroll-driven_animations/index.md @@ -147,7 +147,7 @@ Scroll the element in the inline direction to see its background color change. S - [CSS animations](/en-US/docs/Web/CSS/Guides/Animations) module - {{cssxref("animation-timeline")}} - {{cssxref("@keyframes")}} at-rule - - [``](/en-US/docs/Web/CSS/Reference/Selectors/Keyframe) + - [``](/en-US/docs/Web/CSS/Reference/Selectors/Keyframe_selectors) - [CSS overflow](/en-US/docs/Web/CSS/Guides/Overflow) module - {{glossary("Scroll container")}} - [Scrollport](/en-US/docs/Glossary/Scroll_container#scrollport) diff --git a/files/en-us/web/css/guides/scroll-driven_animations/timelines/index.md b/files/en-us/web/css/guides/scroll-driven_animations/timelines/index.md index 0d8ea0ff07286b0..f50e90cfd9b985e 100644 --- a/files/en-us/web/css/guides/scroll-driven_animations/timelines/index.md +++ b/files/en-us/web/css/guides/scroll-driven_animations/timelines/index.md @@ -320,7 +320,7 @@ The {{cssxref("view-timeline-inset")}} arguments specify insets (if positive) or Unlike the scroll timeline's `scroll()` function, there is no `` argument in the `view()` function, as the view timeline always tracks the subject within its nearest ancestor scroll container. -In this example, as we are using inset values, we can use the `from` and `to` [keyframe selectors](/en-US/docs/Web/CSS/Reference/Selectors/Keyframe). +In this example, as we are using inset values, we can use the `from` and `to` [keyframe selectors](/en-US/docs/Web/CSS/Reference/Selectors/Keyframe_selectors). ```css live-sample___anon_view_args @keyframes action { diff --git a/files/en-us/web/css/guides/selectors/index.md b/files/en-us/web/css/guides/selectors/index.md index 090eb195690dfc4..2918a6a1aa11426 100644 --- a/files/en-us/web/css/guides/selectors/index.md +++ b/files/en-us/web/css/guides/selectors/index.md @@ -190,7 +190,7 @@ The CSS selectors module also introduces the {{CSSXref(":blank")}}, {{CSSXref(": - {{CSSxRef("::cue")}} - [CSS animations](/en-US/docs/Web/CSS/Guides/Animations) - - [``](/en-US/docs/Web/CSS/Reference/Selectors/Keyframe) + - [``](/en-US/docs/Web/CSS/Reference/Selectors/Keyframe_selectors) - {{CSSXref("@namespace")}} at-rule diff --git a/files/en-us/web/css/guides/syntax/error_handling/index.md b/files/en-us/web/css/guides/syntax/error_handling/index.md index 02bd4819f3bf0a3..349f557166ff355 100644 --- a/files/en-us/web/css/guides/syntax/error_handling/index.md +++ b/files/en-us/web/css/guides/syntax/error_handling/index.md @@ -52,7 +52,7 @@ Different at-rules have different grammar rules, different (or no) descriptors, For example, the `@font-face` rule requires both a [`font-family`](/en-US/docs/Web/CSS/Reference/At-rules/@font-face/font-family) and [`src`](/en-US/docs/Web/CSS/Reference/At-rules/@font-face/src) descriptor. If either of these is omitted or invalid, the entire `@font-face` rule is invalid. Including an unrelated descriptor, any other valid font descriptor with an invalid value, or a property style declaration within the `@font-face` nested block will not invalidate the font declaration. As long as the font name and font source are included and valid, any invalid CSS within the at-rule is ignored, but the `@font-face` block is still parsed. -While the grammar of the `@keyframes` at-rule is very different from the `@font-face` rule grammar, the type of error still impacts what gets ignored. Important declarations (marked with the {{cssxref("important")}} flag) and properties that can't be animated are ignored in keyframe rules, but they don't impact other styles declared in the same [keyframe selector](/en-US/docs/Web/CSS/Reference/Selectors/Keyframe) block. Including an invalid keyframe selector (such as a percentage value less than `0%` or greater than `100%`, or a {{cssxref("number")}} omitting the `%`) invalidates the keyframe selector list and therefore the style block is ignored. An invalid keyframe selector only invalidates the invalid selector's style block; it does not invalidate the entire `@keyframes` declaration. Including styles between two keyframe selector blocks, on the other hand, will invalidate the entire `@keyframes` at-rule. +While the grammar of the `@keyframes` at-rule is very different from the `@font-face` rule grammar, the type of error still impacts what gets ignored. Important declarations (marked with the {{cssxref("important")}} flag) and properties that can't be animated are ignored in keyframe rules, but they don't impact other styles declared in the same [keyframe selector](/en-US/docs/Web/CSS/Reference/Selectors/Keyframe_selectors) block. Including an invalid keyframe selector (such as a percentage value less than `0%` or greater than `100%`, or a {{cssxref("number")}} omitting the `%`) invalidates the keyframe selector list and therefore the style block is ignored. An invalid keyframe selector only invalidates the invalid selector's style block; it does not invalidate the entire `@keyframes` declaration. Including styles between two keyframe selector blocks, on the other hand, will invalidate the entire `@keyframes` at-rule. Some at-rules are almost always valid. The {{cssxref("@layer")}} at-rule comes in both regular and nested forms. The `@layer` statement syntax contains just the prelude, ending with a semi-colon. Alternatively, the nested syntax has layer styles nested between curly braces coming after the prelude. Omitting a closing curly brace may be a logic error but is not a syntax error. In the case of a missing closing brace in `@layer`, any styles coming after where the closing brace should have been are parsed as being in the cascade layer defined in the at-rule's prelude. The CSS is valid as there are no syntax errors; nothing is discarded. A syntax error may cause the named or anonymous layer to be empty, but the layer is still created. diff --git a/files/en-us/web/css/reference/at-rules/@keyframes/index.md b/files/en-us/web/css/reference/at-rules/@keyframes/index.md index a605cc331f7518d..130efac0e9cc728 100644 --- a/files/en-us/web/css/reference/at-rules/@keyframes/index.md +++ b/files/en-us/web/css/reference/at-rules/@keyframes/index.md @@ -37,7 +37,7 @@ The **`@keyframes`** [CSS](/en-US/docs/Web/CSS) [at-rule](/en-US/docs/Web/CSS/Gu ## Description -To use keyframes, create a `@keyframes` rule with a name that is then used by the {{ cssxref("animation-name") }} property to match an animation to its keyframe declaration. Each `@keyframes` rule contains a style list of [keyframe selectors](/en-US/docs/Web/CSS/Reference/Selectors/Keyframe), which specify percentages along the animation when the keyframe occurs, and a block containing the styles for that keyframe. +To use keyframes, create a `@keyframes` rule with a name that is then used by the {{ cssxref("animation-name") }} property to match an animation to its keyframe declaration. Each `@keyframes` rule contains a style list of [keyframe selectors](/en-US/docs/Web/CSS/Reference/Selectors/Keyframe_selectors), which specify percentages along the animation when the keyframe occurs, and a block containing the styles for that keyframe. You can list the keyframe percentages in any order; they will be handled in the order they should occur. diff --git a/files/en-us/web/css/reference/properties/animation-range/index.md b/files/en-us/web/css/reference/properties/animation-range/index.md index 4c461710ac2350b..c16128f727f490f 100644 --- a/files/en-us/web/css/reference/properties/animation-range/index.md +++ b/files/en-us/web/css/reference/properties/animation-range/index.md @@ -252,7 +252,7 @@ Scroll to see the element being animated. {{EmbedLiveSample("Examples", "100%", "480px")}} -Note how the `from`, or `0%`, keyframe property values are not applied to the animated element until the top block border edge is `10%` past the container's bottom edge; it is full size, fully opaque, and magenta. At that point, the animation is applied and it is styled with the values defined by the `0%` [keyframe selector](/en-US/docs/Web/CSS/Reference/Selectors/Keyframe). When the `animation-range-end` is reached, 25% from the top of the scrollport, it jumps back to its original styling. +Note how the `from`, or `0%`, keyframe property values are not applied to the animated element until the top block border edge is `10%` past the container's bottom edge; it is full size, fully opaque, and magenta. At that point, the animation is applied and it is styled with the values defined by the `0%` [keyframe selector](/en-US/docs/Web/CSS/Reference/Selectors/Keyframe_selectors). When the `animation-range-end` is reached, 25% from the top of the scrollport, it jumps back to its original styling. Generally, you will want to set `animation-fill-mode: both` when creating [scroll-driven animations](/en-US/docs/Web/CSS/Guides/Scroll-driven_animations). The jump to the default state occurs because we did not set the {{cssxref("animation-fill-mode")}} property on the element, which can be used to apply an animation's styles to an element before and after the animation's execution. We initially omitted the property in this example to better enable visualizing the effects of `animation-range`. diff --git a/files/en-us/web/css/reference/selectors/keyframe/index.md b/files/en-us/web/css/reference/selectors/keyframe_selectors/index.md similarity index 99% rename from files/en-us/web/css/reference/selectors/keyframe/index.md rename to files/en-us/web/css/reference/selectors/keyframe_selectors/index.md index 179b35f385f55c5..609b5cf12641bf2 100644 --- a/files/en-us/web/css/reference/selectors/keyframe/index.md +++ b/files/en-us/web/css/reference/selectors/keyframe_selectors/index.md @@ -1,6 +1,6 @@ --- title: Keyframe selectors -slug: Web/CSS/Reference/Selectors/Keyframe +slug: Web/CSS/Reference/Selectors/Keyframe_selectors page-type: css-selector browser-compat: css.selectors.keyframe sidebar: cssref From 7bcec0c348134b38100ee8c1ed662d2c04f9994b Mon Sep 17 00:00:00 2001 From: Estelle Weyl Date: Tue, 6 Jan 2026 15:58:41 +0100 Subject: [PATCH 15/15] Update files/en-us/web/css/reference/selectors/keyframe_selectors/index.md Co-authored-by: Chris Mills --- .../web/css/reference/selectors/keyframe_selectors/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/en-us/web/css/reference/selectors/keyframe_selectors/index.md b/files/en-us/web/css/reference/selectors/keyframe_selectors/index.md index 609b5cf12641bf2..e6a16f12e36a30f 100644 --- a/files/en-us/web/css/reference/selectors/keyframe_selectors/index.md +++ b/files/en-us/web/css/reference/selectors/keyframe_selectors/index.md @@ -308,7 +308,7 @@ By using a selector list with multiple comma-separated keyframe selectors, the a ### Omitting `to` and `from` -This example demonstrates how, when the `to` or `from` keyframe selectors are not included in a `@keyframes` animation definition, the animated properties will animated to and from the original, non-animated property values. +This example demonstrates how, when the `to` or `from` keyframe selectors are not included in a `@keyframes` animation definition, the animated properties will animate to and from the original, non-animated property values. #### HTML