rem() - CSS: Cascading Style Sheets

rem()
=====

The **`rem()`** CSS function returns a remainder left over when the first parameter is divided by the second parameter, similar to the JavaScript remainder operator (`%`). The remainder is the value left over when one operand, the dividend, is divided by a second operand, the divisor. It always takes the sign of the dividend.

>
> For example, the CSS `rem(27, 5)` function returns the remainder of `2`. When dividing 27 by 5, the result is 5 with a remainder of 2. The full calculation is `27 / 5 = 5 * 5 + 2`.
>
>
>

Syntax
------

```css
/\* Unitless <number> \*/
line-height: rem(21, 2); /\* 1 \*/
line-height: rem(14, 5); /\* 4 \*/
line-height: rem(5.5, 2); /\* 1.5 \*/

/\* Unit based <percentage> and <dimension> \*/
margin: rem(14%, 3%); /\* 2% \*/
margin: rem(18px, 5px); /\* 3px \*/
margin: rem(10rem, 6rem); /\* 4rem \*/
margin: rem(26vmin, 7vmin); /\* 5vmin \*/
margin: rem(1000px, 29rem); /\* 72px - if root font-size is 16px \*/

/\* Negative/positive values \*/
rotate: rem(200deg, 30deg); /\* 20deg \*/
rotate: rem(140deg, -90deg); /\* 50deg \*/
rotate: rem(-90deg, 20deg); /\* -10deg \*/
rotate: rem(-55deg, -15deg); /\* -10deg \*/

/\* Calculations \*/
scale: rem(10 * 2, 1.7); /\* 1.3 \*/
rotate: rem(10turn, 18turn / 3); /\* 4turn \*/
transition-duration: rem(20s / 2, 3000ms * 2); /\* 4s \*/
```

### Parameter

The `rem(dividend, divisor)` function accepts two comma-separated values as its parameters. Both parameters must have the same type, number, dimension, or `<percentage>`, for the function to be valid. While the units in the two parameters don't need to be the same, they do need of the same dimension type, such as `<length>`, `<angle>`, `<time>`, or `<frequency>` to be valid.

`dividend`

A calculation that resolves to a `<number>`, `<dimension>`, or `<percentage>` representing the dividend.

`divisor`

A calculation that resolves to a `<number>`, `<dimension>`, or `<percentage>` representing the divisor.

### Return value

