ExklusivBeta

Reading Ruler <mv-reading-ruler>

Lesehilfe für lange Texte (AGB, Artikel, Dokumentation), die Lesern mit Legasthenie, ADHS oder Sehschwäche hilft, die Stelle zu halten: Ein Band, genau eine Zeile hoch, rastet an den echten Zeilenboxen des Textes unter dem Zeiger ein, der Rest wird sanft abgedunkelt (band, mask oder underline). Anders als Hilfen und Erweiterungen, die nur dem Zeiger folgen, folgt sie auch dem Lesen per Tastatur (dem Textcursor, dem fokussierten Link oder Zeile für Zeile mit Up/Down und J/K), und sie blockiert nie Klicks, Auswahl oder den Systemcursor.

KategorieCursor
TypWeb Component (<mv-reading-ruler>)
StatusBeta
Keywordsexclusive, light, reading, ruler, reading-guide, line-focus, dyslexia, adhd, low-vision, accessibility, article, legal, docs

When to use

  • Terms of service, policies or contracts are long and dense, and readers need help keeping their place
  • An article or docs page wants an accessibility option for readers with dyslexia, ADHD or low vision
  • A reading preference toggle should be remembered across visits without an account or a browser extension

Avoid when

  • Readers need to see the article structure and jump between sections → use Reading Map instead
  • The goal is a decorative highlight that follows the pointer over cards or buttons → use Cursor Snap instead
  • The text is short or in an editor; the ruler is for reading, not for typing

Installation

node scripts/add.mjs reading-ruler --out ./src/marvelous

KI-Agent mit dem MCP-Server von Marvelous UI: install_components({ slugs: ["reading-ruler"], target_dir: "<absolute path>/src/marvelous", framework: "react" }).

Kopierte Dateien (inklusive Abhängigkeiten): tokens/tokens.css, core/base.css, core/dom.js, core/element.js, core/motion.js, components/reading-ruler/reading-ruler.js, components/reading-ruler/reading-ruler.css.

Verwendung

Schnellstart mit dem kleinsten funktionierenden Markup:

<button data-ruler-toggle>Reading ruler</button>
<mv-reading-ruler><article>…</article></mv-reading-ruler>

Referenz-Markup zum Starten und Anpassen mit Attributen, data-* und CSS-Variablen:

<div id="mv-reading-ruler-demo" style="width:min(100%,44rem);margin-inline:auto;display:grid;gap:.75rem">
  <div style="display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:.75rem">
    <label class="mv-choice" style="gap:.6rem">
      <input type="checkbox" role="switch" class="mv-switch" data-ruler-toggle="rr-terms" checked>
      <span class="mv-choice-text"><span class="mv-choice-title">Reading ruler</span></span>
    </label>
    <div style="display:flex;align-items:center;gap:.5rem;font-size:.8rem;color:var(--mv-fg-muted)">
      <label for="rr-mode">Style</label>
      <select class="mv-select" id="rr-mode" style="width:auto">
        <option value="band">Band</option>
        <option value="mask">Mask</option>
        <option value="underline">Underline</option>
      </select>
    </div>
  </div>

  <mv-reading-ruler id="rr-terms" enabled style="padding:1.25rem 1.5rem;border:1px solid var(--mv-border);border-radius:var(--mv-radius-lg);background:var(--mv-bg)">
    <article style="font-size:.95rem;line-height:1.7;color:var(--mv-fg)">
      <p style="margin:0 0 .25rem;font-size:.75rem;color:var(--mv-fg-muted)">Last updated September 24, 2026</p>
      <h3 style="margin:0 0 .5rem;font-size:1.15rem">4. Subscriptions and billing</h3>
      <p style="margin:0 0 .75rem">Your plan renews automatically at the end of each billing period at the price shown on your <a href="#" style="color:var(--mv-accent-fg)">account page</a>, currently $12.00 per month or $120.00 per year. We will email you at least 14 days before any price change, and the new price applies from the next period only.</p>
      <p style="margin:0 0 .75rem">You can cancel at any time from Settings &rsaquo; Billing. Cancellation takes effect at the end of the current period; you keep access until then, and no partial refunds are issued except where the law of your country requires them.</p>
      <h3 style="margin:0 0 .5rem;font-size:1.15rem">5. Your content</h3>
      <p style="margin:0">You keep every right to the documents you upload. You grant us a limited license to store, process and display them only to run the service for you and the people you choose to share them with.</p>
    </article>
  </mv-reading-ruler>

  <p style="margin:0;font-size:.8rem;color:var(--mv-fg-muted)">Move the pointer over the text, or focus it and press <kbd class="mv-kbd">↓</kbd> <kbd class="mv-kbd">↑</kbd> (or <kbd class="mv-kbd">J</kbd> <kbd class="mv-kbd">K</kbd>) to step line by line.</p>

  <script type="module">
    const root = document.getElementById("mv-reading-ruler-demo");
    root.querySelector("#rr-mode").addEventListener("change", (e) => {
      root.querySelector("#rr-terms").setAttribute("mode", e.target.value);
    });
  </script>
