When to Use user-select: none (and When It's a UX/Accessibility Trap)
You’ve probably reached for user-select: none to stop text from highlighting when someone clicks a button. It feels like a small, harmless polish. But apply it in the wrong place and you’ve quietly broken the experience for a meaningful slice of your users. Here’s how to use it well.
Key Takeaways
- The
user-selectCSS property controls whether users can select text in an element, withnone,text,all, andautoas its main values. - Applying
user-select: noneto a parent causes all descendants to inherit it, making broad application risky. - Legitimate uses include buttons, drag-and-drop interfaces, toolbars, and decorative elements that would clutter clipboard copies.
- Disabling selection on content areas, articles, error messages, or code snippets harms users who rely on copying, translating, or highlighting text.
user-select: noneoffers zero content protection — anyone can bypass it through DevTools in seconds.
What the CSS user-select Property Actually Does
The user-select CSS property controls whether a user can select text in an element. The most common values you’ll encounter:
none— prevents text selection entirelytext— explicitly allows selection (useful to override an inheritednone)all— one click selects the entire element’s contentauto— the default, which resolves based on the element’s context and its parent’s computed value
When you apply user-select: none to a parent, it effectively prevents selection in descendants unless you explicitly override them with user-select: text. That behavior is easy to forget and easy to break things with.
When Disabling Text Selection CSS Makes Sense
There are genuinely good reasons to reach for user-select: none. The key is keeping it narrow.
Buttons and button-like links. Native <button> elements aren’t selectable by default. But <a> tags styled as buttons are, and accidental text selection during a click-drag is a real friction point. Applying user-select: none here is reasonable.
.btn {
user-select: none;
cursor: pointer;
}
Drag-and-drop interfaces and sliders. When users interact by dragging, text selection competes directly with the gesture. Disabling it on the draggable element prevents the browser from hijacking the interaction.
Tab bars, toolbars, and interactive UI chrome. Labels on tabs or icon buttons don’t need to be selectable. Applying user-select: none to these components keeps interactions clean.
Excluding decorative or non-content elements from clipboard copies. If an emoji, ad unit, or aside would pollute a user’s copy, wrapping it in user-select: none keeps the selection clean without disabling it broadly.
Discover how at OpenReplay.com.
Where user-select: none Becomes a UX and Accessibility Trap
This is where most articles stop short. Disabling text selection in the wrong context causes real harm.
Content areas. Articles, documentation, error messages, form results, and code snippets should always be selectable. Users copy text to search it, translate it, paste it into tools, or share it. Blocking that is friction with no upside.
Translation and text-to-speech tools. Browser extensions like Google Translate and standalone text-to-speech tools operate on selected text. Users with cognitive disabilities, dyslexia, or limited English proficiency depend on these workflows. user-select: none silently breaks them.
People who read by highlighting. Many users — including those with ADHD or working memory challenges — track their reading position by selecting text as they go. Removing that ability on content-heavy pages is a genuine accessibility barrier.
Find-in-page behavior. While Ctrl+F / Cmd+F still works regardless of user-select, some browser environments and assistive tools interact with selection state in ways that aren’t fully consistent across implementations.
Important: Screen readers like JAWS and NVDA parse the DOM directly and don’t rely on text selection, so
user-select: nonedoesn’t affect them. The accessibility risks lie with sighted users who depend on selection-based workflows.
user-select: none Is Not a Content Protection Mechanism
It’s worth saying plainly: user-select: none does not protect your content. Anyone can open DevTools, disable the CSS, and copy freely in seconds. Treating it as a security measure trades real user harm for zero actual protection.
A Practical Rule for user-select Accessibility
Apply user-select: none only to interactive controls, not to content. If an element’s purpose is to be read, copied, or referenced, leave selection alone.
/* Safe: interactive UI elements */
button,
[role="tab"],
.drag-handle {
user-select: none;
}
/* Never do this to content */
article,
p,
code,
.error-message {
/* user-select: none — don't. */
}
One more note on browser compatibility: older implementations required vendor prefixes (-webkit-user-select, -moz-user-select). Modern browsers handle the unprefixed property well, but behavior isn’t perfectly uniform across all environments, so test rather than assume. Vendor-prefixed versions like -webkit-user-select should only be added when supporting older environments, as prefixed behavior may differ from the standard property.
Conclusion
user-select: none is a useful tool for interactive UI components where accidental selection creates friction. It becomes a trap when applied to anything users need to read, copy, or reference. Keep the scope narrow, never use it as a content lock, and you’ll avoid the most common mistakes.
FAQs
No. Screen readers like JAWS and NVDA read directly from the DOM and do not depend on text selection. The property only affects visual text selection behavior for sighted users. The real accessibility concern is with users who rely on selecting text for translation, text-to-speech tools, or reading by highlighting.
No. It is a CSS property, not a security mechanism. Anyone can open browser DevTools, disable or override the rule, and copy the text freely. Using it as a content protection measure provides no real safeguard while actively harming legitimate users who need to select text.
In most cases, the unprefixed user-select property works across all modern browsers. However, some older browsers or specific WebKit-based environments may still require the -webkit-user-select prefix. If you need to support legacy browsers, include the prefix as a fallback and test across your target environments.
No. Applying it broadly to the body or a top-level container disables text selection for all content, including paragraphs, headings, and code blocks. This breaks copying, translation tools, and highlight-based reading. Limit it strictly to interactive elements like buttons, tabs, and drag handles.
Truly understand users experience
See every user interaction, feel every frustration and track all hesitations with OpenReplay — the open-source digital experience platform. It can be self-hosted in minutes, giving you complete control over your customer data. . Check our GitHub repo and join the thousands of developers in our community..