Skip to content

Customize

Accessibility

tty.css provides visible focus, preference-aware presentation, and native-first styles. It cannot supply meaning, names, state management, or testing for an application.

Semantics first

  • Use landmarks such as header, nav, main, and footer, with one clear page heading and a logical heading order.
  • Use links for destinations and buttons for actions. Do not add a button role to a non-interactive element when a native button works.
  • Give every form control an accessible name, normally with label. Group related choices with fieldset and legend; connect help and errors with aria-describedby.
  • Use native state and validation attributes before ARIA. ARIA communicates behavior but does not implement it.
  • Write useful image alternatives, captions, table headers, link text, and status messages based on the content's purpose.
Notification channel
Use an address the on-call team monitors.
<form>
  <fieldset>
    <legend>Notification channel</legend>
    <label><input type="radio" name="channel" value="email" checked> Email</label>
    <label><input type="radio" name="channel" value="sms"> SMS</label>
  </fieldset>
  <label for="notification-address">Destination</label>
  <input id="notification-address" name="destination" aria-describedby="notification-help">
  <small id="notification-help">Use an address the on-call team monitors.</small>
  <button type="submit">Save settings</button>
</form>

Keyboard and focus

Tabs require application JavaScript: ARIA roles alone do not switch panels or implement keyboard behavior. Keep aria-selected, native panel hidden, and a single roving tabindex="0" synchronized. With manual activation, Left/Right and Home/End move focus among enabled tabs without selecting; Enter/Space activate the focused native button. Skip disabled tabs, use unique tab/panel IDs with reciprocal labels, and make panels focusable when needed. Test focus and selection as separate states.

Native links, controls, disclosures, and dialogs retain their browser keyboard behavior. tty.css adds a :focus-visible outline to interactive elements and explicit tabindex targets.

Focusable link

<p><a href="#keyboard">Focusable link</a></p>
<button type="button">Focusable button</button>

Keep DOM order aligned with the visual reading order. Do not use positive tabindex, remove outlines without an equivalent replacement, or make a scroll container keyboard-focusable without an accessible name. Test all actions with Tab, Shift+Tab, Enter, Space, arrow keys where native controls use them, and Esc for modal dialogs.

Reduced motion

Under prefers-reduced-motion: reduce, tty.css disables smooth scrolling, reduces transitions and animations to 0.01ms, and limits animations to one iteration. This includes the busy spinner. Application animation, canvas, video, and third-party widgets remain the application's responsibility; remove non-essential movement and provide controls for essential motion.

Forced colors

In forced-colors: active, custom checkboxes, radios, switches, ranges, progress bars, and meters return to native appearance. Date and time controls restore their native picker indicator. Test Windows High Contrast because application overrides, icons, generated content, and status colors may still lose meaning. Never communicate state by color alone.

Print

The print stylesheet switches the core canvas, text, and border tokens to black on white, removes decorative frame shadows, underlines links, and avoids breaking articles, fieldsets, and dialogs when possible. Applications should still hide irrelevant navigation and controls, reveal useful link destinations when needed, and verify pagination and data tables in print preview.

Browser requirements

tty.css targets current evergreen browsers rather than a transpiled compatibility matrix. Its presentation relies on modern CSS including :where(), :has(), color-mix(), logical properties, individual transform properties, and native dialog. Older browsers may keep usable semantic HTML while losing layout or decoration, but that fallback is not guaranteed.

OKLCH is required. Chrome/Edge 111+, Firefox 113+, and Safari 15.4+ are the minimum versions for palette support, not a guarantee of all framework features. Browsers without OKLCH have no framework color fallback; some decorative color-mix() effects have simpler fallbacks.

The support target combines the CSS features used by tty.css with Pico CSS v2's Browserslist defaults philosophy: browsers with more than 0.5% global usage, the last two versions of major browsers, Firefox ESR, and browsers that are not officially dead. RTL layouts are out of scope and are not guaranteed.

Test the browsers and assistive-technology combinations required by your product. Pay particular attention to native date and time controls, form validation, dialog focus, meter rendering, forced colors, printing, and mobile viewport behavior because these vary by engine and platform.

Application responsibilities

  • Manage dynamic names, descriptions, expanded or selected state, busy announcements, errors, and focus after updates.
  • Implement dialog opening, closing, initial focus, destructive-action confirmation, and focus restoration. See dialog behavior.
  • Meet text and non-text contrast requirements after changing tokens; tty.css cannot validate custom color combinations.
  • Support reflow and text zoom without clipping at 200% and 400%, and do not disable browser zoom.
  • Provide captions, transcripts, alternatives, timeout controls, authentication accommodations, and error recovery where the product requires them.
  • Test complete tasks with keyboard-only use, screen readers, zoom, reduced motion, forced colors, touch, and print. Automated checks are useful but not sufficient.

A CSS framework cannot make incorrect HTML or incomplete interaction accessible. Treat tty.css as presentation, not an accessibility conformance claim.