</div>

API

Attributes

NameTypDefaultDescription
enabledbooleanTurns the ruler on. Toggles set it for you; without a toggle, set it yourself.
modeband | mask | underlinebandband: tinted band and gently dimmed text around it. mask: only the line stays at full strength (stronger dim). underline: an accent line under the current line, nothing dimmed.
storage-keystringOpt-in: remembers the reader's on/off choice in localStorage under this key (stored as "on" | "off"; only choices made with a toggle are saved).
data-ruler-toggle (on your control)(empty) | ruler idAny button or checkbox anywhere on the page. Empty: controls the ruler it sits in, else the first ruler of the page; with a value: the ruler with that id. Buttons get aria-pressed, checkboxes get checked, both get aria-controls.
data-steppedbooleanSet by the component after a keyboard step, until the text loses focus (hides the hint).

Properties

NameTypDescription
strings{ label, hint }Accessible name of the text while the ruler is on ("Text with reading ruler") and keyboard hint ("↑ ↓ or J K: move line by line"). English defaults, each overridable.

Methods

NameDescription
refresh()Re-measures the line boxes. Automatic on resize, content changes and web font loads.

Events

NameDescription
mv-toggleA toggle is about to turn the ruler on or off. detail = { enabled }. Cancelable: preventDefault() keeps the current state (the toggle is reset).

CSS classes

NameDescription
mv-reading-ruler-layerOverlay (aria-hidden, pointer-events: none, user-select: none); data-placed once positioned.
mv-reading-ruler-bandThe band, one line tall (line box plus padding).
mv-reading-ruler-hintKeyboard hint that rides the band, shown on keyboard focus until the first step.

CSS variables

NameDefaultDescription
--mv-reading-ruler-coloraccent at 9%Band tint (band mode).
--mv-reading-ruler-edgeaccent at 38%Hairlines above and below the band.
--mv-reading-ruler-dim--mv-bg at 38% (mask: 68%)Veil over the rest of the text. Match it to the text's background color.
--mv-reading-ruler-padding0.2emExtra height above and below the line box.
--mv-reading-ruler-underlinevar(--mv-accent)Underline color (underline mode).
--mv-reading-ruler-thickness2pxUnderline thickness.

Accessibility

The overlay is aria-hidden with pointer-events: none and user-select: none, so links, buttons and text selection work exactly as without it, and the system cursor is never hidden or replaced. Pointer following is on only under (hover: hover) and (pointer: fine); on touch a tap places the ruler on that line. While on, the text becomes a focusable region (tabindex=0, role=region, aria-label "Text with reading ruler", aria-keyshortcuts) whose description is the keyboard hint, also shown on keyboard focus: ArrowUp/ArrowDown or J/K step line by line and scroll the line into view (ignored with Ctrl, Alt or Meta, inside fields and editable text). Focusing a link or button inside moves the ruler to its line, and so does moving the caret (caret browsing, keyboard selection). Toggles you place get aria-pressed or checked and aria-controls; the choice is remembered only with storage-key (wrapped in try/catch). Reduced motion (OS or data-motion="reduce"): the band jumps without easing and scrolling is instant. Forced colors: no dimming, the band becomes a 2px Highlight outline. Nothing is announced; the attributes set by the component are removed when it is turned off.

Diese Seite wurde mit KI übersetzt. Übersetzungsfehler melden