interactivity
Limited availability
This feature is not Baseline because it does not work in some of the most widely-used browsers.
Experimental: This is an experimental technology
Check the Browser compatibility table carefully before using this in production.
The interactivity
CSS property specifies whether an element and its descendant nodes are set to be inert.
Syntax
/* Keyword values */
interactivity: auto;
interactivity: inert;
/* Global values */
interactivity: inherit;
interactivity: initial;
interactivity: revert;
interactivity: revert-layer;
interactivity: unset;
Values
auto
-
Selected elements are in their default state in terms of inertness. This usually means that they are interactive, but this is not always the case. This is the default value.
inert
-
Selected elements and their descendants are inert.
Formal definition
Value not found in DB!Formal syntax
interactivity =
auto |
inert
Description
The interactivity
property can be used to set whether an element and its descendants are inert. See the HTML inert
attribute reference page for a detailed description of the inert state.
A typical use case for interactivity: inert
is in paginated content, like carousels, when you only want the currently-visible page's content and controls to be interacted with. In such cases, unexpectedly focusing on an off-screen link or button could spoil the experience.
If an element's inert state is specified both by HTML (the inert
attribute, or an automatic browser setting) and CSS (the interactive
property) at the same time, the CSS will have no effect — it cannot overide the HTML's inertness.
For example, the following HTML element will be inert:
<button inert>You can't press me</button>
Setting interactive: auto
on it will have no effect.
Default inertness
Most elements are interactive by default, but this is not always the case:
- An element's ancestor may be set to an inert state, via the
interactive
property or theinert
attribute. - While a modal
<dialog>
is displayed, the rest of the page is set to an inert state automatically.
Examples
>Basic interactivity
usage
In this example we have two <input>
elements. The second one has interactivity: inert
set on it via a class, and therefore is not focusable or editable in supporting browsers.
<p>
<label>
This input is interactive:
<input type="text" name="one" value="editable" />
</label>
</p>
<p>
<label>
This input is not interactive:
<input type="text" name="two" value="Not editable" class="inert" />
</label>
</p>
.inert {
interactivity: inert;
background-color: lightpink;
}
Result
The output looks like this:
Exploring the effects of inertness
In this example we explore the effects of the interactivity
property.
HTML
The markup features two <p>
elements, each of which contain a link. The second paragraph also has a class of inert
set on it, and a child <span>
element with contenteditable
set on it to make it editable.
<p>
This paragraph is not
<a
href="https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Global_attributes/inert"
>inert</a
>. You should be able to select the text content, search for it using
in-browser search features, and focus and click the link. There is a
<code>click</code> event handler set on the paragraph that changes the border
color for a second when it is clicked anywhere.
<span contenteditable="">This sentence has <code>contenteditable</code> set on
it, so it is editable</span>.
</p>
<p class="inert">
This paragraph is
<a
href="https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Global_attributes/inert"
>inert</a
>. You won't be able to select the text content, search for it using
in-browser search features, focus and click the link, or issue
<code>click</code> events on it (the border color won't change when it is
clicked).
<span contenteditable=""
>This sentence has <code>contenteditable</code> set on it, but it is not
editable because it is inert</span
>.
</p>
CSS
We set the interactivity
property on the second paragraph to a value of inert
, making it inert. This means that you should be able to edit the contenteditable
text in the first paragraph, but not in the second, and you shouldn't be able to search for text, select text, or interact with the link within the second paragraph.
.inert {
interactivity: inert;
}
[contenteditable] {
outline: 1px dashed lightblue;
}
.borderChanged {
border-color: orange;
}
JavaScript
We set an event handler on each paragraph that toggles a class name when clicked, adding the classname then removing the class after two seconds.
const paras = document.querySelectorAll("p");
function tempBorderChange(e) {
const targetPara = e.currentTarget;
targetPara.classList.add("borderChanged");
setTimeout(() => {
targetPara.classList.remove("borderChanged");
}, 2000);
}
for (para of paras) {
para.addEventListener("click", tempBorderChange);
}
Result
Note how the second paragraph is inert; it therefore does not behave like the first paragraph. For example, the link cannot be clicked or focused, the text cannot be selected or searched, the contenteditable
<span>
is not editable, and click
events do not register on it.
Setting off-screen elements to inert using a view timeline
This example shows horizontally-scrolling paginated content, with each page snapped to using CSS Scroll Snap, and the inertness controlled via a scroll-driven animation that uses a view progress timeline. Content displayed in the scroll container is interactive; it becomes inert when it moves out into the overflowing content.
HTML
The HTML consists of a top-level heading and an unordered list with four list items, each containing the content for a separate page.
<h1>Pagination interactivity demo</h1>
<ul>
<li>
<h2>Page 1</h2>
<p>This is the first page of content.</p>
<p><a href="#">A demo link</a>.</p>
<p><button>Press me</button></p>
</li>
<li>
<h2>Page 2</h2>
<p>This is the second page of content.</p>
<p><a href="#">A demo link</a>.</p>
<p><button>Press me</button></p>
</li>
<li>
<h2>Page 3</h2>
<p>This is the third page of content.</p>
<p><a href="#">A demo link</a>.</p>
<p><button>Press me</button></p>
</li>
<li>
<h2>Page 4</h2>
<p>This is the fourth page of content.</p>
<p><a href="#">A demo link</a>.</p>
<p><button>Press me</button></p>
</li>
</ul>
CSS
A width
of 100vw
is set on the unordered list to make it as wide as the viewport. We add a fixed height
, some padding
, and an overflow-x
value of scroll
so overflowing content will scroll. Its child list items are laid out horizontally with display: flex
. This flex container is given a scroll-snap-type
value of x mandatory
to make it into a scroll snap container. The x
keyword causes the container's snap targets to be snapped horizontally. The mandatory
keyword means that the container will always snap to a snap target at the end of a scrolling action.
ul {
width: 100vw;
height: 250px;
padding: 1vw;
overflow-x: scroll;
display: flex;
gap: 1vw;
scroll-snap-type: x mandatory;
}
Each list item has the following styles applied:
- A
flex
value of0 0 98vw
, forcing each item to be as big as the scroll container minus thegap
set on the list (see thegap
declaration in theul
rule shown earlier). This also has the effect of centering each page inside the scroll container. - A
scroll-snap-align
value ofcenter
, to cause the scroll container to snap to the center of each snap target. - A
view-timeline
value of--inertChange inline
, to declare the element as the subject of the--inertChange
view progress timeline, and set that timeline to progress in the inline direction as it moves through its ancestor scroll container. - An
animation-timeline
value with the same name as theview-timeline-name
, as defined in theview-timeline
shorthand, which means that the named view progress timeline will be used to control the progress of animations applied to the element. - An
animation-name
andanimation-fill-mode
defining the animation applied to this element and its fill mode. Theboth
value is required because you want the starting animation state to apply to the element before the animation starts, and the end animation state to apply to the element after the animation finishes. If the animation isn't persisted, theinteractivity: inert
declaration applied via the animation won't apply to list items when they are outside the scroll container.
li {
list-style-type: none;
background-color: #eee;
border: 1px solid #ddd;
padding: 20px;
flex: 0 0 98vw;
scroll-snap-align: center;
view-timeline: --inertChange inline;
animation-timeline: --inertChange;
animation-name: inert-change;
animation-fill-mode: both;
}
Finally, the animation @keyframes
are defined. interactivity: inert
is set at positions entry 0%
and exit 100%
of the view timeline. Combined with the animation-fill-mode: both
value, this means that the list items will be inert before the start and after the end of the view timeline, that is, when they are outside the scroll container. Between positions entry 1%
and exit 99%
, interactivity: auto
is set on the list items, meaning they can be interacted with normally when they are inside the scroll container.
@keyframes inert-change {
entry 0%,
exit 100% {
interactivity: inert;
}
entry 1%,
exit 99% {
interactivity: auto;
}
}
See the animation-range
reference page for an explanation of the position values.
Result
Scroll the unordered list horizontally to see the pagination effect — each page snaps into view. Try tabbing between the links and the buttons; you'll find that only the ones on-screen are interactive and can be tabbed to.
Accessibility concerns
Consider accessibility carefully when making elements inert. By default, there is no visual way to tell whether or not an element or its subtree is inert. As a web developer, it is your responsibility to clearly indicate the content parts that are active and those that are inert.
While providing visual and non-visual cues about content inertness, also remember that the visual viewport may contain only sections of content. Users may be zoomed in to a small section of content, or users may not be able to view the content at all. Inert sections not being obviously inert can lead to frustration and bad user experience.
Specifications
Specification |
---|
CSS Basic User Interface Module Level 4> # propdef-interactivity> |
Browser compatibility
Loading…
See also
- HTML
inert
attribute HTMLElement.inert