CSS user-select Property
The user-select property controls whether or not a user is allowed to highlight and select text within an element. It is commonly used to make UI components feel more like native applications.
| auto | The browser determines the selection behavior based on its default rules for that specific element type. |
| none | The element and its sub-elements cannot be selected by the user highlighting text. |
| text | The user can select the text within the element using the standard cursor selection. |
| all | The entire contents of the element are selected with a single click rather than a drag. |
| contain | Allows selection to start within the element but ensures the selection range stays within the bounds of that element. |
Code Examples
This basic example shows how to prevent a user from selecting text in a specific div using the none value.
<style>
.unselectable {
user-select: none;
background-color: #f0f0f0;
padding: 10px;
border: 1px solid #cccccc;
}
</style>
<div class="unselectable">Try to highlight this text. You cannot do it because of user-select: none.</div>This advanced example uses user-select: all to allow a user to select an entire API key with a single click, combined with a JavaScript event listener to update the UI.
<style>
.code-box {
background-color: #222222;
color: #ffffff;
padding: 15px;
font-family: monospace;
user-select: all;
cursor: pointer;
}
.status {
margin-top: 10px;
color: #333333;
}
</style>
<div class="code-box" id="api-key">SELECT_ME_WITH_ONE_CLICK_12345</div>
<div class="status" id="msg">Click the box to see how user-select: "all" works.</div>
<script>
const box = document.getElementById("api-key");
box.addEventListener("click", () => {
document.getElementById("msg").innerText = "The entire string was selected automatically.";
box.style.backgroundColor = "#444444";
});
</script>Pro Tip
If you are building a mobile web app, you can apply user-select: "none" to the entire body to stop that annoying selection overlay from appearing when people tap around, then simply re-enable user-select: "text" on the specific containers where you actually have readable content.
Deep Dive
When you apply user-select, you are telling the browser how to handle the selection layer of the UI. Think of it like a sheet of plexiglass over a document; setting it to "none" prevents the user from reaching the text with their digital highlighter. If you set it to "all", the browser treats the entire block as a single unit, making it impossible to select just one character—it is the whole thing or nothing. This is handled at the browser's presentation layer, meaning the text is still in the DOM and still accessible to search engines or screen readers, even if the mouse cannot grab it.
Best Practices
Use user-select: "none" on interactive elements like buttons, tabs, or navigation bars where rapid clicking might accidentally trigger an ugly blue text highlight. Use user-select: "all" for text that users frequently need to copy in full, such as code snippets, API keys, or discount codes. This makes the user's life easier by saving them the effort of dragging the mouse precisely from start to finish.
Common Pitfalls
A common mistake is thinking that user-select: "none" is a security feature to prevent people from stealing your content. It is not. Anyone can still view the source code or use developer tools to copy your text. Also, remember that for a long time this property required vendor prefixes like -webkit- or -moz- to work, so if you are supporting older browsers, you still need those prefixed versions in your CSS.
Accessibility
Overusing user-select: "none" can be a nightmare for accessibility. Many users rely on text selection to use built-in translation tools, screen readers, or simply to help them keep their place while reading. Never disable selection on actual content or articles; only use it on decorative or functional UI elements that do not contain information the user might need to store or share.
Dev Data Table: user-select property
| default | auto |
| animatable | no |
| inherited | no |
| experimental | no |
| year_intro | 2000 |
| year_standard | 2020 |
| js_syntax_1 | document.getElementById("myElement").style.userSelect = "none"; |
| js_syntax_2 | document.getElementById("myElement").style.setProperty("user-select", "none"); |
| js_note | When using JavaScript to manipulate this property, ensure you use the camelCase version userSelect or the setProperty method to maintain compatibility. |
| browsers | { "Chrome": 54, "Edge": 12, "Firefox": 69, "Safari": 3, "Opera": 41, "Chrome Android": 54, "Safari on iOS": 3, "Samsung Internet": 6, "Opera Mobile": 41 } |