As an experienced full-stack developer, I often need to make certain text unselectable on websites for security, privacy, or design reasons.

Whether it‘s sensitive personal data, credit card numbers, code snippets, or simply visually-focused text elements that shouldn‘t be highlighted, disabling text selection is a common requirement.

Fortunately, CSS provides simple and flexible ways to make text unselectable with broad browser support. In this comprehensive guide, I’ll share professional techniques and best practices for preventing text selection.

Technical Primer on How Text Selection Works

Before looking at the code, it helps to understand what’s happening technically when users select text on a web page.

When text is highlighted, the browser renders a transparent overlay dividing the selected portion from the rest. This overlay fills with the highlight color (typically pale blue), allowing the selected text to stand out visually.

Several CSS properties control this selection overlay and color:

::selection {
  color: #fff;
  background: #3399ff;
}

So to make text unselectable, the core idea is removing that visual highlight when users select it. This can be achieved by:

  1. Styling the selection overlay differently
  2. Disabling the ability to select text altogether

The user-select property and ::selection pseudo-element give us these capabilities.

Now let’s walk through them in detail, including advanced usage.

1. Using the user-select Property

The user-select CSS property determines if text can be selected or not.

For example, to disable text selection:

p {
  user-select: none;
}

User highlighting is now blocked on all <p> elements.

user-select accepts a few different values:

.auto {
   user-select: auto; /* Default browser behavior */
}

.text {
  user-select: text; /* Text can be selected */  
}

.none {
  user-select: none; /* Text cannot be selected */
}

.all {
  user-select: all; /* Text and sub-elements can be selected */
}

This gives you precise control over text selection behavior.

Browser Support

The user-select property has excellent cross-browser support:

Browser Version
Chrome 1+
Edge 12+
Firefox 3.5+
Safari 3.1+
Opera 9+
iOS Safari 3.2+
Android Browser 2.1+
IE 10+

So you can use it quite safely without worrying about legacy browser issues nowadays.

Use Cases for Disabling Text Selection

There are many reasons why you may want to disable text selection, for example:

  • Masking credit card or personal identity information like SSNs
  • Preventing users from copying code snippets easily
  • Creating text-heavy designs where highlighting would be visually disruptive
  • Highlighting key text elements like headings by preventing selection

Here are some real-world examples:

Site Unselectable Text Elements
Banking & Finance Account numbers, credit cards, SSN, passwords
News & Media Article titles, captions, citations
Software Docs Code blocks, credentials
Legal Sensitive clauses, citations

Of course, you’ll want normal body text to remain selectable so users can copy it. Use good judgment when applying user-select: none;.

Allow Selection on Child Elements

A neat trick with user-select is allowing text selection on child elements even when it’s disabled on the parent:

.parent {
   user-select: none; 
}

.parent .child {
  user-select: text;
}

So the text remains selectable on .child elements inside .parent.

For example:

<div class="parent">
  <p>Non-selectable parent text</p>

  <div class="child">
    <p>But child text is selectable</p>
  </div>
</div>

This granular control over selection behavior is quite useful in some cases.

2. Using the ::selection Pseudo-Element

An alternative approach is styling the selection itself using the ::selection pseudo-element.

For example, this removes the highlight color when text is selected:

::selection {
  background: transparent;
}  

While users can still technically select the text, there will be no visual highlight effect.

Compatibility Notes

::selection has excellent browser support:

Browser Version
Chrome 1+
Edge 12+
Firefox 2+
Safari 3.1+
Opera 9+
IE 9+

It’s also supported on all major mobile and tablet devices. So you don’t need to worry much about cross-browser issues.

Do note that Firefox doesn’t allow styling across element boundaries:

❌ This won’t work:

p::selection {
  color: #fff  
}

⚠️ But this is okay:

::selection {
  color: #fff
}

So with Firefox, apply ::selection styles globally rather than on specific elements.

Styling Capabilities

These properties can be used with ::selection:

  • color
  • background-color
  • cursor
  • outline

That’s more limited than normal CSS, but playing with color and transparency gives you good control over selected text appearance.

Some examples:

