CSS user-select: none: How to Prevent Text Selection
The CSS user-select: none property prevents users from
highlighting and selecting text within an interface by disabling the
browser's default text selection behavior on targeted elements. This
article explains how the property functions at the browser level, why it
is essential for modern UI components like buttons and navigational
controls, how inheritance affects nested elements, and the usability
considerations you must keep in mind when applying it.
How user-select: none Works
When a user clicks and drags over text, or double-clicks a word, modern browsers initiate an internal selection mechanism managed by the DOM Selection API. This mechanism generates a visible selection highlight across text nodes and prepares the highlighted text for clipboard operations.
Applying user-select: none instructs the rendering
engine to exclude the designated element and its text nodes from this
selection mechanism. As a result:
- Mouse drag events over the element will not create a highlight bounding box.
- Double-clicking or triple-clicking text will not highlight the word or paragraph.
- "Select All" (
Ctrl+AorCmd+A) commands bypass elements styled withuser-select: none.
The text remains fully rendered in the DOM, meaning screen readers can still read it, and search engine crawlers can still index it. The property strictly alters visual highlighting and selection via the user interface.
Implementation on UI Components
Interactive elements in web applications—such as buttons, tabs, accordions, and drag-and-drop handles—often suffer from accidental text highlighting during fast or repeated clicking. Disabling selection preserves an application-like feel.
.button,
.draggable-item,
.carousel-nav {
-webkit-user-select: none; /* Safari */
user-select: none; /* Standard syntax */
}Vendor prefixes, primarily -webkit-user-select, are
still recommended to ensure cross-browser compatibility, especially for
older versions of Safari and iOS WebKit.
Inheritance and Overriding
The user-select property is inherited by default. If you
set user-select: none on a parent component, every child
element within that component will also have text selection
disabled.
If a component contains editable fields or content that users should be allowed to copy (such as a code snippet inside a non-selectable card), you must explicitly restore selection on the child element:
.card {
user-select: none;
}
.card-code-output {
user-select: text; /* Restores standard text selection */
}The available values for user-select include:
none: Prevents all selection on the element and its sub-elements.auto: Computes to the default selection behavior of the browser.text: Allows the user to select text normally.all: Selects the entire element's content with a single click.
Best Practices and Usability
While user-select: none improves the visual stability of
interactive controls, it should be used conservatively:
- Target only controls: Limit the rule to UI elements like buttons, icon labels, sliders, and navigation menus.
- Avoid content containers: Never apply
user-select: noneto long-form text, error messages, transactional data, or documentation. Preventing users from copying information they need creates significant frustration. - Not a security measure:
user-select: nonedoes not protect content from being scraped or copied. Users can still inspect the page source, view the DOM tree in developer tools, or disable CSS entirely to copy the text.