Using CSS transitions - CSS: Cascading Style Sheets

Using CSS transitions
=====================

**CSS transitions** provide a way to control animation speed when changing CSS properties. Instead of having property changes take effect immediately, you can cause the changes in a property to take place over a period of time. For example, if you change the color of an element from white to black, usually the change is instantaneous. With CSS transitions enabled, changes occur at time intervals that follow an acceleration curve, all of which can be customized.

Animations that involve transitioning between two states are often called *implicit transitions* as the states in between the start and final states are implicitly defined by the browser.

![A CSS transition tells the browser to draw the intermediate states between the initial and final states, showing the user a smooth transitions.](/en-US/docs/Web/CSS/CSS_transitions/Using_CSS_transitions/transitionsprinciple.png)

CSS transitions let you decide which properties to animate (by *listing them explicitly*), when the animation will start (by setting a *delay*), how long the transition will last (by setting a *duration*), and how the transition will run (by defining an *easing function*, e.g., linearly or quick at the beginning, slow at the end).

Which CSS properties can be transitioned?
-----------------------------------------

The Web author can define which property has to be animated and in which way. This allows the creation of complex transitions. However, some properties are not animatable as it doesn't make sense to animate them.

**Note:** The `auto` value is often a very complex case. The specification recommends not animating from and to `auto`. Some user agents, like those based on Gecko, implement this requirement and others, like those based on WebKit, are less strict. Using animations with `auto` may lead to unpredictable results, depending on the browser and its version, and should be avoided.

Defining transitions
--------------------

CSS Transitions are controlled using the shorthand `transition` property. This is the best way to configure transitions, as it makes it easier to avoid out of sync parameters, which can be very frustrating to have to spend lots of time debugging in CSS.

You can control the individual components of the transition with the following sub-properties:

`transition-property`

Specifies the name or names of the CSS properties to which transitions should be applied. Only properties listed here are animated during transitions; changes to all other properties occur instantaneously as usual.

`transition-duration`

Specifies the duration over which transitions should occur. You can specify a single duration that applies to all properties during the transition, or multiple values to allow each property to transition over a different period of time.

`transition-timing-function`

Specifies a function to define how intermediate values for properties are computed. *Easing functions* determine how intermediate values of the transition are calculated. Most easing functions can be specified by providing the graph of the corresponding function, as defined by four points defining a cubic bezier. You can also choose easing from Easing functions cheat sheet.

`transition-delay`

Defines how long to wait between the time a property is changed and the transition actually begins.

The `transition` shorthand CSS syntax is written as follows:

```css
div {
  transition: <property> <duration> <timing-function> <delay>;
}
```

Examples
--------

### Basic example

This example performs a four-second font size transition with a two-second delay between the time the user mouses over the element and the beginning of the animation effect:

```css
#delay {
  font-size: 14px;
  transition-property: font-size;
  transition-duration: 4s;
  transition-delay: 2s;
}

#delay:hover {
  font-size: 36px;
}
```

### Multiple animated properties example
```

<body>
  <p>
    The box below combines transitions for: width, height, background-color,
    rotate. Hover over the box to see these properties animated.
  </p>
  <div class="box">Sample</div>
</body>
```

#### CSS

```css
.box {
  border-style: solid;
  border-width: 1px;
  display: block;
  width: 100px;
  height: 100px;
  background-color: #0000ff;
  transition:
    width 2s,
    height 2s,
    background-color 2s,
    rotate 2s;
}

.box:hover {
  background-color: #ffcccc;
  width: 200px;
  height: 200px;
  rotate: 180deg;
}
```

### When property value lists are of different lengths

If any property's list of values is shorter than the others, its values are repeated to make them match. For example:

```css
div {
  transition-property: opacity, left, top, height;
  transition-duration: 3s, 5s;
}
```

This is treated as if it were:

```css
div {
  transition-property: opacity, left, top, height;
  transition-duration: 3s, 5s, 3s, 5s;
}
```

Similarly, if any property's value list is longer than that for `transition-property`, it's truncated, so if you have the following CSS:

```css
div {
  transition-property: opacity, left;
  transition-duration: 3s, 5s, 2s, 1s;
}
```

This gets interpreted as:

```css
div {
  transition-property: opacity, left;
  transition-duration: 3s, 5s;
}
```

### Using transitions when highlighting menus

A common use of CSS is to highlight items in a menu as the user hovers the mouse cursor over them. It's easy to use transitions to make the effect even more attractive.

First, we set up the menu using HTML:

```html
<nav>
  <a href="#">Home</a>
  <a href="#">About</a>
  <a href="#">Contact Us</a>
  <a href="#">Links</a>
</nav>
```

Then we build the CSS to implement the look and feel of our menu:

```css
nav {
  display: flex;
  gap: 0.5rem;
}

a {
  flex: 1;
  background-color: #333;
  color: #fff;
  border: 1px solid;
  padding: 0.5rem;
  text-align: center;
  text-decoration: none;
  transition: all 0.5s ease-out;
}

a:hover,
a:focus {
  background-color: #fff;
  color: #333;
}
```

This CSS establishes the look of the menu, with the background and text colors both changing when the element is in its `:hover` and `:focus` states:

### Transitioning display and content-visibility

This example demonstrates how `display` and `content-visibility` can be transitioned. This behavior is useful for creating entry/exit animations where you want to for example remove a container from the DOM with `display: none`, but have it fade out with `opacity` rather than disappearing immediately.

Supporting browsers transition `display` and `content-visibility` with a variation on the discrete animation type. This generally means that properties will flip between two values 50% through animating between the two.

There is an exception, however, which is when animating to/from `display: none` or `content-visibility: hidden`. In this case, the browser will flip between the two values so that the transitioned content is shown for the entire animation duration.

So for example:

* When animating `display` from `none` to `block` (or another visible `display` value), the value will flip to `block` at `0%` of the animation duration so it is visible throughout.
* When animating `display` from `block` (or another visible `display` value) to `none`, the value will flip to `none` at `100%` of the animation duration so it is visible throughout.

When transitioning these properties `transition-behavior: allow-discrete` needs to be set on the transitions. This effectively enables `display`/`content-visibility` transitions.

When transitioning `display`, `@starting-style` is needed to provide a set of starting values for properties set on an element that you want to transition from when the element receives its first style update. This is needed to avoid unexpected behavior. By default, CSS transitions are not triggered on elements' first style updates when they first appear in the DOM, which includes when `display` changes from `none` to another state. `content-visibility` animations do not need starting values specified in a `@starting-style` block. This is because `content-visibility` doesn't hide an element from the DOM like `display` does: it just skips rendering the element's content.

#### HTML

The HTML contains two `<p>` elements with a `<div>` in between that we will animate from `display` `none` to `block`.

```html
<p>
  Click anywhere on the screen or press any key to toggle the
  <code><div></code> between hidden and showing.
</p>

<div>
  This is a <code><div></code> element that transitions between
  <code>display: none; opacity: 0</code> and
  <code>display: block; opacity: 1</code>. Neat, huh?
</div>

<p>
  This is another paragraph to show that <code>display: none; </code> is being
  applied and removed on the above <code><div> </code>. If only its
  <code>opacity</code> was being changed, it would always take up the space in
  the DOM.
</p>
```

#### CSS

```css
html {
  height: 100vh;
}

div {
  font-size: 1.6rem;
  padding: 20px;
  border: 3px solid red;
  border-radius: 20px;
  width: 480px;

  display: none;
  opacity: 0;
  transition:
    opacity 1s,
    display 1s allow-discrete;
  /\* Equivalent to
 transition: all 1s allow-discrete; \*/
}

.showing {
  opacity: 1;
  display: block;
}

@starting-style {
  .showing {
    opacity: 0;
  }
}
```

Note the `@starting-style` block used to specify the starting style for the transition, and the inclusion of the `display` property in the transitions list, with `allow-discrete` set on it.

#### JavaScript

Finally, we include a bit of JavaScript to set up event listeners to trigger the transition (via the `showing` class).

```js
const divElem = document.querySelector("div");
const htmlElem = document.querySelector(":root");

htmlElem.addEventListener("click", showHide);
document.addEventListener("keydown", showHide);

function showHide() {
  divElem.classList.toggle("showing");
}
```

#### Result

The code renders as follows:

JavaScript examples
-------------------

**Note:** Care should be taken when using a transition immediately after:

* adding the element to the DOM using `.appendChild()`
* removing an element's `display: none;` property.

This is treated as if the initial state had never occurred and the element was always in its final state. The easy way to overcome this limitation is to apply a `setTimeout()` of a handful of milliseconds before changing the CSS property you intend to transition to.

### Using transitions to make JavaScript functionality smooth

Transitions are a great tool to make things look much smoother without having to do anything to your JavaScript functionality. Take the following example.

```html
<p>Click anywhere to move the ball</p>
<div id="foo" class="ball"></div>
```

Using JavaScript you can make the effect of moving the ball to a certain position happen:

```js
const f = document.getElementById("foo");
document.addEventListener(
  "click",
  (ev) => {
    f.style.transform = `translateY(${ev.clientY - 25}px)`;
    f.style.transform += `translateX(${ev.clientX - 25}px)`;
  },
  false,
);
```

With CSS you can make it smooth without any extra effort. Add a transition to the element and any change will happen smoothly:

```css
.ball {
  border-radius: 25px;
  width: 50px;
  height: 50px;
  background: #c00;
  position: absolute;
  top: 0;
  left: 0;
  transition: transform 1s;
}
```

### Detecting the start and completion of a transition

You can use the `transitionend` event to detect that an animation has finished running. This is a `TransitionEvent` object, which has two added properties beyond a typical `Event` object:

`propertyName`

A string indicating the name of the CSS property whose transition completed.

`elapsedTime`

