Observation Details
The device list presentation suggests the code to be marked up like this:
<!-- Device list -->
<div>
<!-- Device card -->
<article>
<span><!-- Badge --></span>
<img /><!-- Device image -->
<h2><!-- Device name --></h2>
<p><!-- Storage --></p>
<p><!-- Price info --></p>
<p><!-- Price --></p>
</article>
<!-- More device cards -->
</div>Instead, there are no headings, sections, articles, divs and spans are nested many hierarchy levels and an empty link is present.
Remediation Notes
Ensure, code markup matches the visual presentation. One possible solution could be a structure as follows:
<h2></h2> <!-- Heading to introduce device list -->
<!-- Device list -->
<ul>
<li>
<!-- Device card -->
<article>
<h3></h3> <!-- Device name -->
<span></span> <!-- Badge with promotion/info -->
<dl>
<div>
<dt class="visually-hidden">Verfügbar in den Farben</dt>
<dd>
<ul></ul> <!-- Available colors -->
</dd>
</div>
<div>
<dt class="visually-hidden">Speicherplatz</dt>
<dd>
Verfügbar in
<ul></ul> <!-- Storage options -->
</dd>
</div>
<div>
<dt>Preis, einmalig</dt>
<dd></dd> <!-- Price -->
</div>
</dl>
<img /><!-- Device image -->
</article>
</li>
<!-- More device cards -->
</ul>Improvements made and notes to implement:
Clear structure without unnecessary nesting, without sections/articles nested, etc.
Use actual semantic list (
<ul>) for the listEach product is an
<article>so it can be navigated to easily via screen readerProduct is defined by semantic heading
<h3>as first child of product card<span>with badge positioned right after heading, so it will be announced after the device name; badge can be positioned absolute or visually be moved up by using CSSorder: -1Product description is moved into description list to make each description detail easily navigable
Lists within the description (color list, storage option list) are using semantic list elements
Some
<dt>can use aclass="visually-hidden"to be accessible to screen readers while not being visible; check example class below
.visually-hidden:not(:focus):not(:active) {
clip: rect(0 0 0 0);
clip-path: inset(50%);
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
}Added side-effect of a semantic structure like this is the improved simplicity to build a responsive layout for the list, using CSS grid and Flexbox.