Skip to main content

Notes

Accessible Sale Prices: Why a Struck-Through Price Alone Fails Screen Reader Users

Quietramp ·

Accessible Sale Prices: Why a Struck-Through Price Alone Fails Screen Reader Users

Quick answer: a struck-through original price next to a sale price is a relationship — “this price replaced that one” — conveyed entirely through visual styling. MDN’s own reference for the <s> element states plainly that “the presence of the s element is not announced by most screen reading technology in its default configuration.” A screen reader user tabbing past <s>$49.99</s> $34.99 typically hears “$49.99 $34.99” — two numbers, no indication which is which. WCAG SC 1.3.1 Info and Relationships (Level A) requires that relationship be programmatically determinable, and the fix isn’t a different HTML element — it’s pairing whatever element you use with visually hidden text that states the relationship in words.

This article covers technical accessibility practice, not legal advice — it explains what WCAG 2.1 AA requires for sale-price display and how to meet it, not whether a specific implementation carries legal risk.

A strikethrough is a visual convention, not an announced one

Sighted shoppers learn the strikethrough-price convention early: a line through a number means “this used to be the price; it isn’t anymore.” Nothing about that convention transfers automatically to a screen reader. The <s> and <del> elements exist specifically to carry this “struck-out” meaning in markup rather than CSS alone — the HTML Accessibility API Mappings map <del> to a deletion role and <ins> to an insertion role — but having a correct semantic mapping and having assistive technology actually announce it are two different things. MDN’s guidance on <s> is direct about the gap: “not announced by most screen reading technology in its default configuration.” Swapping a plain <span class="strikethrough"> for a semantically-correct <s> or <del> is still good practice — it’s the right element for the content — but by itself, it does not solve the announcement problem this article is about.

What WCAG actually requires

SC 1.3.1 Info and Relationships (Level A) is the criterion that governs this. Its Intent section states the principle generally: “information and relationships that are implied by visual or auditory formatting are preserved when the presentation format changes” — meaning a screen reader, a braille display, or a high-contrast mode all need access to the same relationship a sighted mouse user sees. The Understanding doc’s own worked example is close to this exact situation, one level simpler: “An on-line catalog may indicate prices using a larger font colored red. A screen reader or person who cannot perceive red, still has the information about the price as long as it is preceded by the currency symbol.” That example covers a single price’s legibility. A sale display adds a second layer on top: it’s not just “can a screen reader read this number,” it’s “can a screen reader tell which of these two numbers is which” — a relationship between two pieces of content, not the content of either one alone.

A related, narrower failure shows up when a site skips the strikethrough convention entirely and signals “this is the discounted price” using color alone — red text, a highlighted background, no strikethrough and no label. SC 1.4.1 Use of Color (Level A) covers this directly: “color is not used as the only visual means of conveying information, indicating an action, prompting a response, or distinguishing a visual element.” The Understanding doc’s own list of failure patterns names almost this exact case — “‘error is shown in red’” as an example of information conveyed by color differences alone. A sale price shown only in red, with no strikethrough on the original and no text label, fails the same way.

What real screen-reader testing shows

Web Axe’s “Strikethrough Accessibility” article — a named, checkable practitioner source, not an anonymous SEO write-up — ran the actual comparison across NVDA, JAWS, VoiceOver, and TalkBack on four markup approaches:

  1. A bare <s> or <del> element, no ARIA, no extra text. Only NVDA and TalkBack picked up and announced the strikethrough semantic; JAWS and VoiceOver did not.
  2. <s role="deletion">, an explicit ARIA role added on top. Nearly identical results, with VoiceOver on iOS also passing this time — still not a reliable cross-tool result.
  3. Visually hidden text stating the relationship in words (e.g., “Original price,” “Sale price”) alongside the visible strikethrough. Every screen reader tested passed.
  4. CSS-generated content via ::before/::after pseudo-elements announcing “start of stricken text” / “end of stricken text” — the technique MDN itself documents as a fallback. This worked in some tools but produced ambiguous output in NVDA and broken output in JAWS.

The pattern across all four scenarios is consistent: relying on the element’s built-in semantics, with or without an explicit ARIA role, is not reliable across the tools people actually use. Visually hidden text was the only approach that passed everywhere it was tested.