/* Make selected text transparent */ 
::selection {
  background: transparent; 
}

/* Remove selection outline */
::selection {
  outline: none;
}

/* Change text and background colors */  
::selection {
  color: black;
  background: lightgrey;
}

Get creative with different styles and effects!

Security Considerations

One downside of ::selection compared to user-select is that text remains selectable and copyable even if the visual highlight is removed.

So for security use cases, combine ::selection styles with user-select: none to also disable selection, along with JavaScript validation for maximal protection.

Unselectable Text Security Best Practices

When dealing with sensitive text that shouldn’t be copied, some additional precautions are recommended:

Use JavaScript Validation

While CSS handles presentation, JavaScript actively prevents unauthorized actions like highlighting protected text or disabling right-clicks.

For example:

function disableSelect(targetElement) {

  targetElement.onselectstart = function() { 
    return false; 
  };

  targetElement.style.MozUserSelect = "none";

  targetElement.style.webkitUserSelect = "none";

}

This offers an extra layer of protection that CSS alone may not provide.

Monitor Clipboard Access

Watch for copy/cut events to prevent unauthorized copying attempts:

document.addEventListener(‘copy‘, function(event) {
    event.preventDefault(); 
}); 

Use Session Storage

Rather than displaying protected info directly in the DOM, use sessionStorage to keep it in-memory client-side and then render securely with JS.

Limit Internal Access

Restrict which users and roles can view protected text in the first place through authentication and authorization.

Transport via HTTPS

Always transfer sensitive data over secure HTTPS connections to prevent man-in-the-middle attacks.

So in high-risk scenarios, utilize a blend of methods for defense-in-depth.

Additional Tips and Tricks

Here are some more tips from my many years disabling text selection professionally:

Change Cursor Style

Subtly indicate unselectable text using the cursor property:

.unselectable {
  cursor: not-allowed;
  user-select: none;
}

Combine user-select + ::selection

Using both techniques together gives you optimal cross-browser support and more styling options:

p {
  user-select: none; /* Disable selection */
}

p::selection {
  background: transparent; /* Hide highlight */
}

Prevent Form Interactions

Make unselectable text non-focusable and non-submittable for forms:

.unselectable {
  user-select: none;
  pointer-events: none;
}

This disables mouse events.

Use Background Clip

Here’s another clever trick – hide text in the selection overlay while keeping it visible otherwise:

::selection {
  background: white;
  -webkit-background-clip: text;  
          background-clip: text;
  color: rgba(0,0,0,0);
}

The text vanishes when highlighted!

Let me know if you have any other clever CSS selection techniques.

Unselectability Myths & Misconceptions

Having disabled text selection across hundreds of sites and apps, there are a few common myths worth dispelling:

Myth: It creates huge accessibility issues

Reality: By only applying to small portions of text, most pages remain keyboard/screenreader friendly.

Myth: Mobile devices won’t respect the rules

Reality: iOS, Android, etc fully support both user-select and ::selection.

Myth: There are major browser compatibility problems

Reality: All modern browsers have excellent support, with fallbacks available.

Myth: It completely blocks copying

Reality: Text can still be accessed by disabling CSS, though extra measures like JS help.

Myth: It’s annoying for users

Reality: When applied judiciously to small sections, most users won’t care or even notice.

Hopefully this reassures anyone hesitant about unselectable text thinking it has major downsides. With mindful usage, it’s quite safe and low-impact.

Now let’s round up everything we’ve covered…

Key Takeaways

Here are the core highlights:

  • The user-select: none property disables text selection
  • The ::selection pseudo-element styles the highlight effect
  • Browser support is excellent overall
  • Balance security without harming DX excessively
  • Combine CSS with JS validation for high-risk scenarios
  • Carefully apply to small sections of text only

Making text unselectable is quite straightforward with native CSS capabilities.

While no approach is 100% bulletproof, user-select and ::selection give you powerful options to disable – or visually hide – selectable text when needed.

So don’t be afraid to leverage them on your sites and apps!

I hope this guide has demystified the process and given you ideas for your own projects. Let me know if you have any other questions!

Similar Posts