If your church has a sermon library on its website, there is a small, tedious problem you have almost certainly run into. Someone wants Bible references in a transcript to stand out. Or search results to be visibly marked. Or a study guide to underline the phrases the small group will discuss on Wednesday. The way this has always been done is to wrap those phrases in extra HTML tags — a <mark> here, a <span class="verse"> there — and hope nothing breaks.
Something almost always breaks. Copy and paste picks up the extra markup. Screen readers read "mark, John 3 16, end mark" out loud. Search functions match the raw text but not the highlighted version. And the moment someone edits a transcript, the tags drift out of place. There is now a better way, and as of this spring it works in every mainstream browser.
What Actually Landed
The CSS Custom Highlight API lets your website point at ranges of text — a verse citation, a matched search phrase, a passage the pastor wanted to emphasize — and style them, without adding a single tag to the underlying HTML.
The transcript in your CMS stays clean text. The visual highlight lives entirely in a stylesheet and a small piece of JavaScript that says, in effect, "these character positions, treat as a highlight." When the visitor copies text, they get the words with no formatting noise. When a screen reader reads the passage, it reads the passage. When your search feature grepps the transcript, it finds the words because the words are still just words.
Firefox shipped support in June of last year, which was the last piece needed for Baseline. As of March 2026, the API works reliably in Chrome, Edge, Safari, and Firefox on desktop and mobile.
What It Looks Like
The whole thing is smaller than you would expect. In CSS, you name a highlight and style it like you would a ::selection:
::highlight(bible-verse) {
background: color-mix(in oklab, gold 25%, transparent);
text-decoration: underline dotted;
text-decoration-color: currentColor;
}
::highlight(search-match) {
background: color-mix(in oklab, oklch(85% 0.15 90) 60%, transparent);
}
In JavaScript, you tell the browser which ranges belong to which highlight:
const transcript = document.querySelector('.sermon-transcript');
const verseHighlight = new Highlight();
// findRanges returns Range objects for each verse citation
for (const range of findRanges(transcript, /\b\d?\s?[A-Z][a-z]+\s\d+:\d+(-\d+)?/g)) {
verseHighlight.add(range);
}
CSS.highlights.set('bible-verse', verseHighlight);
That is the whole architecture. A regular expression, a set of ranges, one register call. The DOM is untouched. If JavaScript fails to load, the visitor still gets the full transcript — just without the visual emphasis, which is exactly the right fallback.
Why This Matters For A Sermon Library
Most church websites underuse their sermon archive. Sermons get posted with a title, a date, maybe a scripture reference in the metadata, and a media player. The transcript, if it exists at all, sits in a wall of text nobody quite finishes.
A few small additions change that.
Bible references become navigable. Every "Romans 8:28" in the transcript can carry a subtle underline that signals "this is a scripture," and clicking one can open the passage in the reader's preferred translation. The reference is not a hardcoded link inside the transcript — it is a highlight applied on top of it, generated automatically from a regex. New sermons get the same treatment without anyone re-tagging anything.
Search results become obvious. When a visitor searches your sermon library for "sabbath rest," the results page can show a snippet with every match glowing, without inserting <mark> tags into archived content. If the search library changes next year, the transcripts do not need to be reprocessed.
Study guides can layer on top of a sermon. A small group leader can share a version of a sermon page with the week's discussion phrases highlighted, using a simple query parameter that adds ranges to a highlight registry. No forked content, no duplicated transcript. The source of truth stays in one place.
Screen reader users are treated with respect. Because the highlights live outside the DOM, assistive technology reads the transcript the way a human would — without the running commentary of "start emphasis, John 3 16, end emphasis" every third sentence.
The One Gotcha
The API styles character ranges, not blocks. That means you can control color, background, text-decoration, and a few related properties, but not padding, border-radius, or box-shadow. If you want a "verse of the week" callout that looks like a card, that still calls for a real HTML element.
Think of Custom Highlights as the right tool for anything that could reasonably be a highlighter pen — background wash, an underline, a color shift. Anything that needs a container is a different tool.
The other note is progressive enhancement. Check for support once — if (CSS.highlights) — and only run the highlighter if the API exists. On older browsers, the visitor sees the plain transcript and misses nothing but the polish. That is the whole point.
Where To Start
If your church has a sermon library, this is a genuinely small change with genuinely large payoff. Two hours of a developer's time to add automatic scripture highlighting to every transcript in your archive. A few more to wire it into search. The result is a sermon page that respects the text, respects the reader, and gets out of the way.
If you would like a set of fresh eyes on your sermon library — what to highlight, what to link, what to leave alone — we would be glad to take a look. Ministry websites earn their trust in small details like this, and the details are finally getting easier to get right.

