Section 2 · Semantic HTML First
Images, Alt Text and Data Tables
17 min4 min readChoose wisely
Lesson at a glance
Decide what alt text each image needs from its purpose in context, and mark up data tables so screen readers announce the right headers for every cell.
No video here — just the real thing: a written lesson, runnable examples, a quiz and practice.
Every image on Ticketly makes a promise: “this tells you something” or “this is decoration”. Alt text is how you keep that promise for people who can’t see the image. The hard part isn’t the syntax, alt="…" is easy. It is the decision about what, if anything, to say.
Alt text describes purpose, not pixels
Start from one question: what would you lose if this image were removed? That is what the alt text should give back.
| Image on Ticketly | Purpose | Alt |
|---|---|---|
| Photo of the Nour Quartet on their artist card | Informative | alt="Nour Quartet performing on a lit harbour stage" |
| Logo inside a link to the home page | Functional | alt="Ticketly home" |
| Magnifying-glass icon as the only content of the search button | Functional | alt="Search" |
| Wavy line separating sections | Decorative | alt="" |
| Crowd photo behind a headline that already says it all | Decorative in context | alt="" |
| “Sold out” badge drawn as an image | Text in an image | alt="Sold out" |
| Seat map | Complex | Short alt plus a full alternative nearby |
Context changes the answer. The same crowd photo is decorative behind a headline, but informative on a page called “What the venue is like”, where it needs a description.
<article class="artist">
<img src="nour-quartet.jpg" alt="Nour Quartet performing on a lit harbour stage">
<h3>Nour Quartet</h3>
<p>Jazz and Arabic maqam from Alexandria.</p>
</article>A few habits make alt text better:
- Don’t start with “image of” or “photo of”. Screen readers already announce “image” (or “graphic”). Say “photo” only when the medium matters, such as “Hand-drawn poster of…”.
- Don’t repeat nearby text. If the caption says “Nour Quartet”, the alt shouldn’t repeat it word for word; describe what the image adds.
- Keep it short. One sentence covers most images. Long descriptions belong in the page text.
Decorative images and icons
For decorative images, use an empty alt: alt="", with nothing between the quotes. A missing attribute is different: many screen readers then announce the file name, such as “hero underscore final underscore v3 dot jpg”. Images added with CSS background-image are invisible to assistive technology, which is fine for decoration but wrong for anything that carries meaning.
Inline SVG icons follow the same logic with different attributes. Decorative icons get aria-hidden="true", as you did in How Assistive Technology Reads Your Page. An SVG that carries meaning on its own gets role="img" and a name:
<svg role="img" aria-label="Wheelchair accessible venue" viewBox="0 0 24 24">…</svg>Complex images
Charts, maps and diagrams hold more information than a sentence can carry. Give them a short alt that states the takeaway, and put the full information in the page: a data table under a chart, a list of sections and availability next to a seat map, or a <details> element holding a longer description. Ticketly’s seat map gets a list of blocks (“Block A, front left, 12 seats left”) that is useful to everyone comparing options, not only to screen reader users.
Data tables
Ticketly’s pricing grid was built from divs styled with CSS grid. Sighted users read it at a glance; a screen reader reads “Pass, Early bird, Standard, Weekend, SAR 280, SAR 320” as a flat list with no way to know which price belongs to which pass. A real table fixes it:
<table>
<caption>Harbour Lights ticket prices</caption>
<thead>
<tr>
<th scope="col">Pass</th>
<th scope="col">Early bird</th>
<th scope="col">Standard</th>
</tr>
</thead>
<tbody>
<tr><th scope="row">Friday</th><td>SAR 150</td><td>SAR 180</td></tr>
<tr><th scope="row">Weekend</th><td>SAR 280</td><td>SAR 320</td></tr>
</tbody>
</table>The <caption> names the table when the user enters it. scope="col" and scope="row" tell the browser which cells each header covers. Screen readers then offer table navigation (Ctrl+Alt+arrow keys in NVDA, VO+arrow keys in VoiceOver) and announce the relevant headers as the user moves. Keep tables simple: if you need merged headers several levels deep, splitting into two tables is usually clearer for everyone.
Use tables for data, never for layout. And be careful with responsive tricks: setting display: block or display: grid on table elements can strip their table semantics in some browsers, so test with a screen reader if you restyle them.
That completes Ticketly’s semantic foundation. Section 3 moves from what the page is to how people move through it, starting with the keyboard.
Key takeaways
- Alt text describes an image’s purpose in its context, so the same photo can need different alt text on different pages.
- Decorative images get alt=“” so screen readers skip them; a missing alt attribute often makes them read the file name.
- An image that is the only content of a link or button needs alt text naming the destination or action.
- Data tables need a caption and th cells with scope, so each cell is announced with its row and column headers.