{
  "id": 11674450,
  "title": "I Wanted Rounded Text Selection for Years. Here's How I Finally Built It in Angular (With AI Help)",
  "url": "https://urgent.news/2026/10/03/i-wanted-rounded-text-selection-for-years-heres-how-i-finally-built",
  "topic": "tech",
  "section": "Tech",
  "published": "2026-10-03T11:53:36.000Z",
  "source": {
    "name": "Dev.to",
    "slug": "dev-to",
    "url": "https://dev.to/gregor123456/i-wanted-rounded-text-selection-for-years-heres-how-i-finally-built-it-in-angular-with-ai-help-40a"
  },
  "original_language": "en",
  "account": "For years, a visual element that I had desired to incorporate into my websites was rounded text selection. Unlike rounded backgrounds or predefined highlighted spans, this refers to the actual selection that appears when using a cursor to drag across text, akin to the selection appearance found in editors like Visual Studio Code. While the concept seemed deceptively simple, implementing it proved challenging after multiple unsuccessful attempts over the years. After exploring various online discussions and even utilizing ChatGPT, I ultimately developed a functional implementation.\n\nThe primary challenge lies in the limitations of CSS. Customizing text selection is relatively straightforward using the ::selection pseudo-element, such as setting background colors and text colors. However, applying a border-radius to the ::selection pseudo-element is not supported by browsers. This limitation led me to search for alternative solutions.\n\nOne relevant Stack Overflow question from 2014 provided some guidance on applying rounded borders to selection highlights. The accepted answer by user coma proposed a solution involving JavaScript, jQuery, Rangy library, and individual span elements. While this approach worked, it required significant modification of the website's existing text structure, which was not ideal. My goal was to create a reusable implementation that could automatically handle dynamically generated Angular content without the need for additional markup.\n\nAfter refining the idea with assistance from ChatGPT, I discovered a better approach involving Angular directives and SVG elements. Instead of altering the original HTML, this directive leverages the browser's native selection geometry to generate a decorative SVG overlay. The process entails listening for changes to the user's text selection, retrieving the native selection using the Selection API, identifying selected text nodes using TreeWalker, calculating their positions using the Range API, merging adjacent fragments belonging to the same visual line, generating rounded SVG paths, and hiding the native selection background when the custom overlay is ready.\n\nThe key advantage of this implementation is that it does not alter the original DOM. Instead of wrapping each character in additional elements, the directive creates an SVG representation of the selected text. The directive retrieves the selection geometry using the browser's native Selection API, identifies the relevant text nodes, creates individual ranges, retrieves their coordinates using the Range API, merges adjacent fragments belonging to the same visual line, and generates rounded SVG paths, including connecting segments between nearby lines.\n\nUpon collecting the geometry, adjacent fragments are merged and converted into SVG paths. The corners of the rounded highlights are created using quadratic Bézier curves, with additional connecting segments where necessary. By combining the resulting geometry into SVG paths grouped by selection color, a more cohesive selection appearance is achieved, avoiding the dark overlapping areas that separate highlight elements can create.\n\nTo make this implementation global across Angular components, I utilized Angular's hostDirectives mechanism. In the root component, I imported the RoundedSelectionDirective and added it to the hostDirectives array. This ensures that the directive attaches to the application's root element and handles ordinary text within it. Additionally, the directive employs MutationObserver and ResizeObserver to respond to relevant content and layout changes. To optimize performance, selection updates are scheduled using requestAnimationFrame, preventing unnecessary repeated calculations within the same animation frame.\n\nThe SVG overlay is purely decorative and does not interfere with mouse interactions. The simplified styling for the overlay involves setting a custom background color and ensuring that the native selection background and text color are overridden. Additionally, a class (.rounded-selection-overlay) is defined to position the overlay fixedly within the viewport.",
  "summary": "There is one incredibly small visual detail I've wanted to implement on my websites for years. Rounded text selection. Not rounded text backgrounds. Not predefined highlighted spans. I mean the actual selection you see when dragging your cursor across text, similar to the selection appearance found in editors such as Visual Studio Code. It sounds ridiculously simple. It wasn't. After years of…",
  "key_points": [
    "Rounded text selection desired for years, finally implemented in Angular with AI help",
    "Challenge: CSS cannot apply border-radius to ::selection pseudo-element",
    "Solution: Angular directive using SVG overlay, native Selection API, Range API, MutationObserver"
  ],
  "editors_take": null,
  "illustration": null,
  "coverage": {
    "outlets": 1,
    "also_reported_by": []
  },
  "ai_generated": true,
  "disclaimer": "Summaries, key points and the editor’s take are written by software from other outlets’ reporting and may contain errors — always check the linked original."
}