Vanilla Breeze

text-reader

Text-to-speech reader with word-level highlighting. Uses the Web Speech API for synthesis and the CSS Custom Highlight API for word tracking.

Overview

The <text-reader> component attaches a text-to-speech control bar to any element. It uses the Web Speech API for synthesis and the CSS Custom Highlight API for real-time word tracking. Progressive enhancement — the component hides itself if the browser lacks speechSynthesis.

Attributes

AttributeTypeDefaultDescription
forstringID of the element to read. Required.
variantstringSet to "icon" for a compact speaker icon with floating mini-toolbar
selectorsstringp,liComma-separated CSS selectors for text extraction within the target
speednumber1Initial playback rate (0.5–2)
voicestringvoiceURI to pre-select on load
highlightstringSet to "false" to disable word highlighting
scrollstringSet to "false" to disable auto-scroll to active word
label-playstringPlayAccessible label for the play button
label-pausestringPauseAccessible label for the pause button
label-stopstringStopAccessible label for the stop button

Observed Attributes

These attributes are reactive — changing them at runtime triggers an update:

AttributeBehavior on Change
speedRestarts speech from the current word at the new rate
voiceRestarts speech from the current word with the new voice
forStops current speech, re-resolves target element

JavaScript API

Method / PropertyTypeDescription
play()methodBegin playback (or resume if paused)
pause()methodPause mid-sentence
resume()methodResume from paused state
stop()methodCancel speech and reset position
voicesPromise<SpeechSynthesisVoice[]>Available TTS voices
speakingbooleanWhether speech is currently active
pausedbooleanWhether speech is paused
progressnumber (0–1)Current position as fraction of total text

Events

EventDetailWhen
text-reader:play{ voice, speed }Speech starts
text-reader:pauseSpeech paused
text-reader:resumeSpeech resumed
text-reader:stopStopped or cancelled
text-reader:end{ duration }Reached end of text
text-reader:word{ word, charIndex, element }Each word boundary
text-reader:error{ error }SpeechSynthesis error

CSS Custom Properties

PropertyDefaultDescription
--text-reader-bgvar(--color-surface-raised)Control bar background
--text-reader-gap0.5remGap between controls
--text-reader-button-size2remButton width and height
--text-reader-highlightMarkWord highlight background color
--text-reader-highlight-textMarkTextWord highlight text color

Custom Icons

Replace the default text symbols with custom icons using slot attributes:

Any element with slot="icon-play", slot="icon-pause", or slot="icon-stop" will be moved into the corresponding button.

Icon Variant

Use variant="icon" for a compact speaker icon that opens a floating mini-toolbar on click. Ideal for article toolbars and <page-tools> integration.

The floating toolbar provides play/pause, stop, and speed controls. It appears above the trigger icon and auto-dismisses when reading ends. Click outside the toolbar to hide it without stopping playback; click the trigger again to re-show it.

Customize the trigger icon with slot="icon-trigger":

Accessibility

  • Controls are wrapped in a role="group" with aria-label="Article reader"
  • Each button has an aria-label (customizable via label-* attributes)
  • All controls are keyboard-focusable and operable
  • Voice select and speed slider have accessible labels
  • Highlighting uses system colors (Mark / MarkText) by default, respecting user contrast preferences
  • Speech is cancelled on page unload to prevent orphaned audio

Browser Support

FeatureChromeFirefoxSafariNotes
Web Speech API33+49+7+Core feature
CSS Custom Highlight API105+117+17.2+Word highlighting only
Custom Elements67+63+10.1+Baseline
adoptedStyleSheets73+101+16.4+Highlight injection

Graceful Degradation

ConditionBehavior
No speechSynthesisElement hides itself (display: none)
No CSS.highlightsSpeech works normally, highlighting skipped
No target foundConsole warning, controls disabled