<div class="article-container">
<h2>Select any text below</h2>
<p class="article-text">
The future of web design focuses heavily on highly polished micro-interactions. When you build interfaces that respond naturally to user intent, you create an experience that feels alive. Highlighting text is a core browser feature, but enhancing it with a native-feeling context menu elevates the entire application to an enterprise standard.
</p>
</div>
<div class="selection-toolbar" id="text-toolbar">
<button class="tool-action">Highlight</button>
<button class="tool-action">Share</button>
<button class="tool-action">Copy</button>
</div>
*, *::before, *::after {
box-sizing: border-box;
}
body {
font-family: system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
margin: 0;
background: #f8fafc;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
padding: 20px;
}
.article-container {
max-width: 600px;
background: #ffffff;
padding: 50px;
border-radius: 20px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.05);
}
.article-container h2 {
margin: 0 0 20px 0;
color: #0f172a;
}
.article-text {
font-size: 1.125rem;
line-height: 1.8;
color: #334155;
margin: 0;
}
::selection {
background: #dbeafe;
color: #1e3a8a;
}
.selection-toolbar {
position: absolute;
background: #0f172a;
padding: 6px;
border-radius: 12px;
display: flex;
gap: 4px;
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2);
z-index: 1000;
/* Start hidden safely */
opacity: 0;
visibility: hidden;
transform: translateY(10px) translateX(-50%);
transition: opacity 0.2s, transform 0.2s, visibility 0.2s;
}
.selection-toolbar.is-visible {
opacity: 1;
visibility: visible;
transform: translateY(0) translateX(-50%);
}
.selection-toolbar::after {
content: "";
position: absolute;
top: 100%;
left: 50%;
transform: translateX(-50%);
border-width: 6px;
border-style: solid;
border-color: #0f172a transparent transparent transparent;
}
.tool-action {
background: transparent;
color: #f8fafc;
border: none;
padding: 8px 16px;
border-radius: 8px;
font-size: 0.9rem;
font-weight: 500;
cursor: pointer;
transition: background 0.2s;
}
.tool-action:hover {
background: #334155;
}
const toolbar = document.getElementById("text-toolbar");
document.addEventListener("mouseup", function() {
/* Using native window selection safely */
const selection = window.getSelection();
const text = selection.toString().trim();
if (text.length > 0) {
/* Get precise coordinates of the highlighted text */
const range = selection.getRangeAt(0);
const rect = range.getBoundingClientRect();
/* Position the toolbar exactly above the text center */
const top = rect.top + window.scrollY - 50;
const left = rect.left + window.scrollX + (rect.width / 2);
toolbar.style.top = top + "px";
toolbar.style.left = left + "px";
toolbar.classList.add("is-visible");
} else {
toolbar.classList.remove("is-visible");
}
});
/* Hide when user clicks away */
document.addEventListener("mousedown", function(e) {
if (e.target !== toolbar && !toolbar.contains(e.target)) {
toolbar.classList.remove("is-visible");
}
});