Returns a `<number>`, `<dimension>`, or `<percentage>` (corresponds to the parameters' type) representing the remainder, that is, the operation left over.

* If `divisor` is `0`, the result is `NaN`.
* If `dividend` is `infinite`, the result is `NaN`.
* If `dividend` is positive the result is positive (`0⁺`), and if `dividend` is negative the result is negative (`0⁻`).
### Formal syntax
```

<rem()> =
  rem( <calc-sum> , <calc-sum> )

<calc-sum> =
  <calc-product> [ [ '+' | '-' ] <calc-product> ]\*

<calc-product> =
  <calc-value> [ [ '*' | '/' ] <calc-value> ]\*

<calc-value> =
  <number>        |
  <dimension>     |
  <percentage>    |
  <calc-keyword>  |
  ( <calc-sum> )

<calc-keyword> =
  e          |
  pi         |
  infinity   |
  -infinity  |
  NaN

```

Specifications
--------------

| Specification |
| --- |
| CSS Values and Units Module Level 4 # funcdef-rem |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `round()`
* `mod()`


mask-repeat - CSS: Cascading Style Sheets

mask-repeat
===========

The **`mask-repeat`** CSS property sets how mask images are repeated. A mask image can be repeated along the horizontal axis, the vertical axis, both axes, or not repeated at all.

By default, the repeated images are clipped to the size of the element, but they can be scaled to fit (using `round`) or evenly distributed from end to end (using `space`).

Syntax
------

```css
/\* One-value syntax \*/
mask-repeat: repeat-x;
mask-repeat: repeat-y;
mask-repeat: repeat;
mask-repeat: space;
mask-repeat: round;
mask-repeat: no-repeat;

/\* Two-value syntax: horizontal | vertical \*/
mask-repeat: repeat space;
mask-repeat: repeat repeat;
mask-repeat: round space;
mask-repeat: no-repeat round;

/\* Multiple values \*/
mask-repeat:
  space round,
  no-repeat;
mask-repeat:
  round repeat,
  space,
  repeat-x;

/\* Global values \*/
mask-repeat: inherit;
mask-repeat: initial;
mask-repeat: revert;
mask-repeat: revert-layer;
mask-repeat: unset;
```

One or more `<repeat-style>` values, separated by commas.

### Values

`<repeat-style>`

The one-value syntax is a shorthand for the full two-value syntax:

| Single value | Two-value equivalent |
| --- | --- |
| `repeat-x` | `repeat no-repeat` |
| `repeat-y` | `no-repeat repeat` |
| `repeat` | `repeat repeat` |
| `space` | `space space` |
| `round` | `round round` |
| `no-repeat` | `no-repeat no-repeat` |

In the two-value syntax, the first value represents the horizontal repetition behavior and the second value represents the vertical behavior. Here is an explanation of how each option works for either direction:

|  |  |
| --- | --- |
| `repeat` |
 The image is repeated as much as needed to cover the whole mask painting
 area. The last image will be clipped if it doesn't fit.
  |
| `space` |
 The image is repeated as much as possible without clipping. The first
 and last images are pinned to either side of the element, and whitespace
 is distributed evenly between the images. The
 `mask-position` property is ignored unless only one
 image can be displayed without clipping. The only case where clipping
 happens using `space` is when there isn't enough room to
 display one image.
  |
| `round` |
 As the allowed space increases in size, the repeated images will stretch
 (leaving no gaps) until there is room for another one to be added. When
 the next image is added, all of the current ones compress to allow room.
 Example: An image with an original width of 260px, repeated three times,
 might stretch until each repetition is 300px wide, and then another
 image will be added. They will then compress to 225px.
  |
| `no-repeat` |
 The image is not repeated (and hence the mask painting area will not
 necessarily be entirely covered). The position of the non-repeated mask
 image is defined by the `mask-position` CSS
 property.
  |

Formal definition
-----------------

|  |  |
| --- | --- |
| Initial value | `repeat` |
| Applies to | all elements; In SVG, it applies to container elements excluding the `<defs>` element and all graphics elements |
| Inherited | no |
| Computed value | Consists of two keywords, one per dimension |
| Animation type | discrete |

Formal syntax
-------------
```

mask-repeat =
  <repeat-style>#

<repeat-style> =
  repeat-x                                     |
  repeat-y                                     |
  [ repeat | space | round | no-repeat ]{1,2}

```

Examples
--------

### Setting repeat for a single mask

### Multiple mask image support

You can specify a different `<repeat-style>` for each mask image, separated by commas:

```css
.examplethree {
  mask-image: url("mask1.png"), url("mask2.png");
  mask-repeat: repeat-x, repeat-y;
}
```

Each image is matched with the corresponding repeat style, from first specified to last.

Specifications
--------------

| Specification |
| --- |
| CSS Masking Module Level 1 # the-mask-repeat |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Clipping and Masking in CSS


@keyframes - CSS: Cascading Style Sheets

@keyframes
==========

The **`@keyframes`** CSS at-rule controls the intermediate steps in a CSS animation sequence by defining styles for keyframes (or waypoints) along the animation sequence. This gives more control over the intermediate steps of the animation sequence than transitions.

Syntax
------

```css
@keyframes slidein {
  from {
    transform: translateX(0%);
  }

  to {
    transform: translateX(100%);
  }
}
```

### Values

`<custom-ident>`

A name identifying the keyframe list. This must match the identifier production in CSS syntax.

`from`

A starting offset of `0%`.

`to`

An ending offset of `100%`.

`<percentage>`

A percentage of the time through the animation sequence at which the specified keyframe should occur.

`<timeline-range-name>` `<percentage>`
Experimental

A percentage of the time through the specified `animation-range` at which the specified keyframe should occur. See CSS scroll-driven animations for more information on the kinds of animations that use named timeline ranges.

Description
-----------

To use keyframes, create a `@keyframes` rule with a name that is then used by the `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.

You can list the keyframe percentages in any order; they will be handled in the order they should occur.

JavaScript can access the `@keyframes` at-rule with the CSS object model interface `CSSKeyframesRule`.

### Valid keyframe lists

If a keyframe rule doesn't specify the start or end states of the animation (that is, `0%`/`from` and `100%`/`to`), browsers will use the element's existing styles for the start/end states. This can be used to animate an element from its initial state and back.

Properties that can't be animated in keyframe rules are ignored, but supported properties will still be animated.

### Resolving duplicates

If multiple keyframe sets exist for a given name, the last one encountered by the parser is used. `@keyframes` rules don't cascade, so animations never derive keyframes from more than one rule set.

If a given animation time offset is duplicated, all keyframes in the `@keyframes` rule for that percentage are used for that frame. There is cascading within a `@keyframes` rule if multiple keyframes specify the same percentage values.

### When properties are left out of some keyframes

Properties that aren't specified in every keyframe are interpolated if possible — properties that can't be interpolated are dropped from the animation. For example:

```css
@keyframes identifier {
  0% {
    top: 0;
    left: 0;
  }
  30% {
    top: 50px;
  }
  68%,
 72% {
    left: 50px;
  }
  100% {
    top: 100px;
    left: 100%;
  }
}
```

Here, the `top` property animates using the `0%`, `30%`, and `100%` keyframes, and `left` animates using the `0%`, `68%`, `72%` and `100%` keyframes.

### When a keyframe is defined multiple times

If a keyframe is defined multiple times but not all affected properties are in each keyframe, all values specified in these keyframes are considered. For example:

```css
@keyframes identifier {
  0% {
    top: 0;
  }
  50% {
    top: 30px;
    left: 20px;
  }
  50% {
    top: 10px;
  }
  100% {
    top: 0;
  }
}
```

In this example, at the `50%` keyframe, the values used are `top: 10px` and `left: 20px`.

Cascading keyframes are supported starting in Firefox 14.

### `!important` in a keyframe

Declarations in a keyframe qualified with `!important` are ignored.

```css
@keyframes important1 {
  from {
    margin-top: 50px;
  }
  50% {
    margin-top: 150px !important; /\* ignored \*/
  }
  to {
    margin-top: 100px;
  }
}

@keyframes important2 {
  from {
    margin-top: 50px;
    margin-bottom: 100px;
  }
  to {
    margin-top: 150px !important; /\* ignored \*/
    margin-bottom: 50px;
  }
}
```

Formal syntax
-------------
```

@keyframes =
  @keyframes <keyframes-name> { <qualified-rule-list> }

<keyframes-name> =
  <custom-ident>  |
  <string>

```

Examples
--------

### CSS animation examples

See Using CSS animations and Animate elements on scroll with Scroll-driven animations for examples.

Specifications
--------------

| Specification |
| --- |
| CSS Animations Level 1 # keyframes |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `animation-range`
* CSS scroll-driven animations
* Using CSS animations
* CSS animations module
* Animate elements on scroll with Scroll-driven animations
* `AnimationEvent`


:first-child - CSS: Cascading Style Sheets

:first-child
============

The **`:first-child`** CSS pseudo-class represents the first element among a group of sibling elements.

Try it
------

Syntax
------

```css
:first-child {
  /\* ... \*/
}
```

Examples
--------

### Basic example

#### HTML

```html
<div>
  <p>This text is selected!</p>
  <p>This text isn't selected.</p>
</div>

<div>
  <h2>This text isn't selected: it's not a `p`.</h2>
  <p>This text isn't selected.</p>
</div>
```

#### CSS

```css
p:first-child {
  color: lime;
  background-color: black;
  padding: 5px;
}
```

#### Result

### Styling a list

#### HTML

```html
<ul>
  <li>Item 1</li>
  <li>Item 2</li>
  <li>
    Item 3
    <ul>
      <li>Item 3.1</li>
      <li>Item 3.2</li>
      <li>Item 3.3</li>
    </ul>
  </li>
</ul>
```

#### CSS

```css
ul li {
  color: blue;
}

ul li:first-child {
  color: red;
  font-weight: bold;
}
```

#### Result

Specifications
--------------

| Specification |
| --- |
| Selectors Level 4 # first-child-pseudo |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `:-moz-first-node`
Non-standard
* `:first-of-type`
* `:last-child`
* `:nth-child()`


:hover - CSS: Cascading Style Sheets

:hover
======

The **`:hover`** CSS pseudo-class matches when the user interacts with an element with a pointing device, but does not necessarily activate it. It is generally triggered when the user hovers over an element with the cursor (mouse pointer).

Try it
------

Styles defined by the `:hover` pseudo-class will be overridden by any subsequent link-related pseudo-class (`:link`, `:visited`, or `:active`) that has at least equal specificity. To style links appropriately, put the `:hover` rule after the `:link` and `:visited` rules but before the `:active` one, as defined by the *LVHA-order*: `:link` — `:visited` — `:hover` — `:active`.

**Note:** The `:hover` pseudo-class is problematic on touchscreens. Depending on the browser, the `:hover` pseudo-class might never match, match only for a moment after touching an element, or continue to match even after the user has stopped touching and until the user touches another element. Web developers should make sure that content is accessible on devices with limited or non-existent hovering capabilities.

Syntax
------

```css
:hover {
  /\* ... \*/
}
```

Examples
--------

### Basic example

#### HTML

```html
<a href="#">Try hovering over this link.</a>
```

#### CSS

```css
a {
  background-color: powderblue;
  transition: background-color 0.5s;
}

a:hover {
  background-color: gold;
}
```

#### Result

Specifications
--------------

| Specification |
| --- |
| HTML Standard # selector-hover |
| Selectors Level 4 # the-hover-pseudo |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Chromium bug #370155: Don't make `:hover` sticky on tap on sites that set a mobile viewport
* Chromium bug #306581: Immediately show hover and active states on touch when page isn't scrollable.


CSS shadow parts - CSS: Cascading Style Sheets

CSS shadow parts
================

The **CSS shadow parts** module defines the `::part()` pseudo-element that can be set on a shadow host. Using this pseudo-element, you can enable shadow hosts to expose the selected element in the shadow tree to the outside page for styling purposes.

By default, elements in a shadow tree can be styled only within their respective shadow roots. The CSS shadow parts module enables including a `part` attribute on `<template>` descendants that make up the custom element, exposing the shadow tree node to external styling via the `::part()` pseudo-element.

Reference
---------

### Selectors

* `::part()`
### HTML attributes

* `part`
* `exportparts`
### Definitions

* Shadow tree
Guides
------

CSS pseudo-elements

Alphabetical list of pseudo-elements defined by all the CSS specifications and WebVTT

Web components

Overview of the different APIs that enable creating reusable custom elements or web components.

Related concepts
----------------

* HTML `<template>` element
* HTML `<slot>` element
* `Element.part` property
* `Element.shadowRoot` property
* `Element.attachShadow()` method
* `ShadowRoot` interface
* CSS scoping module
    + `:host`
    + `:host()`
    + `:host-context()`
    + `::slotted`
Specifications
--------------

| Specification |
| --- |
| CSS Shadow Parts  |

See also
--------

* CSS pseudo elements module
* CSS selectors module
* Using shadow DOM
* Templates: Styling outside of the current scope on web.dev (2023)


mask-composite - CSS: Cascading Style Sheets

mask-composite
==============

The **`mask-composite`** CSS property represents a compositing operation used on the current mask layer with the mask layers below it.

Syntax
------

```css
/\* Keyword values \*/
mask-composite: add;
mask-composite: subtract;
mask-composite: intersect;
mask-composite: exclude;

/\* Global values \*/
mask-composite: inherit;
mask-composite: initial;
mask-composite: revert;
mask-composite: revert-layer;
mask-composite: unset;
```

One or more of the keyword values listed below, separated by commas.

### Values

For the composition the current mask layer is referred to as *source*, while all layers below it are referred to as *destination*.

`add`

The source is placed over the destination.

`subtract`

The source is placed, where it falls outside of the destination.

`intersect`

The parts of source that overlap the destination, replace the destination.

`exclude`

The non-overlapping regions of source and destination are combined.

Formal definition
-----------------

|  |  |
| --- | --- |
| Initial value | `add` |
| Applies to | all elements; In SVG, it applies to container elements excluding the `<defs>` element and all graphics elements |
| Inherited | no |
| Computed value | as specified |
| Animation type | discrete |

Formal syntax
-------------
```

mask-composite =
  <compositing-operator>#

<compositing-operator> =
  add        |
  subtract   |
  intersect  |
  exclude

```

Examples
--------

### Compositing mask layers with addition

Specifications
--------------

| Specification |
| --- |
| CSS Masking Module Level 1 # the-mask-composite |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Clipping and Masking in CSS


CSS at-rule functions - CSS: Cascading Style Sheets

CSS at-rule functions
=====================

**CSS at-rule functions** are at-rule statements that represent complex rules or can invoke special data processing or calculations.

Syntax
------

```css
@identifier function([argument]? [, argument]!) {
}
```

The syntax begins with the at symbol `@` and an at-rule identifier, such as `import`. This is followed by the **name of the at-rule function**, such as `url`, followed by a pair of opening and closing parentheses. One or more arguments are specified inside the parentheses.

Some at-rule functions can take multiple arguments, which are formatted similar to CSS property values. White space is allowed, but it is optional inside the parentheses. Multiple arguments can be separated using a comma or a space.

@import functions
-----------------

The `@import` at-rule is used to import styles from other stylesheets.

`@import url()`

Imports a stylesheet file from the specified URL.

`@import src()`

Imports a stylesheet file from the specified source.

`@import supports()`

Imports a stylesheet file based on browser support.

`@import layer()`

Imports a stylesheet file into the specified cascade layer.

@supports functions
-------------------

The `@supports` at-rule checks for a browser's support for the specified CSS feature and then applies the CSS styling.

`@supports selector()`

Applies CSS rules after checking browser's support for the specified selector syntax.

`@supports font-tech()`

Applies CSS rules after checking browser's support for the specified font technology.

`@supports font-format()`

Applies CSS rules after checking browser's support for the specified font format.

@namespace functions
--------------------

The `@namespace` at-rule is used to specify XML namespaces to be used in a CSS stylesheet.

`@namespace url()`

Defines XML namespace from the specified URL.

`@namespace src()`

Defines XML namespace from the specified source.

@container functions
--------------------

The `@container` at-rule is used to specify styles for a containment context.

`@container style()`

Defines the containment context style.


-webkit-mask-box-image - CSS: Cascading Style Sheets

-webkit-mask-box-image
======================

**Non-standard:** This feature is non-standard and is not on a standards track. Do not use it on production sites facing the Web: it will not work for every user. There may also be large incompatibilities between implementations and the behavior may change in the future.

The non-standard prefixed **`-webkit-mask-box-image`** shorthand property sets the mask image for an element's border box.

**Note:** This property is not standard and is not on any standards track. Consider using the `mask-border` property instead.

Constituent properties
----------------------

This property is a shorthand for the following CSS properties:

* `-webkit-mask-box-image-source`
* `-webkit-mask-box-image-outset`
* `-webkit-mask-box-image-repeat`

The values includes the `<image>` to be used as the mask border, and optionally four border outset values and up to two border repeat styles.

Syntax
------

```css
/\* default \*/
-webkit-mask-box-image: none;

/\* image \*/
-webkit-mask-box-image: url(image.png);

/\* image edge-offset \*/
-webkit-mask-box-image: url(image.png) 10 20 20 10;
-webkit-mask-box-image: url(image.png) 10px 20px 20px 10px;

/\* image repeat-style \*/
-webkit-mask-box-image: url(image.png) space repeat;

/\* image edge-offset repeat-style \*/
-webkit-mask-box-image: url(image.png) 10px 20px 20px 10px space repeat;

/\* Global values \*/
-webkit-mask-box-image: inherit;
-webkit-mask-box-image: initial;
-webkit-mask-box-image: revert;
-webkit-mask-box-image: revert-layer;
-webkit-mask-box-image: unset;
```

### Values

`<image>`

The location of the image resource to be used as a mask image, `<gradient>`, or other `<image>` value.

`none`

Used to specify that a border box is to have no mask image.

`<length>`

The size of the mask image's offset. See `<length>` for possible units.

``<percentage>``

The mask image's offset has a percentage value relative to the border box's corresponding dimension (width or height).

`<number>`

The size of the mask image's offset in pixels.

`repeat`

The mask image is repeated as many times as is necessary to span the border box. May include a partial image if the mask image does not divide evenly into the border box.

`stretch`

The mask image is stretched to contain the border box exactly.

`round`

The mask image is stretched somewhat and repeated such that there is no partial mask image at the end of the border box.

`space`

The mask image is repeated as many times as possible without stretching. There is no partial mask image at the end of the border box.

The outset values, or edge offsets, define the distances from the top, right, bottom, and left edges of the image, in that order. The values can be set as `<length>`, `<number>`, or `<percentage>`, with numbers interpreted as pixel lengths.

Border repeat styles, when included, are interpreted in the order of `<repeat-x> <repeat-y>`. If only one value is declared, the value is the same for both axes. While similar to ``background-repeat``, the `cover` and `contain` values are not supported.

Formal definition
-----------------

* Initial value: `none`
* Applies to: all elements
* Inherited: no
* Computed value: as specified
Formal syntax
-------------
```

-webkit-mask-box-image: <mask-image-source> [<mask-image-offset>{4} <mask-border-repeat>{1,2} ]

Where:

<mask-image-source> = `<uri>` | <gradient> | none

<mask-image-offset> = <length> | <percentage> | <number>

<repeat-style> = repeat | stretch | round | space
```

Examples
--------

### Setting an image

```css
.exampleone {
  -webkit-mask-box-image: url("mask.png");
}
```

### Offsetting and filling an image

```css
.exampletwo {
  -webkit-mask-box-image: url("logo.png") 100 100 0 0 round round;
}
```

Specifications
--------------

Not part of any standard.

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* CSS `mask-border` property
* CSS `border-image` property
* Safari CSS reference: `-webkit-mask-box-image`


border-block-style - CSS: Cascading Style Sheets

border-block-style
==================

The **`border-block-style`** CSS property defines the style of the logical block borders of an element, which maps to a physical border style depending on the element's writing mode, directionality, and text orientation. It corresponds to the `border-top-style` and `border-bottom-style`, or `border-left-style` and `border-right-style` properties depending on the values defined for `writing-mode`, `direction`, and `text-orientation`.

Try it
------

The border style in the other dimension can be set with `border-inline-style`, which sets `border-inline-start-style`, and `border-inline-end-style`.

Syntax
------

```css
/\* <'border-style'> values \*/
border-block-style: dashed;
border-block-style: dotted;
border-block-style: groove;

/\* Global values \*/
border-block-style: inherit;
border-block-style: initial;
border-block-style: revert;
border-block-style: revert-layer;
border-block-style: unset;
```

### Values

`<'border-style'>`

The line style of the border. See `border-style`.

Formal definition
-----------------

|  |  |
| --- | --- |
| Initial value | `none` |
| Applies to | all elements |
| Inherited | no |
| Computed value | as specified |
| Animation type | discrete |

Formal syntax
-------------
```

border-block-style =
  <'border-top-style'>{1,2}

```

Examples
--------

### Dashed border with vertical text

#### HTML

```html
<div>
  <p class="exampleText">Example text</p>
</div>
```

#### CSS

```css
div {
  background-color: yellow;
  width: 120px;
  height: 120px;
}

.exampleText {
  writing-mode: vertical-lr;
  border: 5px solid blue;
  border-block-style: dashed;
}
```

#### Results

Specifications
--------------

| Specification |
| --- |
| CSS Logical Properties and Values Level 1 # propdef-border-block-style |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* CSS Logical Properties and Values
* This property maps to one of the physical border properties: `border-top-style`, `border-right-style`, `border-bottom-style`, or `border-left-style`.
* `writing-mode`, `direction`, `text-orientation`


text-emphasis-position - CSS: Cascading Style Sheets

text-emphasis-position
======================

The **`text-emphasis-position`** CSS property sets where emphasis marks are drawn. Like ruby text, if there isn't enough room for emphasis marks, the line height is increased.

Try it
------

Syntax
------

```css
/\* Initial value \*/
text-emphasis-position: over right;

/\* Keywords value \*/
text-emphasis-position: over left;
text-emphasis-position: under right;
text-emphasis-position: under left;

text-emphasis-position: left over;
text-emphasis-position: right under;
text-emphasis-position: left under;

/\* Global values \*/
text-emphasis-position: inherit;
text-emphasis-position: initial;
text-emphasis-position: revert;
text-emphasis-position: revert-layer;
text-emphasis-position: unset;
```

### Values

`over`

Draws marks over the text in horizontal writing mode.

`under`

Draws marks under the text in horizontal writing mode.

`right`

Draws marks to the right of the text in vertical writing mode.

`left`

Draws marks to the left of the text in vertical writing mode.

Description
-----------

The preferred position of emphasis marks depends on the language. In Japanese for example, the preferred position is `over right`. In Chinese, on the other hand, the preferred position is `under right`. The informative table below summarizes the preferred emphasis mark positions for Chinese, Mongolian and Japanese:

Preferred emphasis mark and ruby position| Language | Preferred position | Illustration |
| --- | --- | --- |
| Horizontal | Vertical |
| Japanese | over | right | Emphasis marks appear over each emphasized character in horizontal Japanese text. | Emphasis marks appear on the right of each emphasized character in vertical Japanese text. |
| Korean |
| Mongolian |
| Chinese | under | right | Emphasis marks appear below each emphasized character in horizontal Simplified Chinese text. |

**Note:** The `text-emphasis-position` cannot be set, and therefore are not reset either, using the `text-emphasis` shorthand property.

Formal definition
-----------------

|  |  |
| --- | --- |
| Initial value | `over right` |
| Applies to | all elements |
| Inherited | yes |
| Computed value | as specified |
| Animation type | discrete |

Formal syntax
-------------
```

text-emphasis-position =
  [ over | under ]   &&
  [ right | left ]?

```

Examples
--------

### Preferring ruby over emphasis marks

Some editors prefer to hide emphasis marks when they conflict with ruby. In HTML, this can be done with the following style rule:

```css
ruby {
  text-emphasis: none;
}
```

### Preferring emphasis marks over ruby

Some other editors prefer to hide ruby when they conflict with emphasis marks. In HTML, this can be done with the following pattern:

```css
em {
  text-emphasis: dot; /\* Set text-emphasis for <em> elements \*/
}

em rt {
  display: none; /\* Hide ruby inside <em> elements \*/
}
```

Specifications
--------------

| Specification |
| --- |
| CSS Text Decoration Module Level 3 # text-emphasis-position-property |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* The longhand properties `text-emphasis-style`, `text-emphasis-color`, and the corresponding shorthand property `text-emphasis`.


Specificity - CSS: Cascading Style Sheets

Specificity
===========

**Specificity** is the algorithm used by browsers to determine the CSS declaration that is the most relevant to an element, which in turn, determines the property value to apply to the element. The specificity algorithm calculates the weight of a CSS selector to determine which rule from competing CSS declarations gets applied to an element.

**Note:** Browsers consider specificity **after** determining cascade origin and importance. In other words, for competing property declarations, specificity is relevant and compared only between selectors from the one cascade origin and layer that has precedence for the property. Scoping proximity and order of appearance become relevant when the selector specificities of the competing declarations in the cascade layer with precedence are equal.

How is specificity calculated?
------------------------------

Specificity is an algorithm that calculates the weight that is applied to a given CSS declaration. The weight is determined by the number of selectors of each weight category in the selector matching the element (or pseudo-element). If there are two or more declarations providing different property values for the same element, the declaration value in the style block having the matching selector with the greatest algorithmic weight gets applied.

The specificity algorithm is basically a three-column value of three categories or weights - ID, CLASS, and TYPE - corresponding to the three types of selectors. The value represents the count of selector components in each weight category and is written as *ID - CLASS - TYPE*. The three columns are created by counting the number of selector components for each selector weight category in the selectors that match the element.

### Selector weight categories

The selector weight categories are listed here in the order of decreasing specificity:

ID column

Includes only ID selectors, such as `#example`. For each ID in a matching selector, add 1-0-0 to the weight value.

CLASS column

Includes class selectors, such as `.myClass`, attribute selectors like `[type="radio"]` and `[lang|="fr"]`, and pseudo-classes, such as `:hover`, `:nth-of-type(3n)`, and `:required`. For each class, attribute selector, or pseudo-class in a matching selector, add 0-1-0 to the weight value.

TYPE column

Includes type selectors, such as `p`, `h1`, and `td`, and pseudo-elements like `::before`, `::placeholder`, and all other selectors with double-colon notation. For each type or pseudo-element in a matching selector, add 0-0-1 to the weight value.

No value

The universal selector (`*`) and the pseudo-class `:where()` and its parameters aren't counted when calculating the weight so their value is 0-0-0, but they do match elements. These selectors do not impact the specificity weight value.

Combinators, such as `+`, `>`, `~`, " ", and `||`, may make a selector more specific in what is selected but they don't add any value to the specificity weight.

The `&` nesting combinator doesn't add specificity weight, but nested rules do. In terms of specificity, and functionality, nesting is very similar to the `:is()` pseudo-class.

Like nesting, the `:is()`, `:has()`, and negation (`:not()`) pseudo-classes themselves add no weight. The parameters in these selectors, however, do. The specificity weight of each comes from the selector parameter in the list of selectors with the highest specificity. Similarly, with nested selectors, the specificity weight added by the nested selector component is the selector in the comma-separated list of nested selectors with the highest specificity.

The `:not()`, `:is()`, `:has()` and CSS nesting exceptions are discussed below.

#### Matching selector

The specificity weight comes from the matching selector. Take this CSS selector with three comma-separated selectors as an example:

```css
[type="password"],
input:focus,
:root #myApp input:required {
  color: blue;
}
```

The `[type="password"]` selector in the above selector list, with a specificity weight of `0-1-0`, applies the `color: blue` declaration to all password input types.

All inputs, no matter the type, when receiving focus, match the second selector in the list, `input:focus`, with a specificity weight of `0-1-1`; this weight is made up of the `:focus` pseudo-class (0-1-0) and the `input` type (0-0-1). If the password input has focus, it will match `input:focus`, and the specificity weight for the `color: blue` style declaration will be `0-1-1`. When that password doesn't have focus, the specificity weight remains at `0-1-0`.

The specificity for a required input nested in an element with attribute `id="myApp"` is `1-2-1`, based on one ID, two pseudo-classes, and one element type.

If the password input type with `required` is nested in an element with `id="myApp"` set, the specificity weight will be `1-2-1`, based on one ID, two pseudo-classes, and one element type, whether or not it has focus. Why is the specificity weight `1-2-1` rather than `0-1-1` or `0-1-0` in this case? Because the specificity weight comes from the matching selector with the greatest specificity weight. The weight is determined by comparing the values in the three columns, from left to right.

```css
[type="password"]             /\* 0-1-0 \*/
input:focus                   /\* 0-1-1 \*/
:root #myApp input:required   /\* 1-2-1 \*/
```

### Three-column comparison

Once the specificity values of the relevant selectors are determined, the number of selector components in each column are compared, from left to right.

```css
#myElement {
  color: green; /\* 1-0-0 - WINS!! \*/
}
.bodyClass .sectionClass .parentClass [id="myElement"] {
  color: yellow; /\* 0-4-0 \*/
}
```

The first column is the value of the *ID* component, which is the number of IDs in each selector. The numbers in the *ID* columns of competing selectors are compared. The selector with the greater value in the *ID* column wins no matter what the values are in the other columns. In the above example, even though the yellow selector has more components in total, only the value of the first column matters.

If the number in the *ID* columns of competing selectors is the same, then the next column, *CLASS*, is compared, as shown below.

```css
#myElement {
  color: yellow; /\* 1-0-0 \*/
}
#myApp [id="myElement"] {
  color: green; /\* 1-1-0 - WINS!! \*/
}
```

The *CLASS* column is the count of class names, attribute selectors, and pseudo-classes in the selector. When the *ID* column value is the same, the selector with the greater value in the *CLASS* column wins, no matter the value in the *TYPE* column. This is shown in the example below.

```css
:root input {
  color: green; /\* 0-1-1 - WINS because CLASS column is greater \*/
}
html body main input {
  color: yellow; /\* 0-0-4 \*/
}
```

If the numbers in the *CLASS* and *ID* columns in competing selectors are the same, the *TYPE* column becomes relevant. The *TYPE* column is the number of element types and pseudo-elements in the selector. When the first two columns have the same value, the selector with the greater number in the *TYPE* column wins.

If the competing selectors have the same values in all the three columns, the proximity rule comes into play, wherein the last declared style gets precedence.

```css
input.myClass {
  color: yellow; /\* 0-1-1 \*/
}
:root input {
  color: green; /\* 0-1-1 WINS because it comes later \*/
}
```

### The `:is()`, `:not()`, `:has()` and CSS nesting exceptions

The matches-any pseudo-class `:is()`, the relational pseudo-class `:has()`, and the negation pseudo-class `:not()` are *not* considered as pseudo-classes in the specificity weight calculation. They themselves don't add any weight to the specificity equation. However, the selector parameters passed into the pseudo-class parenthesis are part of the specificity algorithm; the weight of the matches-any and negation pseudo-class in the specificity value calculation is the weight of the parameter's weight.

```css
p {
  /\* 0-0-1 \*/
}
:is(p) {
  /\* 0-0-1 \*/
}

h2:nth-last-of-type(n + 2) {
  /\* 0-1-1 \*/
}
h2:has(~ h2) {
  /\* 0-0-2 \*/
}

div.outer p {
  /\* 0-1-2 \*/
}
div:not(.inner) p {
  /\* 0-1-2 \*/
}
```

Note that in the above CSS pairing, the specificity weight provided by the `:is()`, `:has()` and `:not()` pseudo-classes is the value of the selector parameter, not of the pseudo-class.

All three of these pseudo-classes accept complex selector lists, a list of comma-separated selectors, as a parameter. This feature can be used to increase a selector's specificity:

```css
:is(p, #fakeId) {
  /\* 1-0-0 \*/
}
h1:has(+ h2, > #fakeId) {
  /\* 1-0-1 \*/
}
p:not(#fakeId) {
  /\* 1-0-1 \*/
}
div:not(.inner, #fakeId) p {
  /\* 1-0-2 \*/
}
```

In the above CSS code block, we have included `#fakeId` in the selectors. This `#fakeId` adds `1-0-0` to the specificity weight of each paragraph.

When creating complex selector lists with CSS nesting this behaves in exactly the same way as the `:is()` pseudo-class.

```css
p,
#fakeId {
  span {
    /\* 1-0-1 \*/
  }
}
```

In the above code block the complex selector `p, #fakeId` the specificity is taken from `#fakeId` and also the `span`, so this create a specificity of `1-0-1` for both `p span` and `#fakeId span`. This is the equivalent specificity as the `:is(p, #fakeId) span` selector.

Generally, you want to keep specificity down to a minimum, but if you need to increase an element's specificity for a particular reason, these three pseudo-classes can help.

```css
a:not(#fakeId#fakeId#fakeID) {
  color: blue; /\* 3-0-1 \*/
}
```

In this example, all links will be blue, unless overridden by a link declaration with 3 or more IDs, a color value matching an `a` includes the `!important` flag, or if the link has an inline style color declaration. If you use such a technique, add a comment to explain why the hack was needed.

### Inline styles

Inline styles added to an element (e.g., `style="font-weight: bold;"`) always overwrite any normal styles in author stylesheets, and therefore, can be thought of as having the highest specificity. Think of inline styles as having a specificity weight of `1-0-0-0`.

The only way to override inline styles is by using `!important`.

Many JavaScript frameworks and libraries add inline styles. Using `!important` with a very targeted selector, such as an attribute selector using the inline style, is one way to override these inline styles.

```html
<p style="color: purple">…</p>
```

```css
p[style\*="purple"] {
  color: rebeccapurple !important;
}
```

Make sure to include a comment with every inclusion of the important flag so code maintainers understand why a CSS anti-pattern was used.

### The `!important` exception

CSS declarations marked as important override any other declarations within the same cascade layer and origin. Although technically, `!important` has nothing to do with specificity, it interacts directly with specificity and the cascade. It reverses the cascade order of stylesheets.

If declarations from the same origin and cascade layer conflict and one property value has the `!important` flag set, the important declaration is applied no matter the specificity. When conflicting declarations from the same origin and cascade layer with the `!important` flag are applied to the same element, the declaration with a greater specificity is applied.

Using `!important` to override specificity is considered a **bad practice** and should be avoided for this purpose. Understanding and effectively using specificity and the cascade can remove any need for the `!important` flag.

Instead of using `!important` to override foreign CSS (from external libraries, like Bootstrap or normalize.css), import the third-party scripts directly into cascade layers. If you must use `!important` in your CSS, comment your usage so future code maintainers know why the declaration was marked important and know not to override it. But definitely, don't use `!important` when writing plugins or frameworks that other developers will need to incorporate without being able to control.

### The `:where()` exception

The specificity-adjustment pseudo-class `:where()` always has its specificity replaced with zero, `0-0-0`. It enables making CSS selectors very specific in what element is targeted without any increase to specificity.

In creating third-party CSS to be used by developers who don't have access to edit your CSS, it's considered a good practice to create CSS with the lowest possible specificity. For example, if your theme includes the following CSS:

```css
:where(#defaultTheme) a {
  /\* 0-0-1 \*/
  color: red;
}
```

Then the developer implementing the widget can easily override the link color using only type selectors.

```css
footer a {
  /\* 0-0-2 \*/
  color: blue;
}
```

### How `@scope` blocks affect specificity

Including a ruleset inside a `@scope` block does not affect the specificity of its selector, regardless of the selectors used inside the scope root and limit. For example:

```css
@scope (.article-body) {
  /\* img has a specificity of 0-0-1, as expected \*/
  img { ... }
}
```

However, if you decide to explicitly prepend the `:scope` pseudo-class to your scoped selectors, you'll need to factor it in when calculating their specificity. `:scope`, like all regular pseudo-classes, has a specificity of 0-1-0. For example:

```css
@scope (.article-body) {
  /\* :scope img has a specificity of 0-1-0 + 0-0-1 = 0-1-1 \*/
  :scope img { ... }
}
```

When using the `&` selector inside a `@scope` block, `&` represents the scope root selector; it is internally rewritten to that selector wrapped inside an `:is()` selector. So for example, in:

```css
@scope (figure, #primary) {
  & img { ... }
}
```

`& img` is equivalent to `:is(figure, #primary) img`.

Since `:is()` takes the specificity of its most specific argument (`#primary`, in this case), the specificity of the scoped `& img` selector is therefore 1-0-0 + 0-0-1 = 1-0-1.

Tips for handling specificity headaches
---------------------------------------

Instead of using `!important`, consider using cascade layers and using low weight specificity throughout your CSS so that styles are easily overridden with slightly more specific rules. Using semantic HTML helps provide anchors from which to apply styling.

### Making selectors specific with and without adding specificity

By indicating the section of the document you're styling before the element you're selecting, the rule becomes more specific. Depending on how you add it, you can add some, a lot, or no specificity, as shown below:

```html
<main id="myContent">
  <h1>Text</h1>
</main>
```

```css
#myContent h1 {
  color: green; /\* 1-0-1 \*/
}
[id="myContent"] h1 {
  color: yellow; /\* 0-1-1 \*/
}
:where(#myContent) h1 {
  color: blue; /\* 0-0-1 \*/
}
```

No matter the order, the heading will be green because that rule is the most specific.

#### Reducing ID specificity

Specificity is based on the form of a selector. Including the `id` of an element as an attribute selector rather than an id selector is a good way to make an element more specific without adding an overabundance of specificity. In the previous example, the selector `[id="myContent"]` counts as an attribute selector for the purpose of determining the selector's specificity, even though it selects an ID.

You can also include the `id` or any part of a selector as a parameter in the `:where()` specificity-adjustment pseudo class if you need to make a selector more specific but don't want to add any specificity at all.

### Increasing specificity by duplicating selector

As a special case for increasing specificity, you can duplicate weights from the *CLASS* or *ID* columns. Duplicating id, class, pseudo-class or attribute selectors within a compound selector will increase specificity when overriding very specific selectors over which you have no control.

```css
#myId#myId#myId span {
  /\* 3-0-1 \*/
}
.myClass.myClass.myClass span {
  /\* 0-3-1 \*/
}
```

Use this sparingly, if at all. If using selector duplication, always comment your CSS.

By using `:is()` and `:not()` (and also `:has()`), you can increase specificity even if you can't add an `id` to a parent element:

```css
:not(#fakeID#fakeId#fakeID) span {
  /\* 3-0-1 \*/
}
:is(#fakeID#fakeId#fakeID, span) {
  /\* 3-0-0 \*/
}
```

### Precedence over third-party CSS

Leveraging cascade layers is the standard way of enabling one set of styles to take precedence over another set of styles; cascade layers enable this without using specificity! Normal (not important) author styles imported into cascade layers have lower precedence than unlayered author styles.

If styles are coming from a stylesheet you can't edit or don't understand and you need to override styles, a strategy is to import the styles you don't control into a cascade layer. Styles in subsequently declared layers take precedence, with unlayered styles having precedence over all layered styles from the same origin.

When two selectors from different layers match the same element, origin and importance take precedence; the specificity of the selector in the losing stylesheet is irrelevant.

```html
<style>
 @import TW.css layer();
 p,
 p \* {
 font-size: 1rem;
 }
</style>
```

In the above example, all paragraph text, including the nested content, will be `1rem` no matter how many class names the paragraphs have that match the TW stylesheet.

### Avoiding and overriding `!important`

The best approach is to not use `!important`. The above explanations on specificity should be helpful in avoiding using the flag and removing it altogether when encountered.

To remove the perceived need for `!important`, you can do one of the following:

* Increase the specificity of the selector of the formerly `!important` declaration so that it is greater than other declarations
* Give it the same specificity and put it after the declaration it is meant to override
* Reduce the specificity of the selector you are trying to override.

All these methods are covered in preceding sections.

If you're unable to remove `!important` flags from an authors style sheet, the only solution to overriding the important styles is by using `!important`. Creating a cascade layer of important declaration overrides is an excellent solution. Two ways of doing this include:

#### Method 1

1. Create a separate, short style sheet containing only important declarations specifically overriding any important declarations you were unable to remove.
2. Import this stylesheet as the first import in your CSS using `layer()`, including the `@import` statement, before linking to other stylesheets. This is to ensure that the important overrides is imported as the first layer.

```html
<style>
 @import importantOverrides.css layer();
</style>
```

#### Method 2

1. At the beginning of your stylesheet declarations, create a named cascade layer, like so:

```css
@layer importantOverrides;
```

2. Each time you need to override an important declaration, declare it within the named layer. Only declare important rules within the layer.

```css
[id="myElement"] p {
  /\* normal styles here \*/
}
@layer importantOverrides {
  [id="myElement"] p {
    /\* important style here \*/
  }
}
```

The specificity of the selector of the important style within the layer can be low, as long as it matches the element you are trying to override. Normal layers should be declared outside the layer because layered styles have lower precedence than unlayered styles.

### Tree proximity ignorance

The proximity of an element to other elements that are referenced in a given selector has no impact on specificity.

```css
body h1 {
  color: green;
}

html h1 {
  color: purple;
}
```

The `<h1>` elements will be purple because when declarations have the same specificity, the last declared selector has precedence.

### Directly targeted elements vs. inherited styles

Styles for a directly targeted element will always take precedence over inherited styles, regardless of the specificity of the inherited rule. Given the following CSS and HTML:

```css
#parent {
  color: green;
}

h1 {
  color: purple;
}
```

```html
<html lang="en">
  <body id="parent">
    <h1>Here is a title!</h1>
  </body>
</html>
```

The `h1` will be purple because the `h1` selector targets the element specifically, while the green is inherited from the `#parent` declarations.

Examples
--------

In the following CSS, we have three selectors targeting `<input>` elements to set a color. For a given input, the specificity weight of the color declaration having precedence is the matching selector with the greatest weight:

```css
#myElement input.myClass {
  color: red;
} /\* 1-1-1 \*/
input[type="password"]:required {
  color: blue;
} /\* 0-2-1 \*/
html body main input {
  color: green;
} /\* 0-0-4 \*/
```

If the above selectors all target the same input, the input will be red, as the first declaration has the highest value in the *ID* column.

The last selector has four *TYPE* components. While it has the highest integer value, no matter how many elements and pseudo-elements are included, even if there were 150, TYPE components never have precedence over *CLASS* components. The column values are compared starting from left to right when column values are equal.

Had we converted the id selector in the example code above to an attribute selector, the first two selectors would have the same specificity, as shown below:

```css
[id="myElement"] input.myClass {
  color: red;
} /\* 0-2-1 \*/
input[type="password"]:required {
  color: blue;
} /\* 0-2-1 \*/
```

When multiple declarations have equal specificity, the last declaration found in the CSS is applied to the element. If both selectors match the same `<input>`, the color will be blue.

Additional notes
----------------

A few things to remember about specificity:

1. Specificity only applies when the same element is targeted by multiple declarations in the same cascade layer or origin. Specificity only matters for declarations of the same importance and same origin and cascade layer. If matching selectors are in different origins, the cascade determines which declaration takes precedence.
2. When two selectors in the same cascade layer and origin have the same specificity, scoping proximity is then calculated; the ruleset with the lowest scoping proximity wins. See How `@scope` conflicts are resolved for more details and an example.
3. If scope proximity is also the same for both selectors, source order then comes into play. When all else is equal, the last selector wins.
4. As per CSS rules, directly targeted elements will always take precedence over rules which an element inherits from its ancestor.
5. Proximity of elements in the document tree has no effect on the specificity.
Specifications
--------------

| Specification |
| --- |
| Selectors Level 4 # specificity-rules |

See also
--------

* "Specificity" in "Cascade and inheritance"
* SpeciFISHity
* Specificity Calculator: An interactive website to test and understand your own CSS rules
* *ID-CLASS-TYPE* exercise a specificity quiz
* CSS key concepts:
    + CSS syntax
    + At-rules
    + Comments
    + Inheritance
    + Box model
    + Layout modes
    + Visual formatting models
    + Margin collapsing
    + Values
        - Initial values
        - Computed values
        - Used values
        - Actual values
    + Value definition syntax
    + Shorthand properties
    + Replaced elements
    + CSS nesting module


CSS flow layout - CSS: Cascading Style Sheets

CSS flow layout
===============

*Normal Flow*, or Flow Layout, is the way that Block and Inline elements are displayed on a page before any changes are made to their layout. The flow is essentially a set of things that are all working together and know about each other in your layout. Once something is taken *out of flow* it works independently.

In normal flow, **inline** elements display in the inline direction, that is in the direction words are displayed in a sentence according to the Writing Mode of the document. **Block** elements display one after the other, as paragraphs do in the Writing Mode of that document. In English therefore, inline elements display one after the other, starting on the left, and block elements start at the top and move down the page.

Basic Example
-------------

The following example demonstrates Block and Inline Level boxes. The two paragraph elements with a green border are Block Level, displaying one under the other.

The first sentence also includes a span element with a blue background. This is inline level and therefore displays in place in the sentence.

Guides
------

* Block and Inline Layout in Normal Flow
* In Flow and Out of Flow
* Formatting Contexts Explained
* Flow Layout and Writing Modes
* Flow Layout and Overflow
Reference
---------

### Glossary Entries

* Block (CSS)


grid-row-start - CSS: Cascading Style Sheets

grid-row-start
==============

Baseline Widely available
-------------------------

This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2020.

* Learn more
* See full compatibility
* Report feedback
The **`grid-row-start`** CSS property specifies a grid item's start position within the grid row by contributing a line, a span, or nothing (automatic) to its grid placement, thereby specifying the inline-start edge of its grid area.

Try it
------

Syntax
------

```css
/\* Keyword value \*/
grid-row-start: auto;

/\* <custom-ident> values \*/
grid-row-start: somegridarea;

/\* <integer> + <custom-ident> values \*/
grid-row-start: 2;
grid-row-start: somegridarea 4;

/\* span + <integer> + <custom-ident> values \*/
grid-row-start: span 3;
grid-row-start: span somegridarea;
grid-row-start: 5 somegridarea span;

/\* Global values \*/
grid-row-start: inherit;
grid-row-start: initial;
grid-row-start: revert;
grid-row-start: revert-layer;
grid-row-start: unset;
```

This property is specified as a single `<grid-line>` value. A `<grid-line>` value can be specified as:

* either the `auto` keyword
* or a `<custom-ident>` value
* or an `<integer>` value
* or both `<custom-ident>` and `<integer>`, separated by a space
* or the keyword `span` together with either a `<custom-ident>` or an `<integer>` or both.
### Values

`auto`

Is a keyword indicating that the property contributes nothing to the grid item's placement, indicating auto-placement, an automatic span, or a default span of `1`.

`<custom-ident>`

If there is a named line with the name '<custom-ident>-start', it contributes the first such line to the grid item's placement.

**Note:** Named grid areas automatically generate implicit named lines of this form, so specifying `grid-row-start: foo;` will choose the start edge of that named grid area (unless another line named `foo-start` was explicitly specified before it).

Otherwise, this is treated as if the integer `1` had been specified along with the `<custom-ident>`.

`<integer> && <custom-ident>?`

Contributes the nth grid line to the grid item's placement. If a negative integer is given, it instead counts in reverse, starting from the end edge of the explicit grid.

If a name is given as a <custom-ident>, only lines with that name are counted. If not enough lines with that name exist, all implicit grid lines are assumed to have that name for the purpose of finding this position.

An `<integer>` value of `0` is invalid.

`span && [ <integer> || <custom-ident> ]`

Contributes a grid span to the grid item's placement; such that the row start edge of the grid item's grid area is n lines from the end edge.

If a name is given as a <custom-ident>, only lines with that name are counted. If not enough lines with that name exist, all implicit grid lines on the side of the explicit grid, corresponding to the search direction, are assumed to have that name for the purpose of counting this span.

If the <integer> is omitted, it defaults to `1`. Negative integers or 0 are invalid.

The `<custom-ident>` cannot take the `span` value.

Formal definition
-----------------

|  |  |
| --- | --- |
| Initial value | `auto` |
| Applies to | grid items and absolutely-positioned boxes whose containing block is a grid container |
| Inherited | no |
| Computed value | as specified |
| Animation type | discrete |

Formal syntax
-------------
```

grid-row-start =
  <grid-line>

<grid-line> =
  auto                                                |
  <custom-ident>                                      |
  [ [ <integer [-∞,-1]> | <integer [1,∞]> ] && <custom-ident>? ]  |
  [ span && [ <integer [1,∞]> || <custom-ident> ] ]

```

Examples
--------

### Setting row start for a grid item

#### HTML

```html
<div class="wrapper">
  <div class="box1">One</div>
  <div class="box2">Two</div>
  <div class="box3">Three</div>
  <div class="box4">Four</div>
  <div class="box5">Five</div>
</div>
```

#### CSS

```css
.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: 100px;
}

.box1 {
  grid-column-start: 1;
  grid-column-end: 4;
  grid-row-start: 1;
  grid-row-end: 3;
}

.box2 {
  grid-column-start: 1;
  grid-row-start: 3;
  grid-row-end: 5;
}
```

```
\* {
  box-sizing: border-box;
}

.wrapper {
  border: 2px solid #f76707;
  border-radius: 5px;
  background-color: #fff4e6;
}

.wrapper > div {
  border: 2px solid #ffa94d;
  border-radius: 5px;
  background-color: #ffd8a8;
  padding: 1em;
  color: #d9480f;
}

.nested {
  border: 2px solid #ffec99;
  border-radius: 5px;
  background-color: #fff9db;
  padding: 1em;
}
```

#### Result

Specifications
--------------

| Specification |
| --- |
| CSS Grid Layout Module Level 2 # line-placement |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Related CSS properties: `grid-row-end`, `grid-row`, `grid-column-start`, `grid-column-end`, `grid-column`
* Grid Layout Guide: *Line-based placement with CSS Grid*
* Video tutorial: *Line-based placement*


animation-composition - CSS: Cascading Style Sheets

animation-composition
=====================

The **`animation-composition`** CSS property specifies the composite operation to use when multiple animations affect the same property simultaneously.

Syntax
------

```css
/\* Single animation \*/
animation-composition: replace;
animation-composition: add;
animation-composition: accumulate;

/\* Multiple animations \*/
animation-composition: replace, add;
animation-composition: add, accumulate;
animation-composition: replace, add, accumulate;

/\* Global values \*/
animation-composition: inherit;
animation-composition: initial;
animation-composition: revert;
animation-composition: revert-layer;
animation-composition: unset;
```

**Note:** When you specify multiple comma-separated values on an `animation-*` property, they will be applied to the animations in the order in which the `animation-name`s appear. If the number of animations and compositions differ, the values listed in the `animation-composition` property will cycle from the first to the last `animation-name`, looping until all the animations have an assigned `animation-composition` value. For more information, see Setting multiple animation property values.

### Values

`replace`

The effect value overrides the underlying value of the property. This is the default value.

`add`

The effect value builds on the underlying value of the property. This operation produces an additive effect. For animation types where the addition operation is not commutative, the order of the operands is the underlying value followed by the effect value.

`accumulate`

The effect and underlying values are combined. For animation types where the addition operation is not commutative, the order of the operands is the underlying value followed by the effect value.

Description
-----------

Each property that is targeted by the @keyframes at-rule is associated with an effect stack. The value of the effect stack is calculated by combining the *underlying value* of a property in a CSS style rule with the *effect value* of that property in the keyframe. The `animation-composition` property helps to specify how to combine the underlying value with the effect value.

For example, in the CSS below, `blur(5px)` is the underlying value, and `blur(10px)` is the effect value. The `animation-composition` property specifies the operation to perform to produce the final effect value after compositing the effect of the underlying value and the effect value.

```css
.icon:hover {
  filter: blur(5px);
  animation: 3s infinite pulse;
  animation-composition: add;
}

@keyframes pulse {
  0% {
    filter: blur(10px);
  }
  100% {
    filter: blur(20px);
  }
}
```

Consider different values for the `animation-composition` property in the above example. The final effect value in each of those cases will be calculated as explained below:

* With `replace`, `blur(10px)` will replace `blur(5px)` in the `0%` keyframe. This is the default behavior of the property.
* With `add`, the composite effect value in the `0%` keyframe will be `blur(5px) blur(10px)`.
* With `accumulate`, the composite effect value in `0%` keyframe will be `blur(15px)`.

**Note:** A composite operation can also be specified in a keyframe. In that case, the specified composite operation is used for each property first within that keyframe and then on each property in the next keyframe.

Formal definition
-----------------

|  |  |
| --- | --- |
| Initial value | `replace` |
| Applies to | all elements |
| Inherited | no |
| Computed value | as specified |
| Animation type | Not animatable |

Formal syntax
-------------
```

animation-composition =
  <single-animation-composition>#

<single-animation-composition> =
  replace     |
  add         |
  accumulate

```

Examples
--------

### Understanding the animation-composition values

The example below shows the effect of different `animation-composition` values side-by-side.

#### HTML

```html
<div class="container">
  replace
  <div id="replace" class="target"></div>
</div>
<div class="container">
  add
  <div id="add" class="target"></div>
</div>
<div class="container">
  accumulate
  <div id="accumulate" class="target"></div>
</div>
```

#### CSS

Here the underlying value is `translateX(50px) rotate(45deg)`.
```

.container {
  width: 230px;
  height: 200px;
  background: cyan;
  display: inline-block;
  text-align: center;
}

.target {
  width: 20px;
  height: 50px;
  background: green;
  border-radius: 10px;
  margin: 20px 0;
}
```

```css
@keyframes slide {
  20%,
 40% {
    transform: translateX(100px);
    background: yellow;
  }
  80%,
 100% {
    transform: translateX(150px);
    background: orange;
  }
}

.target {
  transform: translateX(30px) rotate(45deg);
  animation: slide 5s linear infinite;
}
.target:hover {
  animation-play-state: paused;
}
#replace {
  animation-composition: replace;
}
#add {
  animation-composition: add;
}
#accumulate {
  animation-composition: accumulate;
}
```

#### Result

* With `replace`, the final effect value for the `transform` property in the `0%, 20%` keyframe is `translateX(100px)` (completely replacing the underlying value `translateX(30px) rotate(45deg)`). In this case, the element rotates from 45deg to 0deg as it animates from the default value set on the element itself to the non-rotated value set at the 0% mark. This is the default behavior.
* With `add`, the final effect value for the `transform` property in the `0%, 20%` keyframe is `translateX(30px) rotate(45deg)` followed by `translateX(100px)`. So the element is moved `30px` to the right, rotated `45deg`, then translated `100px` more along the redirected X axis.
* With `accumulate`, the final effect value in the `0%, 20%` keyframe is `translateX(130px) rotate(45deg)`. This means that the two X-axis translation values of `30px` and `100px` are combined or "accumulated".
Specifications
--------------

| Specification |
| --- |
| CSS Animations Level 2 # animation-composition |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Using CSS animations
* Composite property of KeyFrameEffect
* Other related animation properties: `animation`, `animation-delay`, `animation-direction`, `animation-duration`, `animation-fill-mode`, `animation-iteration-count`, `animation-name`, `animation-play-state`, `animation-timeline`, `animation-timing-function`


box-pack - CSS: Cascading Style Sheets

box-pack
========

**Non-standard:** This feature is non-standard and is not on a standards track. Do not use it on production sites facing the Web: it will not work for every user. There may also be large incompatibilities between implementations and the behavior may change in the future.

**Deprecated:** This feature is no longer recommended. Though some browsers might still support it, it may have already been removed from the relevant web standards, may be in the process of being dropped, or may only be kept for compatibility purposes. Avoid using it, and update existing code if possible; see the compatibility table at the bottom of this page to guide your decision. Be aware that this feature may cease to work at any time.

**Warning:** This is a property of the original CSS Flexible Box Layout Module draft, and has been replaced by a newer standard. See flexbox for information about the current standard.

The **`-moz-box-pack`** and **`-webkit-box-pack`** CSS properties specify how a `-moz-box` or `-webkit-box` packs its contents in the direction of its layout. The effect of this is only visible if there is extra space in the box.

The direction of layout depends on the element's orientation: horizontal or vertical.

Syntax
------

```css
/\* Keyword values \*/
box-pack: start;
box-pack: center;
box-pack: end;
box-pack: justify;

/\* Global values \*/
box-pack: inherit;
box-pack: initial;
box-pack: unset;
```

The `box-pack` property is specified as one of the keyword values listed below.

### Values

`start`

The box packs contents at the start, leaving any extra space at the end.

`center`

The box packs contents in the center, dividing any extra space equally between the start and the end.

`end`

The box packs contents at the end, leaving any extra space at the start.

`justify`

The space is divided evenly in-between each child, with none of the extra space placed before the first child or after the last child. If there is only one child, treat the value as if it were `start`.

Notes
-----

The edge of the box designated the *start* for packing purposes depends on the box's orientation and direction:

* For horizontal elements, the *start* is the top edge.
* For vertical elements, the *start* is the left edge.

|  | **Normal** | **Reverse** |
| --- | --- | --- |
| **Horizontal** | left | right |
| **Vertical** | top | bottom |

The edge opposite to the start is designated the *end*.

If the packing is set using the element's `pack` attribute, then the style is ignored.

Formal definition
-----------------

|  |  |
| --- | --- |
| Initial value | `start` |
| Applies to | elements with a CSS `display` value of `-moz-box`, `-moz-inline-box`, `-webkit-box` or `-webkit-inline-box` |
| Inherited | no |
| Computed value | as specified |
| Animation type | discrete |

Formal syntax
-------------
```

box-pack =
  start | center | end | justify
```

Examples
--------

### Examples of box-pack

```css
div.example {
  border-style: solid;

  display: -moz-box; /\* Mozilla \*/
  display: -webkit-box; /\* WebKit \*/

  /\* Make this box taller than the children,
 so there is room for the box-pack \*/
  height: 300px;
  /\* Make this box wide enough to show the contents
 are centered horizontally \*/
  width: 300px;

  /\* Children should be oriented vertically \*/
  -moz-box-orient: vertical; /\* Mozilla \*/
  -webkit-box-orient: vertical; /\* WebKit \*/

  /\* Align children to the horizontal center of this box \*/
  -moz-box-align: center; /\* Mozilla \*/
  -webkit-box-align: center; /\* WebKit \*/

  /\* Pack children to the bottom of this box \*/
  -moz-box-pack: end; /\* Mozilla \*/
  -webkit-box-pack: end; /\* WebKit \*/
}

div.example p {
  /\* Make children narrower than their parent,
 so there is room for the box-align \*/
  width: 200px;
}
```

```html
<div class="example">
  <p>I will be second from the bottom of div.example, centered horizontally.</p>
  <p>I will be on the bottom of div.example, centered horizontally.</p>
</div>
```

Specifications
--------------

Not part of any standard.

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `box-orient`
* `box-direction`
* `box-align`


margin-block-start - CSS: Cascading Style Sheets

margin-block-start
==================

The **`margin-block-start`** CSS property defines the logical block start margin of an element, which maps to a physical margin depending on the element's writing mode, directionality, and text orientation.

Try it
------

Syntax
------

```css
/\* <length> values \*/
margin-block-start: 10px; /\* An absolute length \*/
margin-block-start: 1em; /\* relative to the text size \*/
margin-block-start: 5%; /\* relative to the nearest block container's width \*/

/\* Keyword values \*/
margin-block-start: auto;

/\* Global values \*/
margin-block-start: inherit;
margin-block-start: initial;
margin-block-start: revert;
margin-block-start: revert-layer;
margin-block-start: unset;
```

It corresponds to the `margin-top`, `margin-right`, `margin-bottom`, or `margin-left` property depending on the values defined for `writing-mode`, `direction`, and `text-orientation`.

It relates to `margin-block-end`, `margin-inline-start`, and `margin-inline-end`, which define the other margins of the element.

### Values

The `margin-block-start` property takes the same values as the `margin-left` property.

Formal definition
-----------------

|  |  |
| --- | --- |
| Initial value | `0` |
| Applies to | same as `margin` |
| Inherited | no |
| Percentages | depends on layout model |
| Computed value | if specified as a length, the corresponding absolute length; if specified as a percentage, the specified value; otherwise, `auto` |
| Animation type | a length |

Formal syntax
-------------
```

margin-block-start =
  <'margin-top'>

```

Examples
--------

### Setting block start margin

#### HTML

```html
<div>
  <p class="exampleText">Example text</p>
</div>
```

#### CSS

```css
div {
  background-color: yellow;
  width: 120px;
  height: 120px;
}

.exampleText {
  writing-mode: vertical-lr;
  margin-block-start: 20px;
  background-color: #c8c800;
}
```

#### Result

Specifications
--------------

| Specification |
| --- |
| CSS Logical Properties and Values Level 1 # margin-properties |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* CSS Logical Properties and Values
* The mapped physical properties: `margin-top`, `margin-right`, `margin-bottom`, and `margin-left`
* `writing-mode`, `direction`, `text-orientation`


grid-auto-rows - CSS: Cascading Style Sheets

grid-auto-rows
==============

Baseline Widely available
-------------------------

This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2020.

* Learn more
* See full compatibility
* Report feedback
The **`grid-auto-rows`** CSS property specifies the size of an implicitly-created grid row track or pattern of tracks.

Try it
------

If a grid item is positioned into a row that is not explicitly sized by `grid-template-rows`, implicit grid tracks are created to hold it. This can happen either by explicitly positioning into a row that is out of range, or by the auto-placement algorithm creating additional rows.

Syntax
------

```css
/\* Keyword values \*/
grid-auto-rows: min-content;
grid-auto-rows: max-content;
grid-auto-rows: auto;

/\* <length> values \*/
grid-auto-rows: 100px;
grid-auto-rows: 20cm;
grid-auto-rows: 50vmax;

/\* <percentage> values \*/
grid-auto-rows: 10%;
grid-auto-rows: 33.3%;

/\* <flex> values \*/
grid-auto-rows: 0.5fr;
grid-auto-rows: 3fr;

/\* minmax() values \*/
grid-auto-rows: minmax(100px, auto);
grid-auto-rows: minmax(max-content, 2fr);
grid-auto-rows: minmax(20%, 80vmax);

/\* fit-content() values \*/
grid-auto-rows: fit-content(400px);
grid-auto-rows: fit-content(5cm);
grid-auto-rows: fit-content(20%);

/\* multiple track-size values \*/
grid-auto-rows: min-content max-content auto;
grid-auto-rows: 100px 150px 390px;
grid-auto-rows: 10% 33.3%;
grid-auto-rows: 0.5fr 3fr 1fr;
grid-auto-rows: minmax(100px, auto) minmax(max-content, 2fr) minmax(20%, 80vmax);
grid-auto-rows: 100px minmax(100px, auto) 10% 0.5fr fit-content(400px);

/\* Global values \*/
grid-auto-rows: inherit;
grid-auto-rows: initial;
grid-auto-rows: revert;
grid-auto-rows: revert-layer;
grid-auto-rows: unset;
```

### Values

`<length>`

Is a non-negative length.

`<percentage>`

Is a non-negative `<percentage>` value relative to the block size of the grid container. If the block size of the grid container is indefinite, the percentage value is treated like `auto`.

`<flex>`

Is a non-negative dimension with the unit `fr` specifying the track's flex factor. Each `<flex>`-sized track takes a share of the remaining space in proportion to its flex factor.

When appearing outside a `minmax()` notation, it implies an automatic minimum (i.e. `minmax(auto, <flex>)`).

`max-content`

Is a keyword representing the largest maximal content contribution of the grid items occupying the grid track.

`min-content`

Is a keyword representing the largest minimal content contribution of the grid items occupying the grid track.

`minmax(min, max)`

Is a functional notation that defines a size range greater than or equal to *min* and less than or equal to *max*. If *max* is smaller than *min*, then *max* is ignored and the function is treated as *min*. As a maximum, a `<flex>` value sets the track's flex factor. As a minimum, it is treated as zero (or minimal content, if the grid container is sized under a minimal content constraint).

`fit-content( [ <length> | <percentage> ] )`

Represents the formula `min(max-content, max(auto, argument))`, which is calculated similar to `auto` (i.e. `minmax(auto, max-content)`), except that the track size is clamped at *argument* if it is greater than the `auto` minimum.

`auto`

As a maximum represents the largest `max-content` size of the items in that track.

As a minimum represents the largest minimum size of items in that track (specified by the `min-width`/`min-height` of the items). This is often, though not always, the `min-content` size.

If used outside of `minmax()` notation, `auto` represents the range between the minimum and maximum described above. This behaves similarly to `minmax(min-content,max-content)` in most cases.

**Note:** `auto` track sizes (and only `auto` track sizes) can be stretched by the `align-content` and `justify-content` properties. Therefore by default, an `auto` sized track will take up any remaining space in the grid container.

Formal definition
-----------------

|  |  |
| --- | --- |
| Initial value | `auto` |
| Applies to | grid containers |
| Inherited | no |
| Percentages | refer to corresponding dimension of the content area |
| Computed value | the percentage as specified or the absolute length |
| Animation type | by computed value type |

Formal syntax
-------------
```

grid-auto-rows =
  <track-size>+

<track-size> =
  <track-breadth>                                   |
  minmax( <inflexible-breadth> , <track-breadth> )  |
  fit-content( <length-percentage [0,∞]> )

<track-breadth> =
  <length-percentage [0,∞]>  |
  <flex [0,∞]>               |
  min-content                |
  max-content                |
  auto

<inflexible-breadth> =
  <length-percentage [0,∞]>  |
  min-content                |
  max-content                |
  auto

<length-percentage> =
  <length>      |
  <percentage>

```

Examples
--------

### Setting grid row size

#### HTML

```html
<div id="grid">
  <div id="item1"></div>
  <div id="item2"></div>
  <div id="item3"></div>
</div>
```

#### CSS

```css
#grid {
  width: 200px;
  display: grid;
  grid-template-areas: "a a";
  gap: 10px;
  grid-auto-rows: 100px;
}

#grid > div {
  background-color: lime;
}
```

#### Result

Specifications
--------------

| Specification |
| --- |
| CSS Grid Layout Module Level 2 # auto-tracks |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Related CSS properties: `grid-auto-columns`, `grid-auto-flow`, `grid`
* Grid Layout Guide: *Auto-placement in grid layout - sizing rows in the implicit grid*
* Video tutorial: *Introducing Grid auto-placement and order*


::part() - CSS: Cascading Style Sheets

::part()
========

Limited availability
--------------------

This feature is not Baseline because it does not work in some of the most widely-used browsers.

* Learn more
* See full compatibility
* Report feedback
The **`::part`** CSS pseudo-element represents any element within a shadow tree that has a matching `part` attribute.

```css
custom-element::part(foo) {
  /\* Styles to apply to the `foo` part \*/
}
```

Syntax
------

```css
::part(<ident>+) {
  /\* ... \*/
}
```

Examples
--------

### HTML

```html
<template id="tabbed-custom-element">
  <style>
 \*,
 ::before,
 ::after {
 box-sizing: border-box;
 padding: 1rem;
 }
 :host {
 display: flex;
 }
 </style>
  <div part="tab active">Tab 1</div>
  <div part="tab">Tab 2</div>
  <div part="tab">Tab 3</div>
</template>

<tabbed-custom-element></tabbed-custom-element>
```

### CSS

```css
tabbed-custom-element::part(tab) {
  color: #0c0dcc;
  border-bottom: transparent solid 2px;
}

tabbed-custom-element::part(tab):hover {
  background-color: #0c0d19;
  color: #ffffff;
  border-color: #0c0d33;
}

tabbed-custom-element::part(tab):hover:active {
  background-color: #0c0d33;
  color: #ffffff;
}

tabbed-custom-element::part(tab):focus {
  box-shadow:
    0 0 0 1px #0a84ff inset,
    0 0 0 1px #0a84ff,
    0 0 0 4px rgb(10 132 255 / 30%);
}

tabbed-custom-element::part(active) {
  color: #0060df;
  border-color: #0a84ff !important;
}
```

### JavaScript

```js
let template = document.querySelector("#tabbed-custom-element");
globalThis.customElements.define(
  template.id,
  class extends HTMLElement {
    constructor() {
      super().attachShadow({ mode: "open" }).append(template.content);
    }
  },
);
```

### Result

Specifications
--------------

| Specification |
| --- |
| CSS Shadow Parts # part |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* The `part` attribute - Used to define parts which can be selected by the `::part()` selector
* The `exportparts` attribute - Used to transitively export shadow parts from a nested shadow tree into a containing light tree.
* CSS shadow parts module


:where() - CSS: Cascading Style Sheets

:where()
========

Baseline Widely available
-------------------------

This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2021.

* Learn more
* See full compatibility
* Report feedback
The **`:where()`** CSS pseudo-class function takes a selector list as its argument, and selects any element that can be selected by one of the selectors in that list.

The difference between `:where()` and `:is()` is that `:where()` always has 0 specificity, whereas `:is()` takes on the specificity of the most specific selector in its arguments.

Try it
------

### Forgiving Selector Parsing

The specification defines `:is()` and `:where()` as accepting a forgiving selector list.

In CSS when using a selector list, if any of the selectors are invalid then the whole list is deemed invalid. When using `:is()` or `:where()` instead of the whole list of selectors being deemed invalid if one fails to parse, the incorrect or unsupported selector will be ignored and the others used.

```css
:where(:valid, :unsupported) {
  /\* … \*/
}
```

Will still parse correctly and match `:valid` even in browsers which don't support `:unsupported`, whereas:

```css
:valid,
:unsupported {
  /\* … \*/
}
```

Will be ignored in browsers which don't support `:unsupported` even if they support `:valid`.

Examples
--------

### Comparing :where() and :is()

This example shows how `:where()` works, and also illustrates the difference between `:where()` and `:is()`.

Take the following HTML:

```html
<article>
  <h2>:is()-styled links</h2>
  <section class="is-styling">
    <p>
      Here is my main content. This
      <a href="https://mozilla.org">contains a link</a>.
    </p>
  </section>

  <aside class="is-styling">
    <p>
      Here is my aside content. This
      <a href="https://developer.mozilla.org">also contains a link</a>.
    </p>
  </aside>

  <footer class="is-styling">
    <p>
      This is my footer, also containing
      <a href="https://github.com/mdn">a link</a>.
    </p>
  </footer>
</article>

<article>
  <h2>:where()-styled links</h2>
  <section class="where-styling">
    <p>
      Here is my main content. This
      <a href="https://mozilla.org">contains a link</a>.
    </p>
  </section>

  <aside class="where-styling">
    <p>
      Here is my aside content. This
      <a href="https://developer.mozilla.org">also contains a link</a>.
    </p>
  </aside>

  <footer class="where-styling">
    <p>
      This is my footer, also containing
      <a href="https://github.com/mdn">a link</a>.
    </p>
  </footer>
</article>
```

In this somewhat-contrived example, we have two articles that each contain a section, an aside, and a footer. They differ by the classes used to mark the child elements.

To make selecting the links inside them simpler, but still distinct, we *could* use `:is()` or `:where()`, in the following manner:

```css
html {
  font-family: sans-serif;
  font-size: 150%;
}

:is(section.is-styling, aside.is-styling, footer.is-styling) a {
  color: red;
}

:where(section.where-styling, aside.where-styling, footer.where-styling) a {
  color: orange;
}
```

However, what if we later want to override the color of links in the footers using a simple selector?

```css
footer a {
  color: blue;
}
```

This won't work for the red links, because the selectors inside `:is()` count towards the specificity of the overall selector, and class selectors have a higher specificity than element selectors.

However, selectors inside `:where()` have specificity 0, so the orange footer link will be overridden by our simple selector.

**Note:** You can also find this example on GitHub; see is-where.

Syntax
------

```css
:where(<complex-selector-list>) {
  /\* ... \*/
}
```

Specifications
--------------

| Specification |
| --- |
| Selectors Level 4 # zero-matches |

Browser compatibility
---------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `:is()`
* Selector list
* Web components