Exclusivobeta

Reading Ruler <mv-reading-ruler>

Guia de leitura para textos longos (termos, artigos, documentação) que ajuda leitores com dislexia, TDAH ou baixa visão a não perder a linha: uma faixa com exatamente a altura de uma linha se encaixa nas caixas de linha reais do texto sob o ponteiro, com o resto levemente escurecido (band, mask ou underline). Ao contrário dos guias e extensões que só seguem o ponteiro, ele também acompanha a leitura pelo teclado (o cursor de texto, o link em foco, ou Up/Down e J/K linha a linha), e nunca bloqueia cliques, seleção nem o cursor do sistema.

CategoriaCursores
TipoWeb 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

Instalação

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

Agente de IA com o servidor MCP do Marvelous UI: install_components({ slugs: ["reading-ruler"], target_dir: "<absolute path>/src/marvelous", framework: "react" }).

Arquivos copiados (dependências incluídas): 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.

Uso

Início rápido, a menor marcação que funciona:

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

Marcação de referência, para usar como ponto de partida e personalizar com atributos, data-* e variáveis 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

NameTipoDefaultDescription
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

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

Esta página foi traduzida com IA. Informar um problema de tradução