A float indicating the number of seconds the transition had been running at the time the event fired. This value isn't affected by the value of `transition-delay`.

As usual, you can use the `addEventListener()` method to monitor for this event:

```js
el.addEventListener("transitionend", updateTransition, true);
```

You detect the beginning of a transition using `transitionrun` (fires before any delay) and `transitionstart` (fires after any delay), in the same kind of fashion:

```js
el.addEventListener("transitionrun", signalStart, true);
el.addEventListener("transitionstart", signalStart, true);
```

**Note:** The `transitionend` event doesn't fire if the transition is aborted before the transition is completed because either the element is made `display``: none` or the animating property's value is changed.

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

| Specification |
| --- |
| CSS Transitions  |

See also
--------

* The `TransitionEvent` interface and the `transitionend` event
* Using CSS animations


paint() - CSS: Cascading Style Sheets

paint()
=======

The **`paint()`** CSS function defines an `<image>` value generated with a PaintWorklet.

Syntax
------

```css
paint(workletName, ...parameters)
```

where:

*workletName*

The name of the registered worklet.

*parameters*

Optional additional parameters to pass to the paintWorklet

Examples
--------

### Basic usage example

In JavaScript, we register the paint worklet:

```js
CSS.paintWorklet.addModule("boxbg.js");
```

...then, in the CSS, we define the `background-image` as a `paint()` type with the worklet name, `boxbg`, along with any variables (ex. `--boxColor` and `--widthSubtractor`) the worklet will use:

```css
li {
  background-image: paint(boxbg);
  --boxColor: hsl(55 90% 60% / 100%);
}
li:nth-of-type(3n) {
  --boxColor: hsl(155 90% 60% / 100%);
  --widthSubtractor: 20;
}
li:nth-of-type(3n + 1) {
  --boxColor: hsl(255 90% 60% / 100%);
  --widthSubtractor: 40;
}
```

The result will be the following:

### With additional parameters

You can pass additional arguments via the CSS paint() function. In this example, we passed two arguments: whether the background-image on a group of list items is filled or just has a stroke outline, and the width of that outline:
```

<ul>
  <li>item 1</li>
  <li>item 2</li>
  <li>item 3</li>
  <li>item 4</li>
  <li>item 5</li>
  <li>item 6</li>
  <li>item 7</li>
  <li>item 8</li>
  <li>item 9</li>
  <li>item 10</li>
  <li>item 11</li>
  <li>item 12</li>
  <li>item 13</li>
  <li>item 14</li>
  <li>item 15</li>
  <li>item 16</li>
  <li>item 17</li>
  <li>item 18</li>
  <li>item 19</li>
  <li>item 20</li>
</ul>
```

```
CSS.paintWorklet.addModule(
  "https://mdn.github.io/houdini-examples/cssPaint/intro/worklets/hilite.js",
);
```

```css
li {
  --boxColor: hsl(55 90% 60% / 100%);
  background-image: paint(hollowHighlights, stroke, 2px);
}

li:nth-of-type(3n) {
  --boxColor: hsl(155 90% 60% / 100%);
  background-image: paint(hollowHighlights, filled, 3px);
}

li:nth-of-type(3n + 1) {
  --boxColor: hsl(255 90% 60% / 100%);
  background-image: paint(hollowHighlights, stroke, 1px);
}
```

We've included a custom property in the selector block defining a boxColor. Custom properties are accessible to the PaintWorklet.

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

| Specification |
| --- |
| CSS Painting API Level 1 # paint-notation |

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

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

See also
--------

* `PaintWorkletGlobalScope`
* CSS Painting API
* Using the CSS Painting API
* `<image>`
* Canvas API


image() - CSS: Cascading Style Sheets

image()
=======

The **`image()`** CSS function defines an `<image>` in a similar fashion to the `url()` function, but with added functionality including specifying the image's directionality, displaying just a part of that image defined by a media fragment, and specifying a solid color as a fallback in case none of the specified images are able to be rendered.

**Note:** The CSS `image()` function should not confused with `Image()`, the `HTMLImageElement` constructor.

Syntax
------
```

<image()> =
  image( <image-tags>? [ <image-src>? , <color>? ]! )

<image-tags> =
  ltr  |
  rtl

<image-src> =
  <url>     |
  <string>

<url> =
  <url()>  |
  <src()>

<url()> =
  url( <string> <url-modifier>\* )  |
  <url-token>

<src()> =
  src( <string> <url-modifier>\* )

```

where:

`image-tags` Optional

The directionality of the image, either `ltr` for left-to-right or `rtl` for right-to-left.

`image-src` Optional

Zero or more `url()`s or `<string>`s specifying the image sources, with optional image fragment identifiers.

`color` Optional

A color, specifying a solid background color to use as a fallback if no `image-src` is found, supported, or declared.

### Bi-directional awareness

The first, optional parameter of the `image()` notation is the directionality of the image. If included, and the image is used on an element with opposite directionality, the image will be flipped horizontally in horizontal writing modes. If the directionality is omitted, the image won't be flipped if the language direction is changed.

### Image fragments

One key difference between `url()` and `image()` is the ability to add a media fragment identifier — a starting point along the x and y axis, along with a width and height — onto the image source to display only a section of the source image. The section of the image defined in the parameter becomes a standalone image. The syntax looks like so:

```css
background-image: image("myimage.webp#xywh=0,20,40,60");
```

The background image of the element will be the portion of the image *myImage.webp* that starts at the coordinate 0px, 20px (the top left-hand corner) and is 40px wide and 60px tall.

The `#xywh=#,#,#,#` media fragment syntax takes four comma separated numeric values. The first two represent the X and Y coordinates for the starting point of the box that will be created. The third value is the width of the box, and the last value is the height. By default, these are pixel values. The spacial dimension definition in the media specification indicates that percentages will be supported as well:

```css
xywh=160,120,320,240        /\* results in a 320x240 image at x=160 and y=120 \*/
xywh=pixel:160,120,320,240  /\* results in a 320x240 image at x=160 and y=120 \*/
xywh=percent:25,25,50,50    /\* results in a 50%x50% image at x=25% and y=25% \*/
```

The image fragments can be used in `url()` notation as well. The `#xywh=#,#,#,#` media fragment syntax is 'backwards compatible' in that a media fragment will be ignored if not understood, and won't break the source call when used with `url()`. If the browser doesn't understand the media fragments notation, it ignores the fragment, displaying the entire image.

Browsers that understand `image()` also understand the fragment notation. Therefore, if the fragment is not understood within `image()`, the image will be considered invalid.

### Color fallback

If a color is specified in `image()` along with your image sources, it acts as a fallback if the images are invalid and do not appear. In such cases, the `image()` function renders as if no image were included, generating a solid-color image. As a use case, consider a dark image being used as a background for some white text. A dark background color may be needed for foreground text to be legible, if the image does not render.

Omitting image sources while including a color is valid and creates a color swatch. Unlike declaring a `background-color`, which is placed under or behind all the background images, this can be used to put (generally semi-transparent) colors over other images.

The size of the color swatch can be set with the `background-size` property. This is different from the `background-color`, which sets a color to cover the entire element. Both `image(color)` and `background-color` placements are impacted by the `background-clip` and `background-origin` properties.

Accessibility concerns
----------------------

Browsers do not provide any special information on background images to assistive technology. This is important primarily for screen readers, as a screen reader will not announce its presence and therefore convey nothing to its users. If the image contains information critical to understanding the page's overall purpose, it is better to describe it semantically in the document.

* MDN Understanding WCAG, Guideline 1.1 explanations
* Understanding Success Criterion 1.1.1 | W3C Understanding WCAG 2.0

This feature can help improve accessibility by providing a fallback color when an image fails to load. While this can and should be done by including a background-color on every background image, the CSS `image()` function allows adding allows only including background colors should an image fail to load, which means you can add a fall back color should a transparent PNG/GIF/WebP not load.

Examples
--------

### Directionally-sensitive images

```html
<ul>
  <li dir="ltr">Bullet is a right facing arrow on the left</li>
  <li dir="rtl">Bullet is the same arrow, flipped to point left.</li>
</ul>
```

```css
ul {
  list-style-image: image(ltr "rightarrow.png");
}
```

In the left-to-right list items — those with `dir="ltr"` set on the element itself or inheriting the directionality from an ancestor or default value for the page — the image will be used as-is. List items with `dir="rtl"` set on the `<li>` or inheriting the right-to-left directionality from an ancestor, such as documents set to Arabic or Hebrew, will have the bullet display on the right, horizontally flipped, as if `transform: scaleX(-1)` had been set. The text will also be displayed left-to-right.

### Displaying a section of the background image

```html
<div class="box">Hover over me. What cursor do you see?</div>
```

```css
.box:hover {
  cursor: image("sprite.png#xywh=32,64,16,16");
}
```

When the user hovers over the box, the cursor will change to display the 16x16 px section of the sprite image, starting at x=32 and y=64.

### Putting color on top of a background image
```

.quarterlogo {
  height: 200px;
  width: 200px;
  border: 1px solid;
}
```

```css
.quarterlogo {
  background-image: image(rgb(0 0 0 / 25%)), url("firefox.png");
  background-size: 25%;
  background-repeat: no-repeat;
}
```

```html
<div class="quarterlogo">
  If supported, a quarter of this div has a darkened logo
</div>
```