The fix: visually hidden text, not a different element

The working pattern pairs the visible strikethrough with hidden text that states the relationship explicitly, so a screen reader announces something a shopper can act on instead of two bare numbers:

<p class="price">
  <span class="visually-hidden">Original price: </span>
  <del>$49.99</del>
  <span class="visually-hidden">Now: </span>
  <ins class="price-sale">$34.99</ins>
</p>

Sighted shoppers still see exactly what they see today — a struck-through number and a highlighted one. A screen reader now announces “Original price: $49.99. Now: $34.99.” instead of two adjacent, unexplained dollar amounts. <del>/<ins> are still the right elements to use for their own sake — the hidden text is what makes the relationship reliably announced, not the elements’ implicit roles.

The same fix applies to the color-only case: adding a small, real (not aria-hidden) text label — “Sale,” or a visually hidden “discounted price:” — next to a red price satisfies SC 1.4.1 without requiring any redesign of the visual treatment.

Don’t overdo it

MDN’s own guidance includes a caution worth carrying over directly: “some people who use screen readers deliberately disable announcing content that creates extra verbosity. Because of this, it is important to not abuse this technique and only apply it in situations where not knowing content has been struck out would adversely affect understanding.” A price comparison is exactly that kind of situation — knowing which number is current changes what a shopper does next. This isn’t license to wrap every visual distinction on a page in hidden labels; it’s specific to cases where the distinction carries real decision-relevant meaning, the way a discount does.

How this differs from two things Quietramp has already covered

This is a different failure than the one in Quietramp’s images of text article, which covers sale badges built as a flattened image graphic instead of live text — that article names <del> as the right element to use once the badge is rebuilt as real text, but doesn’t cover whether that element’s meaning actually reaches a screen reader once it’s there. It’s also different from the strikethrough mention in Quietramp’s checkout and cart roundup article, which flags “was $49.99” purely as a low-contrast text problem under SC 1.4.3 — a page can have perfect contrast on both prices and still fail the criterion this article covers, because contrast and semantic announcement are two independent requirements.

Can an automated scanner catch this?

No. A direct check of axe-core’s own rule descriptions turns up no rule targeting strikethrough text, <del>/<ins> semantics, or price relationships at all. That tracks with what the failure actually is: the markup can be perfectly valid HTML — a correctly nested <del> and <ins>, no ARIA errors, no missing attributes — and still fail to communicate anything, because the gap is in what a screen reader chooses to announce by default, not in anything a rule-based parser can detect from the markup alone.

FAQ

Does using <del> and <ins> instead of <span> fix this on its own? No. They’re the semantically correct elements to reach for, and worth using, but Web Axe’s own testing found bare <del>/<s> — with or without an explicit ARIA role — inconsistently announced across NVDA, JAWS, VoiceOver, and TalkBack. Visually hidden text is what made every tool tested pass.

Do I need to add hidden text to every visual style change on the page, not just prices? No — MDN’s own guidance is to reserve this for cases where missing the distinction would change a user’s understanding or decision, which a price change clearly does. Applying it indiscriminately adds verbosity some screen reader users specifically try to avoid.

Is <s> or <del> the better choice for a former price? <del> is generally the closer semantic fit — the HTML spec describes it as marking a “removal from the document,” which matches a superseded price more precisely than <s>’s more general “no longer accurate” meaning. Either is acceptable paired with the visually hidden text fix; neither is a substitute for it.

Get a full audit that checks this by hand

Whether a struck-through price is actually announced with enough context to be useful is a screen-reader behavioral question, not something a markup scanner resolves on its own — it has to be listened to. Quietramp’s audits pair an automated axe-core scan with a manual screen-reader review that catches exactly this kind of gap, delivered as a prioritized, developer-actionable PDF report. See a real sample report or check pricing — $890 one-time, $99/month for ongoing re-checks after fixes ship.


This article is general accessibility information, not legal advice. Meeting WCAG 2.1 AA does not resolve ADA or any other legal compliance question, and nothing here should be read as a compliance guarantee. Consult qualified counsel for legal risk questions.

This article was drafted with AI assistance and reviewed by a person for accuracy before publication.

← Back to Notes