Exclusifbêta

Reading Ruler <mv-reading-ruler>

Guide de lecture pour les textes longs (conditions, articles, documentation) qui aide les lecteurs dyslexiques, atteints de TDAH ou malvoyants à ne pas perdre leur ligne : une bande d’exactement une ligne de haut se cale sur les vraies boîtes de ligne du texte sous le pointeur, le reste étant légèrement assombri (bande, masque ou soulignement). Contrairement aux guides et aux extensions qui ne suivent que le pointeur, il suit aussi la lecture au clavier (le curseur de texte, le lien qui a le focus, ou Haut/Bas et J/K ligne par ligne), et il ne bloque jamais les clics, la sélection ni le curseur système.

CatégorieCurseurs
TypeWeb Component (<mv-reading-ruler>)
Statutbêta
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

Agent IA avec le serveur MCP de Marvelous UI : install_components({ slugs: ["reading-ruler"], target_dir: "<absolute path>/src/marvelous", framework: "react" }).

Fichiers copiés (dépendances comprises) : 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.

Utilisation

Démarrage rapide, le balisage minimal qui fonctionne :

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

Balisage de référence : partez de celui-ci et personnalisez-le avec les attributs, data-* et les variables CSS :

<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

NameTypeDefaultDescription
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

NameTypeDescription
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.

Cette page a été traduite par IA. Signaler un problème de traduction