The CSS pointer-events property
The CSS pointer-events property decides whether an element reacts to mouse and touch. The default is auto; pointer-events: none makes the element ignore clicks entirely, so they pass through to whatever is behind it. It is handy for click-through overlays and decorative layers, but it does not disable keyboard access on its own.
Overview
pointer-events turns an element's responsiveness to the pointer on or off. With the default auto, it behaves normally. Hovers, clicks and taps all register. Set it to none and the element becomes transparent to the pointer: clicks sail straight through to whatever sits underneath.
That click-through behavior is the whole point. A decorative overlay, a gradient scrim, a tooltip arrow or a watermark can sit on top of interactive content without stealing its clicks. pointer-events: none lets the user interact with what is behind. It is also a quick way to make a disabled-looking control unclickable while you style it.
Two cautions, though. It is a blunt instrument: none disables all pointer interaction, including hovers and any children. And, importantly, it does not remove an element from the keyboard tab order or from assistive technology by itself, so it is not a substitute for the disabled attribute on a real control. More on that below.
Syntax
/* let clicks pass through an overlay */
.overlay {
pointer-events: none;
}
Values
The pointer-events property accepts the values below. Every property also accepts the CSS-wide keywords inherit, initial, revert and unset.
| Value | Description |
|---|---|
auto |
The element responds to mouse and touch as normal. The default. |
none |
The element ignores pointer events; clicks pass through to what is behind it. |
Example
<style>
.wrap { position: relative; font: 600 14px system-ui, sans-serif; }
.wrap button { padding: 14px 22px; border: 0; border-radius: 8px; background: #1c7ce9; color: #fff; cursor: pointer; }
.scrim { position: absolute; inset: 0; background: linear-gradient(transparent, rgb(28 124 233 / 0.15)); border-radius: 8px; pointer-events: none; }
</style>
<div class="wrap">
<button onclick="this.textContent='Clicked through the scrim!'">Click me</button>
<div class="scrim"></div>
</div>
Best practices
- Use
pointer-events: noneon decorative overlays, scrims and tooltip arrows so they do not intercept clicks meant for the content beneath. - Re-enable interaction on specific children with
pointer-events: autowhen only part of an overlay should be clickable. - Do not rely on it alone to disable a control; it leaves the element focusable and announced. Use the
disabledattribute on real form controls. - Remember it disables hover too, so any title or hover styling on the element stops working while it is set to none.
Accessibility
pointer-events: none only affects the pointer. A keyboard user can still Tab to the element, and a screen reader still announces it, so using it alone to "disable" a button is misleading. It looks unclickable with a mouse but remains reachable and operable by other means.
For a genuinely disabled control, use the native disabled attribute on a <button> or input, which removes it from the tab order and marks it disabled for assistive technology, or manage aria-disabled and focus deliberately. Keep pointer-events: none for what it is good at: non-interactive decorative layers.
Frequently asked questions
What does pointer-events: none do?
How do I make a div click-through in CSS?
pointer-events: none on it. Clicks then reach the elements underneath. Re-enable specific children with pointer-events: auto if needed.Does pointer-events: none disable keyboard access?
How do I properly disable a button?
disabled attribute on the <button>. That removes it from interaction and the tab order, which pointer-events: none alone does not do.