Interactivity & scrolling
The properties that shape how people interact with a page: the pointer, text selection, form controls and the text caret, focus reading order and speech, then how scroll containers behave, how their scrollbars look, where scrolling comes to rest and the generated parts of a CSS carousel. Whether a box scrolls at all is set by overflow, under Box model; every other property group is listed on the Properties overview.
Pointer & cursor
cursor
The mouse cursor shown while the pointer is over the element. Use it to hint at what a click or drag will do.
| Syntax | [<cursor-image>,]* <cursor-predefined> |
|---|---|
| Initial | auto |
| Applies to | All elements |
| Inherited | Yes |
| Animation | Discrete |
| Support | Chrome 1 · Firefox 1 · Safari 1.2 |
| Spec | css-ui-4 |
| Value | Meaning |
|---|---|
auto | The browser chooses from the context, for example a text cursor over selectable text. |
default | The platform's default cursor, usually an arrow. |
none | No cursor is shown. |
pointer | A link or other clickable thing, usually a pointing hand. |
context-menu, help | A context menu, or help, is available. |
progress | The program is busy in the background but can still be used. |
wait | The program is busy and the user should wait. |
cell, crosshair | A table cell can be selected; a precise point can be picked. |
text, vertical-text | Text can be selected, in horizontal or vertical lines. |
alias, copy, move | Dropping here will create a shortcut, a copy, or move the item. |
no-drop, not-allowed | The dragged item cannot be dropped here; the action is not allowed. |
grab, grabbing | Something can be grabbed and dragged; it is being dragged. |
n-resize, e-resize, s-resize, w-resize, ne-resize, nw-resize, se-resize, sw-resize | An edge or corner can be moved in that compass direction. |
ew-resize, ns-resize, nesw-resize, nwse-resize | Resizing in both directions along one line. |
col-resize, row-resize | A column or row can be resized. |
all-scroll | The content can be scrolled in any direction. |
zoom-in, zoom-out | Something can be zoomed in or out. |
Custom cursors come first as a comma-separated list of images, each optionally followed by the x and y of its hotspot. A keyword must always come last as the fallback.
cursor: url(pen.svg) 2 30, crosshair;
pointer-events
Whether an element can be the target of pointer events such as clicks and hovers. With none, the pointer passes through to whatever is underneath.
| Syntax | auto | bounding-box | visiblePainted | visibleFill | visibleStroke | visible | painted | fill | stroke | all | none |
|---|---|
| Initial | auto |
| Applies to | Container elements, graphics elements and use (in SVG); all elements in HTML |
| Inherited | Yes |
| Animation | Discrete |
| Support | Chrome 1 · Firefox 1.5 · Safari 4 |
| Spec | SVG 2 |
On HTML elements only auto and none matter. The other values are for SVG, where they choose whether the fill, the stroke or the bounding box receives events, and whether it must be visible. A descendant can set pointer-events: auto to take events again inside a parent set to none.
touch-action
Which touch gestures the browser handles itself on an element, such as panning and pinch-zooming. Gestures it does not handle go to the page's pointer event handlers instead, which is what a custom drawing surface, map or slider needs.
| Syntax | auto | none | [ [ pan-x | pan-left | pan-right ] || [ pan-y | pan-up | pan-down ] || pinch-zoom ] | manipulation |
|---|---|
| Initial | auto |
| Applies to | All elements except non-replaced inline elements, table rows, row groups, table columns and column groups |
| Inherited | No |
| Animation | Not animatable |
| Support | Chrome 36 · Firefox 52 · Safari 13 |
| Spec | compat |
| Value | Effect |
|---|---|
auto | The browser handles every gesture as usual. |
none | The browser handles no touch gestures; all of them reach the page's handlers. |
pan-x | Horizontal panning is allowed. |
pan-y | Vertical panning is allowed. |
pinch-zoom | Zooming with more than one finger is allowed. |
manipulation | Panning and pinch-zoom are allowed, but not other gestures such as double-tap to zoom. |
The values combine: pan-y pinch-zoom lets the page scroll vertically and zoom while a script handles horizontal swipes. pan-left, pan-right, pan-up and pan-down allow panning in one direction only, and are supported in Chrome only (from 55). pinch-zoom arrived later than the property itself: Chrome 56, Firefox 85, Safari 13.
user-select
Controls whether the user can select the element's text. none prevents selection, all selects the whole element in one go, and contain keeps a selection that starts inside from extending outside.
| Syntax | auto | text | none | contain | all |
|---|---|
| Initial | auto |
| Applies to | All elements, and optionally the ::before and ::after pseudo-elements |
| Inherited | No |
| Animation | Discrete |
| Support | Chrome 54 · Firefox 69 · Safari no |
| Spec | css-ui-4 |
Safari supports it only with the prefix, as -webkit-user-select.
Form controls & caret
appearance
Whether a form control is drawn with the platform's native look. none strips the native styling so the control can be styled like any other box; auto keeps it.
| Syntax | none | auto | base | base-select | <compat-auto> | <compat-special> |
|---|---|
| Initial | none |
| Applies to | All elements |
| Inherited | No |
| Animation | Discrete |
| Support | Chrome 84 · Firefox 80 · Safari 15.4 |
| Spec | css-ui-4 |
base-select on a <select> and its ::picker(select) switches it to a fully stylable, customisable select (Chrome 135, Safari 27). The <compat-auto> keywords (button, checkbox, menulist and so on) are legacy values that behave like auto; of the <compat-special> keywords, textfield removes a search field's native styling and menulist-button draws a select as a drop-down button.
accent-color
The accent colour of native form controls such as checkboxes, radio buttons, range sliders and progress bars, so they match a brand without being rebuilt.
| Syntax | auto | <color> |
|---|---|
| Initial | auto |
| Applies to | All elements |
| Inherited | Yes |
| Animation | By computed value type |
| Support | Chrome 93 · Firefox 92 · Safari 26.2 |
| Spec | css-ui-4 |
Safari 15.4 to 26.1 applied the colour but did not keep the control's contrast legible.
field-sizing
With content, a form control such as a text input, <textarea> or <select> sizes itself to fit what is in it, growing as the user types, instead of keeping a fixed default size.
| Syntax | fixed | content |
|---|---|
| Initial | fixed |
| Applies to | Elements with a default preferred size |
| Inherited | No |
| Animation | Discrete |
| Support | Chrome 123 · Firefox 152 · Safari 26.2 |
| Spec | css-forms-1 |
textarea { field-sizing: content; min-block-size: 3lh; max-block-size: 12lh; }
caret-color
The colour of the text insertion caret in inputs, textareas and editable content. auto usually follows currentColor.
| Syntax | auto | <color> [auto | <color>]? |
|---|---|
| Initial | auto |
| Applies to | Text or elements that accept text input |
| Inherited | Yes |
| Animation | By computed value |
| Support | Chrome 57 · Firefox 53 · Safari 11.1 |
| Spec | css-ui-4 |
caret-shape
The shape of the text caret: a thin vertical bar, a block covering the next character, or an underscore beneath it. auto uses the platform's usual caret.
| Syntax | auto | bar | block | underscore |
|---|---|
| Initial | auto |
| Applies to | Text or elements that accept text input |
| Inherited | Yes |
| Animation | By computed value |
| Support | Chrome 144 · Firefox no · Safari no |
| Spec | css-ui-4 |
caret-animation
With manual, the browser stops blinking the caret, so an author's own animation of caret-color is not fighting the built-in blink. auto keeps the usual blink.
| Syntax | auto | manual |
|---|---|
| Initial | auto |
| Applies to | Text or elements that accept text input |
| Inherited | Yes |
| Animation | Discrete |
| Support | Chrome 140 · Firefox no · Safari no |
| Spec | css-ui-4 |
resize
Gives the element a handle the user can drag to resize it, in both axes, or only horizontally or vertically. Textareas are resizable by default; other elements need overflow set to something other than visible first.
| Syntax | none | both | horizontal | vertical | block | inline |
|---|---|
| Initial | none |
| Applies to | Scroll containers, and optionally replaced elements such as images, videos and iframes |
| Inherited | No |
| Animation | Discrete |
| Support | Chrome 1 · Firefox 4 · Safari 3 |
| Spec | css-ui-4 |
Interaction
interactivity
With inert, the element and its descendants become inert: they cannot be focused, clicked or selected and are hidden from assistive technology, just as with the HTML inert attribute, but set from a stylesheet.
| Syntax | auto | inert |
|---|---|
| Initial | auto |
| Applies to | All elements |
| Inherited | Yes |
| Animation | Discrete |
| Support | Chrome 135 · Firefox no · Safari no |
| Spec | css-ui-4 |
interest-delay
Shorthand for interest-delay-start and interest-delay-end: how long the user must hover over or focus an interest invoker (an element with the interestfor attribute) before its target shows, and how long after they move away before it hides. One value sets both.
| Syntax | <'interest-delay-start'>{1,2} |
|---|---|
| Initial | See individual properties |
| Applies to | See individual properties |
| Inherited | See individual properties |
| Animation | See individual properties |
| Support | Chrome 142 · Firefox no · Safari no |
| Spec | css-ui-4 |
[interestfor] { interest-delay: 300ms 600ms; }
interest-delay-start, interest-delay-end
The delay before interest is gained (start) or lost (end). normal uses the browser's default delay.
| Syntax | normal | <time> |
|---|---|
| Initial | normal |
| Applies to | All elements |
| Inherited | Yes |
| Animation | By computed value type |
| Support | Chrome 142 · Firefox no · Safari no |
| Spec | css-ui-4 |
reading-flow
Makes keyboard focus order and the order read by assistive technology follow a flex or grid container's visual layout instead of the source order, so reordered items are no longer reached out of sequence.
| Syntax | normal | source-order | flex-visual | flex-flow | grid-rows | grid-columns | grid-order |
|---|---|
| Initial | normal |
| Applies to | Block, flex and grid containers |
| Inherited | No |
| Animation | Not animatable |
| Support | Chrome 137 · Firefox no · Safari no |
| Spec | css-display-4 |
| Value | Reading order |
|---|---|
normal | Source order, as usual. |
flex-visual | Flex items in visual reading order, taking the writing mode into account. |
flex-flow | Flex items in the order given by flex-flow. |
grid-rows, grid-columns | Grid items in visual order, row by row or column by column. |
grid-order | Grid items in source order as changed by the order property. |
source-order | Source order, but items can be moved with reading-order. |
reading-order
Moves an item within its container's reading flow: items are read and focused in ascending reading-order, with ties falling back to the container's reading flow.
| Syntax | <integer> |
|---|---|
| Initial | 0 |
| Applies to | Direct block-level, grid item or flex item children of a reading flow container |
| Inherited | No |
| Animation | By computed value type |
| Support | Chrome 137 · Firefox no · Safari no |
| Spec | css-display-4 |
window-drag
With move, dragging the element moves the browser window. It is for installed web apps that draw their own title bar.
| Syntax | none | move |
|---|---|
| Initial | none |
| Applies to | All elements |
| Inherited | Yes |
| Animation | Discrete |
| Support | Chrome 152 · Firefox no · Safari no |
| Spec | css-ui-4 |
Speech
speak
Whether the element's text is spoken by a speech synthesiser. never silences it, always speaks it even when it is not displayed, and auto follows whether it is rendered.
| Syntax | auto | never | always |
|---|---|
| Initial | auto |
| Applies to | All elements |
| Inherited | Yes |
| Animation | Discrete |
| Support | Chrome ≤80 · Firefox no · Safari no |
| Spec | css-speech-1 |
Chrome's implementation does not fully follow the specification.
speak-as
How text is read aloud: spell-out reads it letter by letter, digits reads numbers one digit at a time, and literal-punctuation or no-punctuation reads punctuation out or skips it.
| Syntax | normal | spell-out || digits || [ literal-punctuation | no-punctuation ] |
|---|---|
| Initial | normal |
| Applies to | All elements |
| Inherited | Yes |
| Animation | Discrete |
| Support | Chrome no · Firefox no · Safari 11.1 |
| Spec | css-speech-1 |
Scrolling behaviour
scroll-behavior
With smooth, scrolls triggered by navigation to a fragment or by script animate smoothly instead of jumping. Scrolling done by the user is not affected.
| Syntax | auto | smooth |
|---|---|
| Initial | auto |
| Applies to | Scroll containers |
| Inherited | No |
| Animation | Not animatable |
| Support | Chrome 61 · Firefox 36 · Safari 15.4 |
| Spec | css-overflow-3 |
@media (prefers-reduced-motion: no-preference) {
html { scroll-behavior: smooth; }
}
overflow-anchor
Scroll anchoring keeps the visible content still when something above it changes size, such as an image loading. none opts an element, or a whole scroll container, out of being used as the anchor.
| Syntax | auto | none |
|---|---|
| Initial | auto |
| Applies to | All elements |
| Inherited | No |
| Animation | Discrete |
| Support | Chrome 56 · Firefox 66 · Safari 27 |
| Spec | css-scroll-anchoring-1 |
overscroll-behavior
Shorthand for overscroll-behavior-x and overscroll-behavior-y: what happens when the user scrolls past the end of a scroll container. One value sets both axes; two set x then y.
| Syntax | [ contain | none | auto | chain ]{1,2} |
|---|---|
| Initial | auto auto |
| Applies to | Scroll container elements |
| Inherited | No |
| Animation | Discrete |
| Support | Chrome 144 · Firefox 150 · Safari 16 |
| Spec | css-overscroll-1 |
| Value | Effect |
|---|---|
auto | Scrolling carries on into the parent scroll container, and the platform's overscroll effects (bounce, pull to refresh) happen as usual. |
contain | Scrolling stops at this container and does not chain to the parent, but the container still shows its own overscroll effect. |
none | No scroll chaining and no overscroll effect. |
chain | Scrolling chains to the parent even when this container has no scrollable overflow (Chrome 150, Firefox 157). |
Earlier versions (Chrome 63, Firefox 59) supported the property except on scroll containers that had no scrollable overflow; Safari 16 still has that limit. overscroll-behavior: contain on a modal or side panel stops the page behind it from scrolling once the panel reaches its end.
overscroll-behavior-x, overscroll-behavior-y, overscroll-behavior-block, overscroll-behavior-inline
Overscroll handling in one axis: the two physical axes, or the block and inline axes of the writing mode.
| Syntax | contain | none | auto | chain |
|---|---|
| Initial | auto |
| Applies to | Scroll container elements |
| Inherited | No |
| Animation | Discrete |
| Support | Chrome 144 · Firefox 150 · Safari 16 |
| Spec | css-overscroll-1 |
scroll-initial-target
With nearest, the element's nearest scroll container starts out scrolled to show it when the page first loads, for example to open a carousel on a middle slide.
| Syntax | none | nearest |
|---|---|
| Initial | none |
| Applies to | All elements |
| Inherited | No |
| Animation | Not animatable |
| Support | Chrome 133 · Firefox no · Safari no |
| Spec | css-scroll-snap-2 |
scroll-axis-lock
Whether the browser may lock a user's scroll gesture to a single axis. With none, a diagonal swipe can scroll in both directions at once.
| Syntax | auto | none |
|---|---|
| Initial | auto |
| Applies to | Scroll container elements |
| Inherited | No |
| Animation | Discrete |
| Support | Chrome 153 · Firefox no · Safari no |
| Spec | css-overflow-5 |
Scrollbars
scrollbar-color
The colours of a scroll container's scrollbars: the thumb first, then the track. auto uses the platform's colours.
| Syntax | auto | <color>{2} |
|---|---|
| Initial | auto |
| Applies to | Scroll containers |
| Inherited | Yes |
| Animation | By computed value |
| Support | Chrome 121 · Firefox 64 · Safari 26.2 |
| Spec | css-scrollbars-1 |
scrollbar-color: oklch(60% 0.1 250) transparent;
scrollbar-width
How thick the scrollbars are: the platform default, a thin variant, or none to hide them while leaving the box scrollable.
| Syntax | auto | thin | none |
|---|---|
| Initial | auto |
| Applies to | Scroll containers |
| Inherited | No |
| Animation | Discrete |
| Support | Chrome 121 · Firefox 64 · Safari 18.2 |
| Spec | css-scrollbars-1 |
scrollbar-gutter
With stable, space for a classic scrollbar is always reserved, so the content does not shift sideways when the scrollbar appears or disappears. both-edges reserves the same space on the opposite side too, keeping content centred.
| Syntax | auto | stable && both-edges? |
|---|---|
| Initial | auto |
| Applies to | Scroll containers |
| Inherited | No |
| Animation | Discrete |
| Support | Chrome 94 · Firefox 97 · Safari 18.2 |
| Spec | css-overflow-3 |
Overlay scrollbars, which float over the content, never take up a gutter, so the property has no effect on them.
Scroll snap
scroll-snap-type
Turns a scroll container into a snap container: after the user scrolls, it comes to rest aligned to one of its children's snap positions. The first keyword picks the axis; mandatory always snaps, while proximity (the default) snaps only when a snap position is close.
| Syntax | none | [ x | y | block | inline | both | pair ] [ mandatory | proximity ]? |
|---|---|
| Initial | none |
| Applies to | Scroll containers |
| Inherited | No |
| Animation | Discrete |
| Support | Chrome 69 · Firefox 99 · Safari 11 |
| Spec | css-scroll-snap-1 |
.carousel {
overflow-x: auto;
scroll-snap-type: x mandatory;
}
.carousel > * {
scroll-snap-align: center;
scroll-snap-stop: always; /* never skip past a slide */
}
Snap positions are set on the children with scroll-snap-align. pair, which snaps in both axes together to a single position, is in Chrome 156 only.
scroll-snap-align
Where an element sits in the snapport when its scroll container snaps to it: aligned to the start, end or center. One value sets both axes; two set the block axis then the inline axis.
| Syntax | [ none | start | end | center ]{1,2} |
|---|---|
| Initial | none |
| Applies to | All elements |
| Inherited | No |
| Animation | Discrete |
| Support | Chrome 69 · Firefox 68 · Safari 11 |
| Spec | css-scroll-snap-1 |
scroll-snap-stop
With always, a fast scroll must stop at this element's snap position rather than flying past it to a later one. normal allows skipping.
| Syntax | normal | always |
|---|---|
| Initial | normal |
| Applies to | All elements |
| Inherited | No |
| Animation | Discrete |
| Support | Chrome 75 · Firefox 103 · Safari 15 |
| Spec | css-scroll-snap-1 |
Scroll margin & padding
scroll-margin
Shorthand for the four physical scroll margins: extra space around an element that is kept in view when it is scrolled to, whether by snapping, a fragment link or scrollIntoView(). Takes one to four values in the same order as margin. It does not affect layout.
| Syntax | <length>{1,4} |
|---|---|
| Initial | 0 |
| Applies to | All elements |
| Inherited | No |
| Animation | By computed value type |
| Support | Chrome 69 · Firefox 90 · Safari 14.1 |
| Spec | css-scroll-snap-1 |
h2[id] { scroll-margin-block-start: 5rem; }
scroll-margin-block, scroll-margin-inline
Shorthands for the start and end scroll margins in the block or inline axis. One value sets both ends; two set start then end.
| Syntax | <length>{1,2} |
|---|---|
| Initial | 0 |
| Applies to | All elements |
| Inherited | No |
| Animation | By computed value type |
| Support | Chrome 69 · Firefox 68 · Safari 15 |
| Spec | css-scroll-snap-1 |
scroll-margin-top, scroll-margin-right, scroll-margin-bottom, scroll-margin-left
The scroll margin on one physical side of the element.
| Syntax | <length> |
|---|---|
| Initial | 0 |
| Applies to | All elements |
| Inherited | No |
| Animation | By computed value type |
| Support | Chrome 69 · Firefox 68 · Safari 14.1 |
| Spec | css-scroll-snap-1 |
scroll-margin-block-start, scroll-margin-block-end, scroll-margin-inline-start, scroll-margin-inline-end
The scroll margin on one flow-relative side, mapped to a physical side by the writing mode and direction.
| Syntax | <length> |
|---|---|
| Initial | 0 |
| Applies to | All elements |
| Inherited | No |
| Animation | By computed value type |
| Support | Chrome 69 · Firefox 68 · Safari 15 |
| Spec | css-scroll-snap-1 |
scroll-padding
Shorthand for the four physical scroll paddings: an inset on the scroll container that shrinks the area used when scrolling things into view, for example to keep snapped or linked content out from under a sticky header. Takes one to four values in the same order as padding. It does not affect layout.
| Syntax | [ auto | <length-percentage [0,∞]> ]{1,4} |
|---|---|
| Initial | auto |
| Applies to | Scroll containers |
| Inherited | No |
| Percentages | Relative to the corresponding dimension of the scroll container's scrollport |
| Animation | By computed value type |
| Support | Chrome 69 · Firefox 68 · Safari 14.1 |
| Spec | css-scroll-snap-1 |
html { scroll-padding-block-start: 4rem; }
scroll-padding-block, scroll-padding-inline
Shorthands for the start and end scroll paddings in the block or inline axis. One value sets both ends; two set start then end.
| Syntax | [ auto | <length-percentage [0,∞]> ]{1,2} |
|---|---|
| Initial | auto |
| Applies to | Scroll containers |
| Inherited | No |
| Percentages | Relative to the scroll container's scrollport |
| Animation | By computed value |
| Support | Chrome 69 · Firefox 68 · Safari 15 |
| Spec | css-scroll-snap-1 |
scroll-padding-top, scroll-padding-right, scroll-padding-bottom, scroll-padding-left
The scroll padding on one physical side of the scroll container. auto lets the browser choose, which is usually 0.
| Syntax | auto | <length-percentage [0,∞]> |
|---|---|
| Initial | auto |
| Applies to | Scroll containers |
| Inherited | No |
| Percentages | Relative to the scroll container's scrollport |
| Animation | By computed value type |
| Support | Chrome 69 · Firefox 68 · Safari 14.1 |
| Spec | css-scroll-snap-1 |
scroll-padding-block-start, scroll-padding-block-end, scroll-padding-inline-start, scroll-padding-inline-end
The scroll padding on one flow-relative side of the scroll container, mapped to a physical side by the writing mode and direction.
| Syntax | auto | <length-percentage [0,∞]> |
|---|---|
| Initial | auto |
| Applies to | Scroll containers |
| Inherited | No |
| Percentages | Relative to the scroll container's scrollport |
| Animation | By computed value type |
| Support | Chrome 69 · Firefox 68 · Safari 15 |
| Spec | css-scroll-snap-1 |
Carousel parts
scroll-marker-group
Makes a scroll container generate a ::scroll-marker-group pseudo-element, placed before or after it, which holds the ::scroll-marker of each item: a row of dots or tabs that jump to the item and show which one is in view.
| Syntax | none | [ [ before | after ] || [ links | tabs ] ] |
|---|---|
| Initial | none |
| Applies to | Scroll containers |
| Inherited | No |
| Animation | Discrete |
| Support | Chrome 135 · Firefox no · Safari no |
| Spec | css-overflow-5 |
.carousel { scroll-marker-group: after; }
.carousel > li::scroll-marker { content: ''; }
.carousel > li::scroll-marker:target-current { background: currentColor; }
scroll-target-group
With auto, the element becomes a group of ordinary anchor links whose targets are tracked as the page scrolls; the link whose target is in view matches :target-current. Use it to highlight the current section in a table of contents.
| Syntax | none | auto |
|---|---|
| Initial | none |
| Applies to | All elements |
| Inherited | No |
| Animation | Discrete |
| Support | Chrome 140 · Firefox no · Safari no |
| Spec | css-overflow-5 |