Content visually hidden but available to assistive technology.
visible label: “Close” icon only
debug view: the .sr-only span is normally clipped to 1px — shown here so you can see what the button's accessible name actually is{{unless reveal}}hidden text is clipped off-screen, exactly as a sighted user would see it
<div class="sro-demo" style="--accent:#F5C2E0;">
<button type="button" class="sro-demo__btn">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M5 5l14 14M19 5L5 19" /></svg>
<span class="sro-demo__sronly sro-demo__sronly--revealed">Close dialog, discard changes</span>
</button>
<p class="sro-demo__visible-label">visible label: “Close” icon only</p>
<p class="sro-demo__note">debug view: the .sr-only span is normally clipped to 1px — shown here so you can see what the button's accessible name actually is{{unless reveal}}hidden text is clipped off-screen, exactly as a sighted user would see it<div style="width:320px;font-family:system-ui,sans-serif;color:#241430">
<button type="button" class="inline-flex items-center gap-2 p-2.5 rounded-lg border-0 cursor-pointer" style="background:#F5C2E0;color:#241430">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M5 5l14 14M19 5L5 19" /></svg>
<span class="sro-tw sro-tw--revealed">Close dialog, discard changes</span>
</button>
<p class="mt-2.5 mb-1 text-xs text-[#241430aa]">visible label: “Close” icon only</p>
<p class="m-0 text-xs text-[#241430aa]">debug view: the .sr-only span is normally clipped to 1px — shown here so you can see what the button's accessible name actually is{{unless reveal}}hidden text is clipped off-screen, exactly as a sighted user would see itexport function ScreenReaderOnly({
buttonPurpose = "Close",
hiddenText = "Close dialog, discard changes",
reveal = true,
accent = "#F5C2E0",
}) {
const clipped = { position: "absolute", width: 1, height: 1, padding: 0, margin: -1, overflow: "hidden", clip: "rect(0,0,0,0)", whiteSpace: "nowrap", border: 0 };
const revealed = { position: "static", width: "auto", height: "auto", margin: 0, overflow: "visible", clip: "auto", whiteSpace: "normal", padding: "3px 8px", background: "#24143014", borderRadius: 4, outline: "1.5px dashed " + accent, fontSize: 12 };
return (
<div style={{ width: 320, fontFamily: "system-ui, sans-serif", fontSize: 14, color: "#241430" }}>
<button type="button" style={{ display: "inline-flex", alignItems: "center", gap: 8, padding: 10, borderRadius: 8, border: "none", background: accent, color: "#241430", cursor: "pointer" }}>
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" aria-hidden="true"><path d="M5 5l14 14M19 5L5 19" /></svg>
<span style={reveal ? revealed : clipped}>{hiddenText}</span>
</button>
<p style={{ margin: "10px 0 4px", fontSize: 12, color: "#241430aa" }}>visible label: “{buttonPurpose}” icon only</p>
<p style={{ margin: 0, fontSize: 12, color: "#241430aa" }}>{reveal ? "debug view: the .sr-only span is normally clipped to 1px \u2014 shown here so you can see what the button's accessible name actually is" : "hidden text is clipped off-screen, exactly as a sighted user would see it"}</p>
</div>
);
}