The above will put a semi-transparent black mask over the Firefox logo background image. Had we used the `background-color` property instead, the color would have appeared behind the logo image instead of on top of it. Additionally, the entire container would have had the same background color. Because we used `image()` along with the `background-size` property (and prevented the image from repeating with the `background-repeat` property, the color swatch will only cover a quarter of the container.

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

| Specification |
| --- |
| CSS Images Module Level 4 # image-notation |

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

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

See also
--------

* `<image>`
* `element()`
* `url()`
* `clip-path`
* `<gradient>`
* `image-set()`
* `cross-fade()`


image-set() - CSS: Cascading Style Sheets

image-set()
===========

The **`image-set()`** CSS functional notation is a method of letting the browser pick the most appropriate CSS image from a given set, primarily for high pixel density screens.

Resolution and bandwidth differ by device and network access. The `image-set()` function delivers the most appropriate image resolution for a user's device, providing a set of image options — each with an associated resolution declaration — from which the browser picks the most appropriate for the device and settings. Resolution can be used as a proxy for filesize — a user agent on a slow mobile connection with a high-resolution screen may prefer to receive lower-resolution images rather than waiting for a higher resolution image to load.

`image-set()` allows the author to provide options rather than determining what each individual user needs.

Syntax
------

```css
/\* Select image based on resolution \*/
image-set(
  "image1.jpg" 1x,
  "image2.jpg" 2x
);

image-set(
  url("image1.jpg") 1x,
  url("image2.jpg") 2x
);

/\* Select gradient based on resolution \*/
image-set(
  linear-gradient(blue, white) 1x,
  linear-gradient(blue, green) 2x
);

/\* Select image based on supported formats \*/
image-set(
  url("image1.avif") type("image/avif"),
  url("image2.jpg") type("image/jpeg")
);
```

### Values

`<image>`

The `<image>` can be any image type except for an image set. The `image-set()` function may not be nested inside another `image-set()` function.

`<string>`

A URL to an image.

`<resolution>` Optional

`<resolution>` units include `x` or `dppx`, for dots per pixel unit, `dpi`, for dots per inch, and `dpcm` for dots per centimeter. Every image within an `image-set()` must have a unique resolution.

`type(<string>)` Optional

A valid MIME type string, for example "image/jpeg".

### Formal syntax
```

<image-set()> =
  image-set( <image-set-option># )

<image-set-option> =
  [ <image> | <string> ] [ <resolution> || type( <string> ) ]?

<image> =
  <url>       |
  <gradient>

<url> =
  <url()>  |
  <src()>

<url()> =
  url( <string> <url-modifier>\* )  |
  <url-token>

<src()> =
  src( <string> <url-modifier>\* )

```

Examples
--------

### Using image-set() to provide alternative background-image options

This example shows how to use `image-set()` to provide two alternative `background-image` options, chosen depending on the resolution needed: a normal version and a high-resolution version.

**Note:** In the above example, the `-webkit` prefixed version is also used to support Chrome and Safari. In Firefox 90, support was added for `-webkit-image-set()` as an alias to `image-set()` (in order to provide compat where developers had not added the standard property).

### Using image-set() to provide alternative image formats

In the next example the `type()` function is used to serve the image in AVIF and JPEG formats. If the browser supports avif, it will choose that version. Otherwise it will use the jpeg version.

#### Providing a fallback

There is no inbuilt fallback for `image-set()`; therefore to include a `background-image` for those browsers that do not support the function, a separate declaration is required before the line using `image-set()`.

```css
.box {
  background-image: url("large-balloons.jpg");
  background-image: image-set(
    "large-balloons.avif" type("image/avif"),
    "large-balloons.jpg" type("image/jpeg")
  );
}
```

Accessibility concerns
----------------------

Browsers do not provide any special information on background images to assistive technology. This is important primarily for screen readers, as a screen reader will not announce its presence and therefore convey nothing to its users. If the image contains information critical to understanding the page's overall purpose, it is better to describe it semantically in the document.

* MDN Understanding WCAG, Guideline 1.1 explanations
* Understanding Success Criterion 1.1.1 | W3C Understanding WCAG 2.0
Specifications
--------------

| Specification |
| --- |
| CSS Images Module Level 4 # image-set-notation |

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

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

See also
--------

* `<image>`
* `image()`
* `element()`
* `url()`
* `<gradient>`
* `cross-fade()`


Spanning and balancing columns - CSS: Cascading Style Sheets

Spanning and balancing columns
==============================

In this guide, we look at how to make elements span across columns inside the multi-column (*multicol*) container and how to control how the columns are filled.

Spanning the columns
--------------------

To cause an item to span across columns, use the `column-span` property with a value of `all`. This will cause the element to become a *spanner*, spanning all the columns.

Any descendant element of the multicol container may be turned into a spanner, including both direct and indirect children. For example, a heading nested directly inside the container could become a spanner, as could a heading nested inside a `<section>` nested inside the multicol container.

In the example below, the `<h2>` element is set to `column-span: all` and spans all of the columns.

In this second example, the heading is inside an `<article>` element, yet still spans the content as expected.

When a spanner is introduced, it breaks the flow of columns; columns restart after the spanner, effectively creating a new set of column boxes. The content does not jump over a spanning element.

### Limitations of column-span

The `column-span` can have only two values. The initial value `none` means the item does not span and remains within a column. The value `all` means the item spans all of the columns. There are no values that enable partial spanning, such as having an item span two out of three columns.

### Things to watch out for

If the spanning element is inside another element with margins, padding, and a border or background color, the box may appear above the spanner with the rest of the content being displayed below. For this reason, care should be taken when setting an element to span all the columns, ensuring this scenario is accounted for.

Additionally, if a spanning element appears later in the content, it can cause unexpected or unwanted behavior when there is not enough content to create columns after the spanner. Use spanning carefully and test at various breakpoints to make sure you get the effect you intended.

Filling and balancing columns
-----------------------------

A balanced set of columns is where all columns have approximately the same amount of content. Filling and balancing are relevant when the amount of content does not match the amount of space provided, such as when a `height` is declared on the container.

The initial value for `column-fill` is `balance`. The value of `balance` means all columns are as balanced as possible. In fragmented contexts, such as paged media, only the last fragment is balanced. This means that on the last page, the final set of column boxes is balanced.

The other balancing value, `balance-all`, balances all columns in fragmented contexts.

The columns in this example contain an image and some text, which are balanced. The image, which cannot break, is in the first column. The other columns are balanced, filling with equal amounts of text.

The `auto` value for `column-fill` fills a column sequentially, filling the first column in the inline-start direction, before placing content in subsequent columns, rather than balancing and filling all the columns equally. In this example, we changed `column-fill` to `auto`. The columns are filled to the height of the container, leaving empty columns at the end.

Next steps
----------

In the next guide, you will learn how multicol handles overflow within columns and when there are more columns than can fit in the container.


Handling content breaks in multi-column layout - CSS: Cascading Style Sheets

Handling content breaks in multi-column layout
==============================================

Content between column boxes in a multicol layout breaks in the same way that it breaks between pages in paged media. In both contexts, you can control where and how content breaks by using properties of the CSS fragmentation module. In this guide, we see how fragmentation works in a *multi-column container* or *multicol container* for short.

Fragmentation basics
--------------------

The CSS fragmentation module provides details on how content breaks between the fragmentation containers or *fragmentainers*. The multi-column layout module, on the other hand, defines the `break-after`, `break-before`, and `break-inside` properties that provide some control within and between columns. In multicol layout, a column box is a fragment container.

A column box can contain other markup and there are many places where a break would not be ideal. For example, we would generally prefer that the caption of an image not be separated into a new column away from the image it refers to. Also, ending a column with a heading looks strange. The multicol fragmentation properties give us ways to exercise some control over this.

There are various places we might want to control our breaks:

* Breaks inside boxes, for example inside a figure element.
* Breaks before and after boxes, which would include our heading example above.
* Breaks between lines.
Breaks inside boxes
-------------------

To control breaks inside boxes use the `break-inside` property. This property takes values of:

* `auto`
* `avoid`
* `avoid-page`
* `avoid-column`
* `avoid-region`

In the example below, we have applied break-inside to the figure element to prevent the caption from becoming separated from the image.

Breaks before and after boxes
-----------------------------

The `break-before` and `break-after` properties are used to control breaks before and after elements. They take the following values when in a multicol context:

* auto
* avoid
* avoid-column
* column

In this next example, we are forcing a column break before an `h2` element.

Breaks between lines
--------------------

The `orphans` and `widows` properties, part of the CSS fragmentation module, are also useful and worth mentioning. The `orphans` property controls the number of lines left on their own at the end of a fragment. The `widows` property controls the number left on their own at the start of a fragment.

The `orphans` and `widows` properties take an `<integer>` as a value, which represents the number of lines to keep together at the end and start of a fragment, respectively. Note that these properties only work inside a block container, such as a paragraph. If the block has fewer lines in it than the number that you specify as a value, all lines will be kept together.

In the example below, we are using the `orphans` property to control the number of lines left at the bottom of a column. You can change that value to see the effect on the breaking of the content.

When things don't work as expected
----------------------------------

If you have small amounts of content and are trying to control breaks on several elements, your content needs to break somewhere, so you may not always get the result you intended. To some extent, your use of fragmentation is always a suggestion to the browser, to control breaks in this way if it is possible. If the content doesn't break where you intended, the result may be untidy, but the content is still available for your users.


Using multi-column layouts - CSS: Cascading Style Sheets

Using multi-column layouts
==========================

The properties defined in the **CSS multi-column layout module** extend the *block layout mode* , enabling the easy definition of multiple columns of text. People have trouble reading text if lines are too long. If it takes too long for the eyes to move from the end of one line to the beginning of the next, readers can lose track of which line they were on. To provide for a better user experience when reading text making use of a large screen, you should limit the width of text by using columns of text placed side by side, just as newspapers do.

Using columns
-------------

### Column count and width

Two CSS properties control whether and how many columns will appear: `column-count` and `column-width`.

The `column-count` property sets the number of columns to a particular number. E.g.,

Example 1
---------

### HTML

```html
<div id="col">
  <p>
    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
    tempor incididunt ut labore et dolore magna aliqua.
  </p>
  <p>
    Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
    aliquip ex ea commodo consequat.
  </p>
  <p>
    Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore
    eu fugiat nulla pariatur.
  </p>
  <p>
    Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
    deserunt mollit anim id est laborum.
  </p>
</div>
```

### CSS

```css
#col {
  column-count: 2;
}
```

### Result

The content will be displayed in two columns:

The `column-width` property sets the minimum desired column width. If `column-count` is not also set, then the browser will automatically make as many columns as fit in the available width.

Example 2
---------

### HTML

```html
<div id="wid">
  Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
  tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
  quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
  consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
  cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
  proident, sunt in culpa qui officia deserunt mollit anim id est laborum
</div>
```

### CSS

```css
#wid {
  column-width: 100px;
}
```

### Result

In a multi-column block, content automatically flows from one column into the next as needed. All HTML, CSS, and DOM functionality is supported within columns, as are editing and printing.

### The columns shorthand

You can use either `column-count` or `column-width`. Because values for these properties do not overlap, it is often convenient to use the shorthand `columns`.

Example 3
---------

In this example, the CSS declaration `column-width: 12em` is replaced by `columns: 12em`.

### HTML

```html
<div id="col\_short">
  Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
  tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
  quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
  consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
  cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
  proident, sunt in culpa qui officia deserunt mollit anim id est laborum
</div>
```

### CSS

```css
#col\_short {
  columns: 12em;
}
```

Example 4
---------

In this example, the CSS declaration `column-count: 4` is replaced by `columns: 4`.

### HTML

```html
<div id="columns\_4">
  Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
  tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
  quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
  consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
  cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
  proident, sunt in culpa qui officia deserunt mollit anim id est laborum
</div>
```

### CSS

```css
#columns\_4 {
  columns: 4;
}
```

### Result

Example 5
---------

The two CSS declarations `column-width: 8em` and `column-count: 12` can be replaced by `columns: 12 8em`. The `column-count` portion of the shorthand is the maximum number of columns that will be present. The `column-width` is the minimum width each column should be.

### HTML

```html
<div id="columns\_12">
  Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
  tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
  quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
  consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
  cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
  proident, sunt in culpa qui officia deserunt mollit anim id est laborum
</div>
```

### CSS

```css
#columns\_12 {
  columns: 12 8em;
}
```

### Result

Assuming a default `1em` gap between columns, if the container is wider than `103ems` (12 columns \* `8em` width each + 7 `1em` gaps), there will be 12 columns, each with a width of `8ems` or more. If the container is less than `103ems` wide, there will be fewer than 12 columns. If the container is less than `17ems` wide (`8em` column + `8em` column + `1em` gap), the content will be displayed as a single column with no column gap.

### Height balancing

CSS columns require that the column heights must be balanced: that is, the browser automatically sets the maximum column height so that the heights of the content in each column are approximately equal. Firefox does this.

However, in some situations it is also useful to set the maximum height of the columns explicitly, and then lay out content starting at the first column and creating as many columns as necessary, possibly overflowing to the right. Therefore, if the height is constrained, by setting the CSS `height` or `max-height` properties on a multi-column block, each column is allowed to grow to that height and no further before adding new column. This mode is also much more efficient for layout.

### Column Gaps

There is a gap between columns. The recommended default is `1em`. This size can be changed by applying the `column-gap` property to the multi-column block:

Example 6
---------

### HTML

```html
<div id="column\_gap">
  Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
  tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
  quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
  consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
  cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
  proident, sunt in culpa qui officia deserunt mollit anim id est laborum
</div>
```

### CSS

```css
#column\_gap {
  column-count: 5;
  column-gap: 2em;
}
```

### Result

Conclusion
----------

CSS columns are a layout primitive that can help make large blocks of text easier to read when responsive content is viewed on wide viewports. Imaginative developers may find many uses for them, especially in conjunction with container queries and with the automatic height balancing feature.


Handling overflow in multi-column layout - CSS: Cascading Style Sheets

Handling overflow in multi-column layout
========================================

In this guide, we look at how to deal with overflow in a multi-column (*multicol*) layout, both inside the column boxes and in situations where there is more content than will fit into the container.

Overflow inside column boxes
----------------------------

An overflow situation happens when an item's size is larger than the column box. For example, the situation could happen when an image in a column is wider than the `column-width` value or the width of the column based on the number of columns declared with `column-count`.

In this situation, the content should visibly overflow into the next column, rather than be clipped by the column box.

There are two columns of text. In the left column, there is a photo that is wider than the column. The image expands into that second column, appearing behind the text of the right column. The flow of text in the right column isn't affected by the protruding photo, but the appearance is.

If you want an image to fit the column box, setting `max-width: 100%` will prevent the image from growing beyond its container, in this case, the column box.

More columns than will fit
--------------------------

How overflowing columns are handled depends on whether the media context is fragmented, such as print, or is continuous, such as a web page.

In fragmented media, after a fragment (for example, a page) is filled with columns, the columns will move to a new page and fill that up with columns. In continuous media, columns will overflow in the inline direction. On the web, this means that you will get a horizontal scrollbar.

The example below shows this overflow behavior. The multicol container has a set `height` and there is more text than space to create columns; therefore, we get columns created outside of the container.

Using vertical media queries
----------------------------

One issue with multicol on the web is that if the columns are taller than the viewport, the reader will need to scroll the page up and down to read, which is not a good user experience. One way to avoid this is to only apply the column properties if you know there is enough vertical space.

In the example below, we used a `min-height` @media query to ensure there is enough vertical space before applying the column properties.

Next steps
----------

In the final guide in this series, we will see how fragmentation works with multicol layouts to give us control over how content breaks between columns.


Styling columns - CSS: Cascading Style Sheets

Styling columns
===============

As column boxes created inside multi-column (*multicol*) containers are anonymous boxes, styling individual columns is not possible, but we can style the gaps between the columns and the container in general. This guide explains how to change the gap and style rules between columns.

Column gaps
-----------

The gap between columns is controlled using the `column-gap` or `gap` property. The `column-gap` property is defined in the multi-column layout module. The `gap` property is defined in the box alignment module. This is a unified property to define gaps between boxes in all layouts that support gaps, including CSS grid layout and CSS flexible box layout.

The initial value of `column-gap` is `1em`, which prevents columns from running into each other. In other layout methods, `column-gap` is supported as a synonym for `gap`, but with an initial value of `0`. The keyword value `normal` sets `column-gap` to the initial value.

You can change the gap by using any `<length>` value. In the example below, the `column-gap` is set to `40px`.

The allowed value for `column-gap` is a `<length-percentage>`, meaning percentages are allowed. Percentage values for `column-gap` are calculated as a percentage of the width of the multicol container.

Column rules
------------

The specification defines `column-rule-width`, `column-rule-style` and `column-rule-color`, providing a shorthand `column-rule`. These properties work in exactly the same way as the `border` properties: any `<line-style>` can be used as a `column-rule-style`, just as for valid `border-style`.

These properties are applied to the element, which is the multicol container, and therefore, all columns will have the same rule. Rules are only drawn between columns and not on the outer edges. Rules are also only drawn between columns that have content.

In this next example, a 5px-dotted rule with a color of `rebeccapurple` has been created using the longhand values.

Note that the rule itself does not take up any space: a wide rule will not push the columns apart to make space for the rule. Instead, the rule overlays the gap.

The example below uses a very wide rule of `40px` and a `10px` gap. The rule displays under the column content. To make space on both sides of the rule, the gap would need to be increased to be larger than `40px`.

Next steps
----------

This article details all the current ways in which column boxes can be styled. In the next guide, we will take a look at making elements inside a container span across all columns.


Basic concepts of multi-column layout - CSS: Cascading Style Sheets

Basic concepts of multi-column layout
=====================================

Multi-column layout, usually referred to as multicol layout, is a specification for laying out content into a set of column boxes much like columns in a newspaper. This guide explains how the specification works with some common use case examples.

Key properties
--------------

Multicol layout is unlike any of the other layout methods in CSS; it fragments the content, including all descendant elements, into columns. This happens in the same way that content is fragmented into pages when we work with CSS paged media by creating a print stylesheet.

In this and subsequent guides, we will be discussing the following properties defined in the CSS multi-column layout module:

* `column-width`
* `column-count`
* `columns` shorthand
* `column-rule-color`
* `column-rule-style`
* `column-rule-width`
* `column-rule` shorthand
* `column-span`
* `column-fill`
* `column-gap`
* `break-after`
* `break-before`
* `break-inside`
Defining columns
----------------

By adding the `column-count` or the `column-width` property to an element, or using the `columns` shorthand, the element becomes a *multi-column container* or *multicol container* for short. The columns are anonymous boxes; they're described as *column boxes* in the specification.

### Specifying the number of columns

The `column-count` property specifies the number of columns that you would like the content to be displayed as. The browser will then assign the correct amount of space to each column box to create the requested number of columns.

In the below example, we use the `column-count` property to create three columns on the `.container` element. The content, including the children of `.container`, is then split between the three columns.

In the above example, the content is wrapped within the paragraph `<p>` tags with the default styling. Therefore, there is a margin above each paragraph. You can see how this margin causes the first line of text to be pushed down. This is because a multicol container creates a block formatting context (BFC) because of which margins on child elements do not collapse with any margin on the container.

### Specifying the width of columns

The `column-width` property is used to set the optimal width for every column box. If you declare a column width, the browser will work out how many columns of that width will fit into the multicol container and distribute any extra space equally between the columns. Therefore, the column width should be seen as minimum width because the column boxes are likely to be wider due to the additional space.

In the case of a single column with less width available than the value of `column-width`, the column box will shrink to be smaller than the declared column width.

In the example below, the `column-width` property is set to `200px`. We get as many 200-pixel columns as will fit the container, with the extra space shared equally.

### Specifying both number and width of columns

If you specify both the properties on a multicol container, then `column-count` will act as a maximum number of columns. Therefore, the behavior as described for `column-width` will happen, until the number of columns in `column-count` is reached. After this point, no more columns will be drawn, and the extra space is distributed evenly between the existing columns, even if there is enough room for more columns of the specified `column-width` size.

When using both properties together, you may get fewer columns than specified in the value for `column-count`.

In this next example, we use `column-width` of `200px` and `column-count` of `2`. Even if there is space for more than two columns, we get two. If there is not enough space for two columns of at least 200 pixels each, we get one.

### Shorthand for column properties

You can use the `columns` shorthand to set the `column-count` and `column-width` values. If you specify a length unit, the value will be used for `column-width`, and if you specify an integer, the value will be used for `column-count`. You can set both the properties, separating the two values with a space.

This CSS would give the same result as example 1, with `column-count` set to `3`.

```css
.container {
  columns: 3;
}
```

This CSS would give the same result as example 2, with `column-width` of `200px`.

```css
.container {
  columns: 200px;
}
```

This CSS would give the same result as example 3, with both `column-count` and `column-width` set.

```css
.container {
  columns: 2 200px;
}
```

Next steps
----------

In this guide, we've learned the basic use of multi-column layout. In the next guide, we will look at how much we can style the columns themselves.


Using media queries for accessibility - CSS: Cascading Style Sheets

Using media queries for accessibility
=====================================

**CSS media queries** can be used to help users with disabilities better experience your website.

Reduced Motion
--------------

Blinking and flashing animation can be problematic for people with cognitive concerns such as Attention Deficit Hyperactivity Disorder (ADHD). Additionally, certain kinds of motion can be a trigger for Vestibular disorders, epilepsy, and migraine and Scotopic sensitivity. The `prefers-reduced-motion` media query enables providing an experience with fewer animations and transitions to users who have set their operating system's accessibility preferences to reduce motion.

Also, this method of switching animation off according to the user's preference can also benefit users with low battery or low-end phones or computers.

### Syntax

`no-preference`

Indicates that the user has made no preference known to the system.

`reduce`

Indicates that user has notified the system that they prefer an interface that minimizes the amount of movement or animation, preferably to the point where all non-essential movement is removed.

### Example

This example has an annoying animation unless you turn on Reduce Motion in your accessibility preferences.

#### HTML

```html
<div class="animation">animated box</div>
```

#### CSS

```css
.animation {
  animation: vibrate 0.3s linear infinite both;
}

@media (prefers-reduced-motion: reduce) {
  .animation {
    animation: none;
  }
}
```

The value of `prefers-reduced-motion` is `reduce`, not "none". Users are not expecting no animation, such as could be set with `* {animation: none !important;}`. Rather, they expect motion animation triggered by interaction to be disabled, unless the animation is essential to the functionality or the information being conveyed (see WCAG: Animation from Interactions).

See also
--------

* `prefers-contrast`: to adjust page styles based on user's contrast preference
* `prefers-reduced-transparency`
* `prefers-color-scheme`
* `inverted-colors`
* Designing With Reduced Motion For Motion Sensitivities


Printing - CSS: Cascading Style Sheets

Printing
========

There may be times in which your website or application would like to improve the user's experience when printing content. There are several possible scenarios:

* You wish to adjust layout to take advantage of the size and shape of the paper.
* You wish to use different styles to enhance the appearance of your content on paper.
* You wish to use higher resolution images for a better result.
* You want to adjust the user experience of printing, such as presenting a specially-formatted version of your content before printing begins.

There may be other cases in which you want to manage the printing process, but these are some of the most common scenarios. This article provides tips and techniques for helping your web content print better.

Using a print style sheet
-------------------------

Add the following to your `<head>` tag.

```html
<link href="/path/to/print.css" media="print" rel="stylesheet" />
```

Using media queries and @page to improve layout
-----------------------------------------------

You can use the CSS `@media` at-rule to set a different appearance for your webpage when it is printed on paper and when it is displayed on the screen. The `print` option sets the styles that will be used when the content is printed.

Add this at the end of your stylesheet. Note that specificity and precedence rules still apply:

```css
@media print {
  /\* All your print styles go here \*/
  #header,
 #footer,
 #nav {
    display: none !important;
  }
}
```

You can also use the `@page` at-rule to modify different aspects of printed pages including the page's dimensions, orientation, and margins. The `@page` at-rule can be used to target all pages in a print-out or just a specific subset of pages

Detecting print requests
------------------------

Browsers send `beforeprint` and `afterprint` events to let content determine when printing may have occurred. You can use this to adjust the user interface presented during printing (such as by displaying or hiding user interface elements during the print process).

Examples
--------

Here are some common examples.

### Automatically close the window when finished

The following example will close the window after the user has printed its contents:

```js
window.addEventListener("afterprint", () => self.close);
```

### Print an external page without opening it

If you want to be able to print an external page without opening it, you can utilize a hidden `<iframe>` (see: HTMLIFrameElement), automatically removing it after the user prints its contents. The following is a possible example which will print a file named `externalPage.html`:

#### HTML

```html
<button id="print\_external">Print external page!</button>
```

#### JavaScript

```js
function setPrint() {
  const closePrint = () => {
    document.body.removeChild(this);
  };
  this.contentWindow.onbeforeunload = closePrint;
  this.contentWindow.onafterprint = closePrint;
  this.contentWindow.print();
}

document.getElementById("print\_external").addEventListener("click", () => {
  const hideFrame = document.createElement("iframe");
  hideFrame.onload = setPrint;
  hideFrame.style.display = "none"; // hide iframe
  hideFrame.src = "external-page.html";
  document.body.appendChild(hideFrame);
});
```

See also
--------

* `window.print`
* `beforeprint` event
* `afterprint` event
* Media queries
* `@media`
* CSS paged media module


Testing media queries programmatically - CSS: Cascading Style Sheets

Testing media queries programmatically
======================================

The DOM provides features that can test the results of a media query programmatically, via the `MediaQueryList` interface and its methods and properties. Once you've created a `MediaQueryList` object, you can check the result of the query or receive notifications when the result changes.

Creating a media query list
---------------------------

Before you can evaluate the results of a media query, you need to create the `MediaQueryList` object representing the query. To do this, use the `window.matchMedia` method.

For example, to set up a query list that determines if the device is in landscape or portrait orientation:

```js
const mediaQueryList = window.matchMedia("(orientation: portrait)");
```

Checking the result of a query
------------------------------

Once you've created your media query list, you can check the result of the query by looking at the value of its `matches` property:

```js
if (mediaQueryList.matches) {
  /\* The viewport is currently in portrait orientation \*/
} else {
  /\* The viewport is not currently in portrait orientation, therefore landscape \*/
}
```

Receiving query notifications
-----------------------------

If you need to be aware of changes to the evaluated result of the query on an ongoing basis, it's more efficient to register a listener than to poll the query's result. To do this, call the `addEventListener()` method on the `MediaQueryList` object, with a callback function to invoke when the media query status changes (e.g., the media query test goes from `true` to `false`):

```js
// Create the query list.
const mediaQueryList = window.matchMedia("(orientation: portrait)");

// Define a callback function for the event listener.
function handleOrientationChange(mql) {
  // …
}

// Run the orientation change handler once.
handleOrientationChange(mediaQueryList);

// Add the callback function as a listener to the query list.
mediaQueryList.addEventListener("change", handleOrientationChange);
```

This code creates the orientation-testing media query list, then adds an event listener to it. After defining the listener, we also call the listener directly. This makes our listener perform adjustments based on the current device orientation; otherwise, our code might assume the device is in portrait mode at startup, even if it's actually in landscape mode.

The `handleOrientationChange()` function would look at the result of the query and handle whatever we need to do on an orientation change:

```js
function handleOrientationChange(evt) {
  if (evt.matches) {
    /\* The viewport is currently in portrait orientation \*/
  } else {
    /\* The viewport is currently in landscape orientation \*/
  }
}
```

Above, we define the parameter as `evt` — an event object of type `MediaQueryListEvent` that also includes the `media` and `matches` properties, so you can query these features of the `MediaQueryList` by directly accessing it, or accessing the event object.

Ending query notifications
--------------------------

To stop receiving notifications about changes to the value of your media query, call `removeEventListener()` on the `MediaQueryList`, passing it the name of the previously-defined callback function:

```js
mediaQueryList.removeEventListener("change", handleOrientationChange);
```

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

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

See also
--------

* Media queries
* `window.matchMedia()`
* `MediaQueryList`
* `MediaQueryListEvent`


Using media queries - CSS: Cascading Style Sheets

Using media queries
===================

**Media queries** allow you to apply CSS styles depending on a device's general type (such as print vs. screen) or other characteristics such as screen resolution or browser viewport width.
 Media queries are used for the following:

* To conditionally apply styles with the CSS `@media` and `@import` at-rules.
* To target specific media for the `<style>`, `<link>`, `<source>`, and other HTML elements with the `media=` attribute.
* To test and monitor media states using the `Window.matchMedia()` and `EventTarget.addEventListener()` methods.

**Note:** The examples on this page use CSS's `@media` for illustrative purposes, but the basic syntax remains the same for all types of media queries.

Syntax
------

 A media query is composed of an optional *media type* and any number of *media feature* expressions, which may optionally be combined in various ways using *logical operators*.
 Media queries are case-insensitive.

* Media types define the broad category of device for which the media query applies: `all`, `print`, `screen`.
 The type is optional (assumed to be `all`) except when using the `not` or `only` logical operators.
* Media features describe a specific characteristic of the user agent, output device, or environment:
    + `any-hover`
    + `any-pointer`
    + `aspect-ratio`
    + `color`
    + `color-gamut`
    + `color-index`
    + `device-aspect-ratio`
    Deprecated
    + `device-height`
    Deprecated
    + `device-width`
    Deprecated
    + `display-mode`
    + `dynamic-range`
    + `forced-colors`
    + `grid`
    + `height`
    + `hover`
    + `inverted-colors`
    + `monochrome`
    + `orientation`
    + `overflow-block`
    + `overflow-inline`
    + `pointer`
    + `prefers-color-scheme`
    + `prefers-contrast`
    + `prefers-reduced-motion`
    + `prefers-reduced-transparency`
    Experimental
    + `resolution`
    + `scripting`
    + `update`
    + `video-dynamic-range`
    + `width`.For example, the `hover` feature allows a query to test against whether the device supports hovering over elements.
 Media feature expressions test for their presence or value, and are entirely optional.
 Each media feature expression must be surrounded by parentheses.
* Logical operators can be used to compose a complex media query: `not`, `and`, and `only`.
 You can also combine multiple media queries into a single rule by separating them with commas.

 A media query computes to `true` when the media type (if specified) matches the device on which a document is being displayed *and* all media feature expressions compute as true.
 Queries involving unknown media types are always false.

**Note:** A style sheet with a media query attached to its `<link>` tag will still download even if the query returns `false`, the download will happen but the priority of downloading will be much lower.
 Nevertheless, its contents will not apply unless and until the result of the query changes to `true`.
 You can read why this happens in Tomayac's blog Why Browser Download Stylesheet with Non-Matching Media Queries.

Targeting media types
---------------------

 Media types describe the general category of a given device.
 Although websites are commonly designed with screens in mind, you may want to create styles that target special devices such as printers or audio-based screen readers.
 For example, this CSS targets printers:

```css
@media print {
  /\* … \*/
}
```

 You can also target multiple devices.
 For instance, this `@media` rule uses two media queries to target both screen and print devices:

```css
@media screen, print {
  /\* … \*/
}
```

 See media type for a list of all media types.
 Because they describe devices in only very broad terms, just a few are available; to target more specific attributes, use *media features* instead.

Targeting media features
------------------------

 Media features describe the specific characteristics of a given user agent, output device, or environment.
 For instance, you can apply specific styles to widescreen monitors, computers that use mice, or to devices that are being used in low-light conditions.
 This example applies styles when the user's *primary* input mechanism (such as a mouse) can hover over elements:

```css
@media (hover: hover) {
  /\* … \*/
}
```

 Many media features are *range features*, which means they can be prefixed with "min-" or "max-" to express "minimum condition" or "maximum condition" constraints.
 For example, this CSS will apply styles only if your browser's viewport width is equal to or narrower than 1250px:

```css
@media (max-width: 1250px) {
  /\* … \*/
}
```

 If you create a media feature query without specifying a value, the nested styles will be used as long as the feature's value is not zero (or `none`, in Level 4).
 For example, this CSS will apply to any device with a color screen:

```css
@media (color) {
  /\* … \*/
}
```

If a feature doesn't apply to the device on which the browser is running, expressions involving that media feature are always false.

For more Media feature examples, please see the reference page for each specific feature.

Creating complex media queries
------------------------------

 Sometimes you may want to create a media query that depends on multiple conditions. This is where the *logical operators* come in: `not`, `and`, and `only`.
 Furthermore, you can combine multiple media queries into a *comma-separated list*; this allows you to apply the same styles in different situations.

 In the previous example, we've already seen the `and` operator used to group a media *type* with a media *feature*.
 The `and` operator can also combine multiple media features into a single media query. The `not` operator, meanwhile, negates a media query, basically reversing its normal meaning.
 The `only` operator prevents older browsers from applying the styles.

**Note:** In most cases, the `all` media type is used by default when no other type is specified.
 However, if you use the `not` or `only` operators, you must explicitly specify a media type.

### Combining multiple types or features

 The `and` keyword combines a media feature with a media type *or* other media features.
 This example combines two media features to restrict styles to landscape-oriented devices with a width of at least 30 ems:

```css
@media (min-width: 30em) and (orientation: landscape) {
  /\* … \*/
}
```

To limit the styles to devices with a screen, you can chain the media features to the `screen` media type:

```css
@media screen and (min-width: 30em) and (orientation: landscape) {
  /\* … \*/
}
```

### Testing for multiple queries

 You can use a comma-separated list to apply styles when the user's device matches any one of various media types, features, or states.
 For instance, the following rule will apply its styles if the user's device has either a minimum height of 680px *or* is a screen device in portrait mode:

```css
@media (min-height: 680px), screen and (orientation: portrait) {
  /\* … \*/
}
```

 Taking the above example, if the user had a printer with a page height of 800px, the media statement would return true because the first query would apply.
 Likewise, if the user were on a smartphone in portrait mode with a viewport height of 480px, the second query would apply and the media statement would still return true.

### Inverting a query's meaning

 The `not` keyword inverts the meaning of an entire media query. It will only negate the specific media query it is applied to.
 (Thus, it will not apply to every media query in a comma-separated list of media queries.)
 The `not` keyword can't be used to negate an individual feature query, only an entire media query.
 The `not` is evaluated last in the following query:

```css
@media not all and (monochrome) {
  /\* … \*/
}
```

This means that the above query is evaluated like this:

```css
@media not (all and (monochrome)) {
  /\* … \*/
}
```

It wouldn't be evaluated like this:

```css
@media (not all) and (monochrome) {
  /\* … \*/
}
```

As another example, the following media query:

```css
@media not screen and (color), print and (color) {
  /\* … \*/
}
```

This means that the above query is evaluated like this:

```css
@media (not (screen and (color))), print and (color) {
  /\* … \*/
}
```

### Improving compatibility with older browsers

 The `only` keyword prevents older browsers that do not support media queries with media features from applying the given styles.
 *It has no effect on modern browsers.*

```css
@media only screen and (color) {
  /\* … \*/
}
```

Syntax improvements in Level 4
------------------------------

 The Media Queries Level 4 specification includes some syntax improvements to make media queries using features that have a "range" type, for example width or height, less verbose.
 Level 4 adds a *range context* for writing such queries.
 You can check the `@media` browser compatibility table for details on support.

To see how the "range" syntax works, let's look at an example that applies styles based on `max-width`:

```css
@media (max-width: 30em) {
  /\* … \*/
}
```

In Media Queries Level 4 this can be written as:

```css
@media (width <= 30em) {
  /\* … \*/
}
```

Using `min-` and `max-` we can check for a width between two values like so:

```css
@media (min-width: 30em) and (max-width: 50em) {
  /\* … \*/
}
```

You can write this using the "range" syntax as:

```css
@media (30em <= width <= 50em) {
  /\* … \*/
}
```

Media Queries Level 4 also adds ways to combine media queries using full boolean algebra with **and**, **not**, and **or**.

### Negating a feature with `not`

Using `not()` around a media feature negates that feature in the query. For example, `not(hover)` would match if the device had no hover capability:

```css
@media (not(hover)) {
  /\* … \*/
}
```

### Testing for multiple features with `or`

 You can use `or` to test for a match among more than one feature, resolving to `true` if any of the features are true.
 For example, the following query tests for devices that have a monochrome display or hover capability:

```css
@media (not (color)) or (hover) {
  /\* … \*/
}
```

See also
--------

* @media
* Container queries
* Testing media queries programmatically
* CSS Animations Between Media Queries
* Extended Mozilla media features
* Extended WebKit media features


size - CSS: Cascading Style Sheets

size
====

The **`size`** CSS at-rule descriptor, used with the `@page` at-rule, defines the size and orientation of the box which is used to represent a page. Most of the time, this size corresponds to the target size of the printed page if applicable.

Size may either be defined with a "scalable" keyword (in this case the page will fill the available dimensions) or with absolute dimensions.

Syntax
------

```css
/\* Keyword values for scalable size \*/
size: auto;
size: portrait;
size: landscape;

/\* <length> values \*/
/\* 1 value: height = width \*/
size: 6in;

/\* 2 values: width then height \*/
size: 4in 6in;

/\* Keyword values for absolute size \*/
size: A4;
size: B5;
size: JIS-B4;
size: letter;

/\* Mixing size and orientation \*/
size: A4 portrait;
```

### Values

`auto`

The user agent decides the size of the page. In most cases, the dimensions and orientation of the target sheet are used.

`landscape`

The content of the page is displayed in landscape mode (i.e. the longest side of the box is horizontal).

`portrait`

The content of the page is displayed in portrait mode (i.e. the longest side of the box is vertical). This is the default orientation.

`<length>`

Any length value (see `<length>`). The first value corresponds to the width of the page box and the second one corresponds to its height. If only one value is provided, it is used for both width and height.

`<page-size>`

A keyword which may be any of the following values:

A5

This matches the standard, ISO dimensions: 148mm x 210mm.

A4

This matches the standard, ISO dimensions: 210mm x 297mm. (most frequently used dimensions for personal printing.)

A3

This matches the standard, ISO dimensions: 297mm x 420mm.

B5

This matches the standard, ISO dimensions: 176mm x 250mm.

B4

This matches the standard, ISO dimensions: 250mm x 353mm.

JIS-B5

This correspond to the JIS standard dimensions: 182mm x 257mm.

JIS-B4

This correspond to the JIS standard dimensions: 257mm x 364mm.

letter

This keyword is an equivalent to the dimensions of letter paper in North America i.e. 8.5in x 11in.

legal

This keyword is an equivalent to the dimensions of legal papers in North America i.e. 8.5in x 14in.

ledger

This keyword is an equivalent to the dimensions of ledger pages in North America i.e. 11in x 17in.

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

|  |  |
| --- | --- |
| Related at-rule | `@page` |
| Initial value | `auto` |
| Computed value | as specified, but with relative lengths converted into absolute lengths |

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

size =
  <length [0,∞]>{1,2}                          |
  auto                                         |
  [ <page-size> || [ portrait | landscape ] ]

```

Examples
--------

### Specifying size and orientation

```css
@page {
  size: A4 landscape;
}
```

### Specifying a custom size

```css
@page {
  size: 4in 6in;
}
```

### Nesting inside a @media rule

```css
@media print {
  @page {
    size: 50mm 150mm;
  }
}
```

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

| Specification |
| --- |
| CSS Paged Media Module Level 3 # page-size-prop |

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

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


page-orientation - CSS: Cascading Style Sheets

page-orientation
================

The **`page-orientation`** CSS descriptor for the `@page` at-rule controls the rotation of a printed page. It handles the flow of content across pages when the orientation of a page is changed. This behavior differs from the `size` descriptor in that a user can define the direction in which to rotate the page.

This descriptor helps with the layout and orientation of printed documents, especially when documents are printed double-sided. A user can specify how the pages will be rotated when printed. This is particularly useful to lay out content such as tables, which may be wider than the rest of the content, in a different orientation.

**Note:** Margin boxes and other positional elements have no special interaction with this descriptor. Margins are laid out as normal in the unrotated page, then rotated along with everything else.

Syntax
------

```css
/\* Displays the print content in an upright position \*/
@page {
  page-orientation: upright;
}

/\* Displays the print content rotated counter-clockwise \*/
@page {
  page-orientation: rotate-left;
}

/\* Displays the print content rotated counter-clockwise \*/
@page {
  page-orientation: rotate-right;
}
```

Values
------

`upright`

No orientation is applied and the page is laid out and formatted as normal.

`rotate-left`

After a page is laid out, the page must be displayed rotated a quarter turn to the left (counter-clockwise).

`rotate-right`

After the page is laid out, the page must be displayed rotated a quarter turn to the right (clockwise).

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

|  |  |
| --- | --- |
| Related at-rule | `@page` |
| Initial value | `upright` |
| Computed value | as specified |

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

page-orientation =
  upright       |
  rotate-left   |
  rotate-right

```

Examples
--------

### Rotating printed pages

This example shows how the contents of a print document can be rotated to suit the page content and the page position.
```

<fieldset id="printStyle">
  <legend>
    Click Print. The page will be laid out in the defined orientation.
  </legend>
  <button id="print">Print</button>
</fieldset>
<div id="print-area">
  <section class="upright">
    <h2>Section in Portrait/Upright</h2>
    <p>This section will be printed in portrait and upright with:</p>
    <pre>
.upright {
  size: portrait;
  page-orientation: upright;
}
    </pre>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur eu
      convallis ligula, tincidunt malesuada tortor. Ut ac turpis erat. Mauris
      consequat, leo rhoncus venenatis elementum, sem nisl venenatis justo, non
      mattis diam massa vitae dolor. Aenean ac dolor et leo laoreet tincidunt.
      Suspendisse tempus risus nibh, a feugiat mauris pharetra a. Nulla mi dui,
      scelerisque vitae sollicitudin nec, placerat eget purus. Vivamus enim
      elit, scelerisque id venenatis eu, sodales vel leo. Quisque bibendum
      feugiat diam, ut feugiat urna suscipit et. Nulla lacinia metus a nisi
      volutpat interdum. Lorem ipsum dolor sit amet, consectetur adipiscing
      elit. Vestibulum vitae elit vel orci malesuada bibendum ut vitae enim. Ut
      ultrices elit nec vestibulum blandit. In in eleifend dui. Nam nec aliquet
      nunc. Praesent convallis ipsum sed fermentum scelerisque.
    </p>
    <p>
      Praesent posuere, neque non fringilla ultricies, purus mi ullamcorper
      velit, vitae egestas nisl eros at ex. Nulla sed viverra libero. Praesent
      sed placerat magna, iaculis commodo lectus. Ut gravida ligula sed purus
      molestie, in accumsan est eleifend. Etiam consectetur nulla pretium
      blandit iaculis. Nunc semper libero ut mauris faucibus placerat. Cras ac
      justo ac est laoreet sollicitudin. Aliquam vel sapien ut sapien vestibulum
      dictum.
    </p>
  </section>
  <section class="left">
    <h2>Section in Landscape/Left</h2>
    <p>This section will be printed in landscape and rotated left with:</p>
    <pre>
.left {
  size: landscape;
  page-orientation: rotate-left;
}
    </pre>
    <table>
      <thead>
        <tr>
          <th></th>
          <th>100m</th>
          <th>1500m</th>
          <th>Hurdles</th>
          <th>Long Jump</th>
          <th>High Jump</th>
          <th>Javelin</th>
          <th>Discus</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <th>Dave</th>
          <td>9.65</td>
          <td>3:49</td>
          <td>12.64</td>
          <td>8.54m</td>
          <td>1.95m</td>
          <td>56.65m</td>
          <td>47.63m</td>
        </tr>
        <tr>
          <th>Simon</th>
          <td>9.87</td>
          <td>3:52</td>
          <td>11.89</td>
          <td>8.16m</td>
          <td>1.96m</td>
          <td>59.03m</td>
          <td>45.72m</td>
        </tr>
        <tr>
          <th>Fred</th>
          <td>9.67</td>
          <td>3:52</td>
          <td>12.03</td>
          <td>8.04m</td>
          <td>2.01m</td>
          <td>62.58m</td>
          <td>46.83m</td>
        </tr>
        <tr>
          <th>Gary</th>
          <td>9.77</td>
          <td>3:56</td>
          <td>13.04</td>
          <td>7.96m</td>
          <td>2.02m</td>
          <td>63.87m</td>
          <td>47.73m</td>
        </tr>
        <tr>
          <th>Dick</th>
          <td>9.95</td>
          <td>3:44</td>
          <td>12.99</td>
          <td>5.66m</td>
          <td>1.97m</td>
          <td>56.43m</td>
          <td>43.87m</td>
        </tr>
        <tr>
          <th>Tom</th>
          <td>9.84</td>
          <td>3:48</td>
          <td>12.86</td>
          <td>6.87m</td>
          <td>1.95m</td>
          <td>67.03m</td>
          <td>42.73m</td>
        </tr>
        <tr>
          <th>Harry</th>
          <td>9.91</td>
          <td>3:53</td>
          <td>13.77</td>
          <td>7.34m</td>
          <td>1.94m</td>
          <td>62.84m</td>
          <td>46.72m</td>
        </tr>
      </tbody>
    </table>
  </section>
  <section class="right">
    <h2>Section in Landscape/Right</h2>
    <p>This section will be printed in landscape and rotated right with:</p>
    <pre>
.right {
  size: landscape;
  page-orientation: rotate-right;
}
    </pre>
    <table>
      <thead>
        <tr>
          <th></th>
          <th>100m</th>
          <th>1500m</th>
          <th>Hurdles</th>
          <th>Long Jump</th>
          <th>High Jump</th>
          <th>Javelin</th>
          <th>Discus</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <th>Dave</th>
          <td>9.65</td>
          <td>3:49</td>
          <td>12.64</td>
          <td>8.54m</td>
          <td>1.95m</td>
          <td>56.65m</td>
          <td>47.63m</td>
        </tr>
        <tr>
          <th>Simon</th>
          <td>9.87</td>
          <td>3:52</td>
          <td>11.89</td>
          <td>8.16m</td>
          <td>1.96m</td>
          <td>59.03m</td>
          <td>45.72m</td>
        </tr>
        <tr>
          <th>Fred</th>
          <td>9.67</td>
          <td>3:52</td>
          <td>12.03</td>
          <td>8.04m</td>
          <td>2.01m</td>
          <td>62.58m</td>
          <td>46.83m</td>
        </tr>
        <tr>
          <th>Gary</th>
          <td>9.77</td>
          <td>3:56</td>
          <td>13.04</td>
          <td>7.96m</td>
          <td>2.02m</td>
          <td>63.87m</td>
          <td>47.73m</td>
        </tr>
        <tr>
          <th>Dick</th>
          <td>9.95</td>
          <td>3:44</td>
          <td>12.99</td>
          <td>5.66m</td>
          <td>1.97m</td>
          <td>56.43m</td>
          <td>43.87m</td>
        </tr>
        <tr>
          <th>Tom</th>
          <td>9.84</td>
          <td>3:48</td>
          <td>12.86</td>
          <td>6.87m</td>
          <td>1.95m</td>
          <td>67.03m</td>
          <td>42.73m</td>
        </tr>
        <tr>
          <th>Harry</th>
          <td>9.91</td>
          <td>3:53</td>
          <td>13.77</td>
          <td>7.34m</td>
          <td>1.94m</td>
          <td>62.84m</td>
          <td>46.72m</td>
        </tr>
      </tbody>
    </table>
  </section>
</div>
```

#### CSS

In this first part of the CSS code, named pages are set up to define the direction in which to rotate the content.

```css
@page upright {
  size: portrait;
  page-orientation: upright;
}

@page left {
  size: landscape;
  page-orientation: rotate-left;
}

@page right {
  size: landscape;
  page-orientation: rotate-right;
}
```

```
fieldset {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  gap: 1rem;
  width: fit-content;
}
p {
  max-width: 60ch;
}
@media print {
  fieldset {
    display: none;
  }
  section {
    font-family: Roboto;
    font-size: 1.5rem;
  }
}
```

The following second part of the CSS code declares a named page rule defined above for the selectors, such as `<section class="left">…</section>`.

```css
@media print {
  .upright {
    page: upright;
  }
  .left {
    page: left;
  }
  .right {
    page: right;
  }
}
```

```
const printButton = document.querySelector("#print");
printButton.addEventListener("click", () => {
  window.print();
});
```

### Result

Click the print button to see the pages rotated.

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

| Specification |
| --- |
| CSS Paged Media Module Level 3 # page-orientation-prop |

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

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


Logical properties for sizing - CSS: Cascading Style Sheets

Logical properties for sizing
=============================

In this guide we will explain the flow-relative mappings between physical dimension properties and logical properties used for sizing elements on our pages.

When specifying the size of an item, the Logical Properties and Values specification gives you the ability to indicate sizing as it relates to the flow of text (inline and block) rather than physical sizing which relates to the physical dimensions of horizontal and vertical (e.g. left and right). While these flow relative mappings may well become the default for many of us, in a design you may well use both physical and logical sizing. You might want some features to always relate to the physical dimensions whatever the writing mode.

Mappings for dimensions
-----------------------

The table below provides mappings between logical and physical properties. These mappings assume that you are in a `horizontal-tb` writing mode, such as English or Arabic, in which case `width` would be mapped to `inline-size`.

If you were in a vertical writing mode then `inline-size` would be mapped to `height`.

| Logical Property | Physical Property |
| --- | --- |
| `inline-size` | `width` |
| `block-size` | `height` |
| `min-inline-size` | `min-width` |
| `min-block-size` | `min-height` |
| `max-inline-size` | `max-width` |
| `max-block-size` | `max-height` |

Width and height example
------------------------

The logical mappings for `width` and `height` are `inline-size`, which sets the length in the inline dimension and `block-size`, which sets the length in the block dimension. When working in English, replacing `width` with `inline-size` and `height` with `block-size` will give the same layout.

In the live example below I have set the Writing Mode to `horizontal-tb`. Change it to `vertical-rl` and you will see that the first example — which uses `width` and `height` — remains the same size in each dimension, despite the text becoming vertical. The second example — which uses `inline-size` and `block-size` — will follow the text direction as if the entire block has rotated.

Min-width and min-height example
--------------------------------

There are also mappings for `min-width` and `min-height` — these are `min-inline-size` and `min-block-size`. These work in the same way as the `inline-size` and `block-size` properties, but setting a minimum rather than a fixed size.

Try changing the example below to `vertical-rl`, as with the first example, to see the effect it has. I am using `min-height` in the first example and `min-block-size` in the second.

Max-width and max-height example
--------------------------------

Finally you can use `max-inline-size` and `max-block-size` as logical replacements for `max-width` and `max-height`. Try playing with the below example in the same way as before.

Logical keywords for resize
---------------------------

The `resize` property sets whether or not an item can be resized and has physical values of `horizontal` and `vertical`. The `resize` property also has logical keyword values. Using `resize: inline` allows resizing in the inline dimension and `resize: block` allow resizing in the block dimension.

The keyword value of `both` for the resize property works whether you are thinking physically or logically. It sets both dimensions at once. Try playing with the below example.


Basic concepts of logical properties and values - CSS: Cascading Style Sheets

Basic concepts of logical properties and values
===============================================

The Logical Properties and Values Specification introduces flow-relative mappings for many of the properties and values in CSS. This article introduces the specification, and explains flow relative properties and values.

Why do we need logical properties?
----------------------------------

CSS traditionally has sized things according to the physical dimensions of the screen. Therefore we describe boxes as having a `width` and `height`, position items from the `top` and `left`, float things left, assign borders, margin, and padding to the `top`, `right`, `bottom`, `left`, etc. The Logical Properties and Values specification defines mappings for these physical values to their logical, or flow relative, counterparts — e.g. `start` and `end` as opposed to `left` and `right`/`top` and `bottom`.

An example of why these mappings might be needed is as follows. I have a Layout using CSS Grid, the grid container has a width applied and I am using the `align-self` and `justify-self` properties to align the items. These properties are flow relative — `justify-self: start` aligns the item to the start on the inline dimension, `align-self: start` does the same on the block dimension.

![A grid in a horizontal writing mode](/en-US/docs/Web/CSS/CSS_logical_properties_and_values/Basic_concepts_of_logical_properties_and_values/grid-horizontal-width-sm.png)

If I now change the writing mode of this component to `vertical-rl` using the `writing-mode` property, the alignment continues to work in the same way. The inline dimension is now running vertically and the block dimension horizontally. The grid doesn't look the same, however, as the width assigned to the container is a horizontal measure, a measure tied to the physical and not the logical or flow relative running of the text.

![A grid in vertical writing mode.](/en-US/docs/Web/CSS/CSS_logical_properties_and_values/Basic_concepts_of_logical_properties_and_values/grid-vertical-width-sm.png)

If instead of the `width` property we use the logical property `inline-size`, the component now works the same way no matter which writing mode it is displayed using.

![A grid layout in vertical writing mode](/en-US/docs/Web/CSS/CSS_logical_properties_and_values/Basic_concepts_of_logical_properties_and_values/grid-vertical-inline-size-small.png)

You can try this out in the live example below. Change `writing-mode` from `vertical-rl` to `horizontal-tb` on `.grid` to see how the different properties change the layout.

When working with a site in a writing mode other than a horizontal, top to bottom one, or when using writing modes for creative reasons, being able to relate to the flow of the content makes a lot of sense.

Block and inline dimensions
---------------------------

A key concept of working with flow relative properties and values is the two dimensions of block and inline. As we saw above, newer CSS layout methods such as Flexbox and Grid Layout use the concepts of `block` and `inline` rather than `right` and `left`/`top` and `bottom` when aligning items.

The `inline` dimension is the dimension along which a line of text runs in the writing mode in use. Therefore, in an English document with the text running horizontally left to right, or an Arabic document with the text running horizontally right to left, the inline dimension is *horizontal*. Switch to a vertical writing mode (e.g. a Japanese document) and the inline dimension is now *vertical*, as lines in that writing mode run vertically.

The block dimension is the other dimension, and the direction in which blocks — such as paragraphs — display one after the other. In English and Arabic, these run vertically, whereas in any vertical writing mode these run horizontally.

The below diagram shows the inline and block directions in a horizontal writing mode:

![diagram showing the inline axis running horizontally, block axis vertically.](/en-US/docs/Web/CSS/CSS_logical_properties_and_values/Basic_concepts_of_logical_properties_and_values/mdn-horizontal.png)

This diagram shows block and inline in a vertical writing mode:

![Diagram showing the block axis running horizontally the inline axis vertically.](/en-US/docs/Web/CSS/CSS_logical_properties_and_values/Basic_concepts_of_logical_properties_and_values/mdn-vertical.png)

See also
--------

* Box alignment in grid layout
* Box alignment in flex layout
* Flow layout and writing modes
* Understanding logical properties and values on Smashing Magazine (2018)


Logical properties for floating and positioning - CSS: Cascading Style Sheets

Logical properties for floating and positioning
===============================================

The Logical Properties and Values specification contains logical mappings for the physical values of `float` and `clear`, and also for the positioning properties used with positioned layout. This guide takes a look at how to use these.

Mapped properties and values
----------------------------

The table below details the properties and values discussed in this guide along with their physical mappings. They assume a horizontal `writing-mode`, with a left-to-right direction.

| Logical property or value | Physical property or value |
| --- | --- |
| `float`: inline-start | `float`: left |
| `float`: inline-end | `float`: right |
| `clear`: inline-start | `clear`: left |
| `clear`: inline-end | `clear`: right |
| `inset-inline-start` | `left` |
| `inset-inline-end` | `right` |
| `inset-block-start` | `top` |
| `inset-block-end` | `bottom` |
| `text-align`: start | `text-align`: left |
| `text-align`: end | `text-align`: right |

In addition to these mapped properties there are some additional shorthand properties made possible by being able to address block and inline dimensions. These have no mapping to physical properties, aside from the `inset` property.

| Logical property | Purpose |
| --- | --- |
| `inset-inline` | Sets both of the above inset values for the inline dimension simultaneously. |
| `inset-block` | Sets both of the above inset values for the block dimension simultaneously. |
| `inset` | Sets all four inset values simultaneously with physical mapping of multi-value. |

Float and clear example
-----------------------

The physical values used with the `float` and `clear` properties are `left`, `right` and `both`. The Logical Properties specification defines the values `inline-start` and `inline-end` as mappings for `left` and `right`.

In the example below I have two boxes — the first has the box floated with `float: left`, the second with `float: inline-start`. If you change the `writing-mode` to `vertical-rl` or the `direction` to `rtl` you will see that the left-floated box always sticks to the left, whereas the `inline-start`-floated item follows the `direction` and `writing-mode`.

Example: Inset properties for positioned layout
-----------------------------------------------

Positioning generally allows us to position an element in a manner relative to its containing block — we essentially inset the item relative to where it would fall based on normal flow. To do this we have historically used the physical properties `top`, `right`, `bottom` and `left`.

These properties take a length or a percentage as a value, and relate to the user's screen dimensions.

New properties have been created in the Logical Properties specification for when you want the positioning to relate to the flow of text in your writing mode. These are as follows: `inset-block-start`, `inset-block-end`, `inset-inline-start` and `inset-inline-end`.

In the below example I have used the `inset-block-start` and `inset-inline-end` properties to position the blue box using absolute positioning inside the area with the grey dotted border, which has `position: relative`. Change the `writing-mode` property to `vertical-rl`, or add `direction: rtl`, and see how the flow relative box stays with the text direction.

New two- and four-value shorthands
----------------------------------

As with other properties in the specification we have some new shorthand properties, which give the ability to set two or four values at once.

* `inset` — sets all four sides together with physical mapping.
* `inset-inline` — sets both logical inline insets.
* `inset-block` — sets both logical block insets.
Example: Logical values for text-align
--------------------------------------

The `text-align` property has logical values that relate to text direction — rather than using `left` and `right` we can use `start` and `end`. In the below example I have set `text-align: right` in the first block and `text-align: end` in the second.

If you change the value of `direction` to `rtl` you will see that the alignment stays to the right for the first block, but goes to the logical end on the left in the second.

This works more consistently when using box alignment that uses start and end rather than physical directions for alignment.