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.

selector { user-select: value; }
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 }
results render here...