🧊

CSSの`::highlight()`が、Firefox 140に実装されてた

全俺が待望のやつ。

CSS selector: ::highlight() | Can I use… Support tables for HTML5, CSS3, etc https://caniuse.com/mdn-css_selectors_highlight

ただしフルサポートではなく、text-decorationtext-shadowはまだ効かないとのこと。

CSS Custom Highlight API

CSS Custom Highlight API - Web APIs | MDN https://developer.mozilla.org/en-US/docs/Web/API/CSS_Custom_Highlight_API

何ができるかというと、任意の部分のRangeさえ用意すれば、そこにCSSを適用できるようになる。

MDNのページにデモが埋まってるけど、ページ内検索の結果みたいなものを、“DOMを変更することなく”ハイライトできちゃう。

コード例

つい最近に書いたコードで、まさにpre要素の内の特定文字列にハイライトを付けるもの。

SvelteのAttachmentで書いてるけど、どこでも流用できるはず。

import type { Attachment } from "svelte/attachments";

const HIGHLIGHT_SELECTOR = "error-code";

// CSS Custom Highlight API attachment for error code highlighting
export function highlightErrorCode(errorCode: string): Attachment {
  return (element: Element) => {
    const textNode = element.firstChild;
    if (!textNode || textNode.nodeType !== Node.TEXT_NODE) return;

    const text = textNode.textContent;
    if (!text) return;

    const searchTerm = `TS${errorCode}`;

    CSS.highlights.clear();

    const ranges: Range[] = [];
    let startIndex = 0;
    while (true) {
      const index = text.indexOf(searchTerm, startIndex);
      if (index === -1) break;

      const range = document.createRange();
      range.setStart(textNode, index);
      range.setEnd(textNode, index + searchTerm.length);
      ranges.push(range);

      startIndex = index + searchTerm.length;
    }

    if (ranges.length > 0) {
      const highlight = new Highlight(...ranges);
      CSS.highlights.set(HIGHLIGHT_SELECTOR, highlight);
    }

    return () => CSS.highlights.clear();
  };
}

TS1234のようなエラーコード部分に、error-codeというハイライトを指定してる。

あとはCSS側でこう書くだけ。

::highlight(error-code) {
  background-color: var(--highlight-bg);
}

便利だ・・・。

https://github.com/leaysgur/tsc-error_diagnostic_codes-viewer/

Syntaxハイライトもできる

andreruffert/syntax-highlight-element: 👓 Syntax Highlighting using the CSS Custom Highlight API https://github.com/andreruffert/syntax-highlight-element

あの頃は前衛的すぎるぜ・・・って思ってたこういうライブラリも、いつの間にか実用的になってきたってことかね。