{"id":6559,"date":"2026-08-27T07:00:00","date_gmt":"2026-08-27T05:00:00","guid":{"rendered":"https:\/\/volcanicinternet.com\/?p=6559"},"modified":"2026-08-26T11:47:23","modified_gmt":"2026-08-26T09:47:23","slug":"making-complex-tables-accessible","status":"publish","type":"post","link":"https:\/\/volcanicinternet.com\/en\/making-complex-tables-accessible\/","title":{"rendered":"Making complex tables accessible"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\"><abbr title=\"HyperText Markup Language\">HTML<\/abbr> tables have a bad reputation. People often see them as bad for accessibility, bad practice, and outdated.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This reputation is only fair when we use tables for layout. Most modern websites don&#8217;t do this, but most emails still do. Tables have semantic value (meaning) and functional behaviour. Tables work well for data in rows and columns. They don&#8217;t work well for layout.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You can use <code>role=\"presentation\"<\/code> to remove a table&#8217;s semantic value and functional behaviour. Even then, the content order in the <abbr title=\"Document Object Model\">DOM<\/abbr> still needs to make sense.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Let&#8217;s see an example of a table with inventory information for a small bakery:<\/p>\n\n\n\n<style data-wp-block-html=\"css\">\ntable {\n    border-collapse: collapse;\n  }\n  caption, th, td {\n    border: 1px solid #666 !important;\n    padding: 0.5rem 0.75rem !important;\n    text-align: left !important;\n    vertical-align: top !important;\n  }\n  caption,\n  table:nth-of-type(1) tr:nth-child(1) td[colspan=\"7\"] {\n    border-bottom: none !important;\n    font-size: 1.25rem !important;\n  }\n  table:not(:has(thead)) tr:nth-child(1) td,\n  table:not(:has(thead)) tr:nth-child(2) td,\n  table:not(:has(thead)) tr:nth-child(3) td,\n  table:not(:has(thead)) tr:nth-child(n+2) td:nth-child(1),\n  table:not(:has(thead)) tr td[rowspan] + td:nth-child(2),\n  caption,\n  table tr th {\n    color: #FF700E !important;\n    font-weight: bold !important;\n  }\n<\/style>\n\n<figure class=\"has-custom-css\"><table class=\"has-fixed-layout\"><tbody><tr><td colspan=\"7\">Weekly inventory by category<\/td><\/tr><tr><td rowspan=\"2\">Category<\/td><td rowspan=\"2\">Item<\/td><td colspan=\"2\">Pricing<\/td><td colspan=\"2\">Stock<\/td><td rowspan=\"2\">Status<\/td><\/tr><tr><td>Unit Cost<\/td><td>Retail Price<\/td><td>In Stock<\/td><td>Reorder Level<\/td><\/tr><tr><td rowspan=\"3\">Breads<\/td><td>Baguette<\/td><td>$0.65<\/td><td>$3.25<\/td><td>42<\/td><td>20<\/td><td>OK<\/td><\/tr><tr><td>Sourdough Loaf<\/td><td>$0.90<\/td><td>$4.75<\/td><td>15<\/td><td>18<\/td><td>Low<\/td><\/tr><tr><td>Rye Loaf<\/td><td>$0.85<\/td><td>$4.50<\/td><td>27<\/td><td>15<\/td><td>OK<\/td><\/tr><tr><td rowspan=\"2\">Pastries<\/td><td>Butter Croissant<\/td><td>$0.55<\/td><td>$2.95<\/td><td>60<\/td><td>25<\/td><td>OK<\/td><\/tr><tr><td>Cherry Danish<\/td><td>$0.70<\/td><td>$3.50<\/td><td>8<\/td><td>12<\/td><td>Low<\/td><\/tr><tr><td rowspan=\"2\">Cakes<\/td><td>Carrot Cake Slice<\/td><td>$1.10<\/td><td>$4.95<\/td><td>18<\/td><td>10<\/td><td>OK<\/td><\/tr><tr><td>Cheesecake Slice<\/td><td>$1.25<\/td><td>$5.25<\/td><td>22<\/td><td>10<\/td><td>OK<\/td><\/tr><tr><td colspan=\"2\">Totals<\/td><td>\u2014<\/td><td>\u2014<\/td><td>192 units<\/td><td>110 units<\/td><td>2 items low<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">It doesn&#8217;t look bad, does it? <abbr title=\"Cascading Style Sheets\">CSS<\/abbr> makes the parts easy to tell apart, and the layout makes sense.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">That&#8217;s the main problem. Important information like relationships and structure relies only on visual styles and position. People using assistive technology can&#8217;t access that information.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">At the end of this article, you&#8217;ll find the same table with everything the first version is missing.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Let&#8217;s go step by step.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Header cells<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This is the easiest change to make. All cells in the first table use the data cell tag, <code>&lt;td&gt;<\/code>. But HTML also has a header cell tag, <code>&lt;th&gt;<\/code>, for cells that act as headers.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Use the <code>scope<\/code> attribute to mark a header cell as a column header (<code>scope=\"col\"<\/code>) or a row header (<code>scope=\"row\"<\/code>). This gives you headers across the top for each column, and a header at the start of each row.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Row groups<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A table can have both column groups and row groups. The scope attribute also accepts <code>colgroup<\/code> and <code>rowgroup<\/code> values for these.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">There are 3 main row groups: the table head (<code>&lt;thead&gt;<\/code>), the table body (<code>&lt;tbody&gt;<\/code>), and the table footer (<code>&lt;tfoot&gt;<\/code>). These are especially useful for large tables.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In our example:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The top headers go in the table head.<\/li>\n\n\n\n<li>The product data goes in the table body.<\/li>\n\n\n\n<li>The totals go in the table footer.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">This makes it easier to navigate between the main parts.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Caption<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This part matters. A caption describes the table&#8217;s content so people can decide whether they need or want to read the data.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You have a few options here. You can use:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>A caption (or <code>&lt;figcaption><\/code> if the table sits inside a <code>&lt;figure><\/code>)<\/li>\n\n\n\n<li>Text, like a paragraph, placed before the table<\/li>\n\n\n\n<li>Text in another element, linked with the <code>aria-describedby<\/code> attribute<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">These methods work equally well. Use only one.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">One advantage of <code>&lt;caption&gt;<\/code>: you can nest a <code>&lt;details&gt;<\/code> element inside it, with extra information in a <code>&lt;summary&gt;<\/code> dropdown, or add text that&#8217;s visually hidden but still readable by screen readers. I used this second approach in the example at the end of the article. It gives everyone a short, visible label, and gives screen-reader users a longer text with more context.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Note: the <code>summary<\/code> attribute on the <code>&lt;table&gt;<\/code> element is obsolete in the HTML Living Standard. Don&#8217;t use it.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Multi-level headers<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This part makes the biggest difference for people using assistive technology, especially in complex tables.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In our example, both columns and rows have multiple header levels. This can look tricky, but the fix is simple.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">First, add a unique <code>id<\/code> attribute to each header cell. Then add a <code>headers<\/code> attribute to each data cell. List every header cell it relates to \u2014 both column and row headers, at every level.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For example, the cell with the baguette&#8217;s retail price includes: <code>headers=\"row-breads row-baguette col-pricing col-retail\"<\/code>. This lets screen readers announce every related header for that cell.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Accessible tables aren&#8217;t difficult to build. The markup can get verbose, since you&#8217;re linking many cells to many headers. But it&#8217;s simple to implement. And it turns a slow, frustrating experience \u2014 scrolling through endless data with no context \u2014 into a clear, usable source of information.<\/p>\n\n\n\n<figure class=\"has-custom-css\"><table class=\"has-fixed-layout\">\n  <caption id=\"inventory-caption\">\n    Weekly inventory by category\n    <span id=\"inventory-desc\" class=\"screen-reader-text\">\n      Lists each bakery item&#8217;s unit cost, retail price, current stock,\n      and reorder level, grouped by product category, with totals in\n      the final row.\n    <\/span>\n  <\/caption>\n  <thead>\n    <tr>\n      <th id=\"col-category\" rowspan=\"2\" scope=\"col\">Category<\/th>\n      <th id=\"col-item\" rowspan=\"2\" scope=\"col\">Item<\/th>\n      <th id=\"col-pricing\" colspan=\"2\" scope=\"colgroup\">Pricing<\/th>\n      <th id=\"col-stock\" colspan=\"2\" scope=\"colgroup\">Stock<\/th>\n      <th id=\"col-status\" rowspan=\"2\" scope=\"col\">Status<\/th>\n    <\/tr>\n    <tr>\n      <th id=\"col-unitcost\" headers=\"col-pricing\" scope=\"col\">Unit Cost<\/th>\n      <th id=\"col-retail\" headers=\"col-pricing\" scope=\"col\">Retail Price<\/th>\n      <th id=\"col-instock\" headers=\"col-stock\" scope=\"col\">In Stock<\/th>\n      <th id=\"col-reorder\" headers=\"col-stock\" scope=\"col\">Reorder Level<\/th>\n    <\/tr>\n  <\/thead>\n  <tbody>\n    <tr>\n      <th id=\"row-breads\" rowspan=\"3\" scope=\"rowgroup\">Breads<\/th>\n      <th id=\"row-baguette\" scope=\"row\">Baguette<\/th>\n      <td headers=\"row-breads row-baguette col-pricing col-unitcost\">$0.65<\/td>\n      <td headers=\"row-breads row-baguette col-pricing col-retail\">$3.25<\/td>\n      <td headers=\"row-breads row-baguette col-stock col-instock\">42<\/td>\n      <td headers=\"row-breads row-baguette col-stock col-reorder\">20<\/td>\n      <td headers=\"row-breads row-baguette col-status\">OK<\/td>\n    <\/tr>\n    <tr>\n      <th id=\"row-sourdough\" scope=\"row\">Sourdough Loaf<\/th>\n      <td headers=\"row-breads row-sourdough col-pricing col-unitcost\">$0.90<\/td>\n      <td headers=\"row-breads row-sourdough col-pricing col-retail\">$4.75<\/td>\n      <td headers=\"row-breads row-sourdough col-stock col-instock\">15<\/td>\n      <td headers=\"row-breads row-sourdough col-stock col-reorder\">18<\/td>\n      <td headers=\"row-breads row-sourdough col-status\" class=\"low-stock\">Low<\/td>\n    <\/tr>\n    <tr>\n      <th id=\"row-rye\" scope=\"row\">Rye Loaf<\/th>\n      <td headers=\"row-breads row-rye col-pricing col-unitcost\">$0.85<\/td>\n      <td headers=\"row-breads row-rye col-pricing col-retail\">$4.50<\/td>\n      <td headers=\"row-breads row-rye col-stock col-instock\">27<\/td>\n      <td headers=\"row-breads row-rye col-stock col-reorder\">15<\/td>\n      <td headers=\"row-breads row-rye col-status\">OK<\/td>\n    <\/tr>\n    <tr>\n      <th id=\"row-pastries\" rowspan=\"2\" scope=\"rowgroup\">Pastries<\/th>\n      <th id=\"row-croissant\" scope=\"row\">Butter Croissant<\/th>\n      <td headers=\"row-pastries row-croissant col-pricing col-unitcost\">$0.55<\/td>\n      <td headers=\"row-pastries row-croissant col-pricing col-retail\">$2.95<\/td>\n      <td headers=\"row-pastries row-croissant col-stock col-instock\">60<\/td>\n      <td headers=\"row-pastries row-croissant col-stock col-reorder\">25<\/td>\n      <td headers=\"row-pastries row-croissant col-status\">OK<\/td>\n    <\/tr>\n    <tr>\n      <th id=\"row-danish\" scope=\"row\">Cherry Danish<\/th>\n      <td headers=\"row-pastries row-danish col-pricing col-unitcost\">$0.70<\/td>\n      <td headers=\"row-pastries row-danish col-pricing col-retail\">$3.50<\/td>\n      <td headers=\"row-pastries row-danish col-stock col-instock\">8<\/td>\n      <td headers=\"row-pastries row-danish col-stock col-reorder\">12<\/td>\n      <td headers=\"row-pastries row-danish col-status\" class=\"low-stock\">Low<\/td>\n    <\/tr>\n    <tr>\n      <th id=\"row-cakes\" rowspan=\"2\" scope=\"rowgroup\">Cakes<\/th>\n      <th id=\"row-carrot\" scope=\"row\">Carrot Cake Slice<\/th>\n      <td headers=\"row-cakes row-carrot col-pricing col-unitcost\">$1.10<\/td>\n      <td headers=\"row-cakes row-carrot col-pricing col-retail\">$4.95<\/td>\n      <td headers=\"row-cakes row-carrot col-stock col-instock\">18<\/td>\n      <td headers=\"row-cakes row-carrot col-stock col-reorder\">10<\/td>\n      <td headers=\"row-cakes row-carrot col-status\">OK<\/td>\n    <\/tr>\n    <tr>\n      <th id=\"row-cheesecake\" scope=\"row\">Cheesecake Slice<\/th>\n      <td headers=\"row-cakes row-cheesecake col-pricing col-unitcost\">$1.25<\/td>\n      <td headers=\"row-cakes row-cheesecake col-pricing col-retail\">$5.25<\/td>\n      <td headers=\"row-cakes row-cheesecake col-stock col-instock\">22<\/td>\n      <td headers=\"row-cakes row-cheesecake col-stock col-reorder\">10<\/td>\n      <td headers=\"row-cakes row-cheesecake col-status\">OK<\/td>\n    <\/tr>\n  <\/tbody>\n  <tfoot>\n    <tr>\n      <th id=\"row-totals\" colspan=\"2\" scope=\"row\">Totals<\/th>\n      <td headers=\"row-totals col-pricing col-unitcost\">\u2014<\/td>\n      <td headers=\"row-totals col-pricing col-retail\">\u2014<\/td>\n      <td headers=\"row-totals col-stock col-instock\">192 units<\/td>\n      <td headers=\"row-totals col-stock col-reorder\">110 units<\/td>\n      <td headers=\"row-totals col-status\">2 items low<\/td>\n    <\/tr>\n  <\/tfoot>\n<\/table>\n<\/figure>\n","protected":false},"excerpt":{"rendered":"<p>HTML tables have a bad reputation. People often&#8230;<\/p>\n","protected":false},"author":5,"featured_media":6604,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"wpce_document_language":"","_kad_blocks_custom_css":"","_kad_blocks_head_custom_js":"","_kad_blocks_body_custom_js":"","_kad_blocks_footer_custom_js":"","footnotes":""},"categories":[33],"tags":[],"class_list":["post-6559","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-accessibility"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.3 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>HTML Tables: A Guide to Semantics and Screen Reader Support<\/title>\n<meta name=\"description\" content=\"Learn how to build accessible HTML tables with proper headers, row groups, captions, and multi-level relationships for screen reader.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/volcanicinternet.com\/en\/making-complex-tables-accessible\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"HTML Tables: A Guide to Semantics and Screen Reader Support\" \/>\n<meta property=\"og:description\" content=\"Learn how to build accessible HTML tables with proper headers, row groups, captions, and multi-level relationships for screen reader.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/volcanicinternet.com\/en\/making-complex-tables-accessible\/\" \/>\n<meta property=\"og:site_name\" content=\"Volcanic Internet\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/volcanicinternet\" \/>\n<meta property=\"article:published_time\" content=\"2026-08-27T05:00:00+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/volcanicinternet.com\/app\/uploads\/2026\/08\/Making-complex-tables-accessible.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1000\" \/>\n\t<meta property=\"og:image:height\" content=\"500\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Fran Rosa\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@volcanictech\" \/>\n<meta name=\"twitter:site\" content=\"@volcanictech\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Fran Rosa\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/volcanicinternet.com\\\/en\\\/making-complex-tables-accessible\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/volcanicinternet.com\\\/en\\\/making-complex-tables-accessible\\\/\"},\"author\":{\"name\":\"Fran Rosa\",\"@id\":\"https:\\\/\\\/volcanicinternet.com\\\/en\\\/#\\\/schema\\\/person\\\/409c516eedd21dff3ffd020f75ba42fe\"},\"headline\":\"Making complex tables accessible\",\"datePublished\":\"2026-08-27T05:00:00+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/volcanicinternet.com\\\/en\\\/making-complex-tables-accessible\\\/\"},\"wordCount\":729,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/volcanicinternet.com\\\/en\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/volcanicinternet.com\\\/en\\\/making-complex-tables-accessible\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/volcanicinternet.com\\\/app\\\/uploads\\\/2026\\\/08\\\/Making-complex-tables-accessible.png\",\"articleSection\":[\"Accessibility\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/volcanicinternet.com\\\/en\\\/making-complex-tables-accessible\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/volcanicinternet.com\\\/en\\\/making-complex-tables-accessible\\\/\",\"url\":\"https:\\\/\\\/volcanicinternet.com\\\/en\\\/making-complex-tables-accessible\\\/\",\"name\":\"HTML Tables: A Guide to Semantics and Screen Reader Support\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/volcanicinternet.com\\\/en\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/volcanicinternet.com\\\/en\\\/making-complex-tables-accessible\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/volcanicinternet.com\\\/en\\\/making-complex-tables-accessible\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/volcanicinternet.com\\\/app\\\/uploads\\\/2026\\\/08\\\/Making-complex-tables-accessible.png\",\"datePublished\":\"2026-08-27T05:00:00+00:00\",\"description\":\"Learn how to build accessible HTML tables with proper headers, row groups, captions, and multi-level relationships for screen reader.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/volcanicinternet.com\\\/en\\\/making-complex-tables-accessible\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/volcanicinternet.com\\\/en\\\/making-complex-tables-accessible\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/volcanicinternet.com\\\/en\\\/making-complex-tables-accessible\\\/#primaryimage\",\"url\":\"https:\\\/\\\/volcanicinternet.com\\\/app\\\/uploads\\\/2026\\\/08\\\/Making-complex-tables-accessible.png\",\"contentUrl\":\"https:\\\/\\\/volcanicinternet.com\\\/app\\\/uploads\\\/2026\\\/08\\\/Making-complex-tables-accessible.png\",\"width\":1000,\"height\":500},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/volcanicinternet.com\\\/en\\\/making-complex-tables-accessible\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Inici\",\"item\":\"https:\\\/\\\/volcanicinternet.com\\\/en\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Making complex tables accessible\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/volcanicinternet.com\\\/en\\\/#website\",\"url\":\"https:\\\/\\\/volcanicinternet.com\\\/en\\\/\",\"name\":\"Volcanic Internet\",\"description\":\"P\u00e0gines web, aplicacions m\u00f2bils, desenvolupament a mida\",\"publisher\":{\"@id\":\"https:\\\/\\\/volcanicinternet.com\\\/en\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/volcanicinternet.com\\\/en\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/volcanicinternet.com\\\/en\\\/#organization\",\"name\":\"Volcanic Internet\",\"url\":\"https:\\\/\\\/volcanicinternet.com\\\/en\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/volcanicinternet.com\\\/en\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/volcanicinternet.com\\\/app\\\/uploads\\\/2026\\\/08\\\/volcanic_logo.png\",\"contentUrl\":\"https:\\\/\\\/volcanicinternet.com\\\/app\\\/uploads\\\/2026\\\/08\\\/volcanic_logo.png\",\"width\":642,\"height\":80,\"caption\":\"Volcanic Internet\"},\"image\":{\"@id\":\"https:\\\/\\\/volcanicinternet.com\\\/en\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/volcanicinternet\",\"https:\\\/\\\/x.com\\\/volcanictech\",\"https:\\\/\\\/es.linkedin.com\\\/company\\\/volcanic-internet\"],\"description\":\"Implantaci\u00f3n de IA con Claude, desarrollo web y accesibilidad digital\",\"areaServed\":[\"ES\",\"EU\",\"LATAM\"],\"knowsAbout\":[\"Claude IA\",\"Desarrollo Web\",\"Accesibilidad Web\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/volcanicinternet.com\\\/en\\\/#\\\/schema\\\/person\\\/409c516eedd21dff3ffd020f75ba42fe\",\"name\":\"Fran Rosa\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1d51829327994fc3b0c6f1d6d853c8242a493a21590d75432104e00e4425ba2b?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1d51829327994fc3b0c6f1d6d853c8242a493a21590d75432104e00e4425ba2b?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1d51829327994fc3b0c6f1d6d853c8242a493a21590d75432104e00e4425ba2b?s=96&d=mm&r=g\",\"caption\":\"Fran Rosa\"},\"description\":\"Senior developer and advocate focused on peope-first development\",\"url\":\"https:\\\/\\\/volcanicinternet.com\\\/en\\\/author\\\/fran-rosa\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"HTML Tables: A Guide to Semantics and Screen Reader Support","description":"Learn how to build accessible HTML tables with proper headers, row groups, captions, and multi-level relationships for screen reader.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/volcanicinternet.com\/en\/making-complex-tables-accessible\/","og_locale":"en_US","og_type":"article","og_title":"HTML Tables: A Guide to Semantics and Screen Reader Support","og_description":"Learn how to build accessible HTML tables with proper headers, row groups, captions, and multi-level relationships for screen reader.","og_url":"https:\/\/volcanicinternet.com\/en\/making-complex-tables-accessible\/","og_site_name":"Volcanic Internet","article_publisher":"https:\/\/www.facebook.com\/volcanicinternet","article_published_time":"2026-08-27T05:00:00+00:00","og_image":[{"width":1000,"height":500,"url":"https:\/\/volcanicinternet.com\/app\/uploads\/2026\/08\/Making-complex-tables-accessible.png","type":"image\/png"}],"author":"Fran Rosa","twitter_card":"summary_large_image","twitter_creator":"@volcanictech","twitter_site":"@volcanictech","twitter_misc":{"Written by":"Fran Rosa","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/volcanicinternet.com\/en\/making-complex-tables-accessible\/#article","isPartOf":{"@id":"https:\/\/volcanicinternet.com\/en\/making-complex-tables-accessible\/"},"author":{"name":"Fran Rosa","@id":"https:\/\/volcanicinternet.com\/en\/#\/schema\/person\/409c516eedd21dff3ffd020f75ba42fe"},"headline":"Making complex tables accessible","datePublished":"2026-08-27T05:00:00+00:00","mainEntityOfPage":{"@id":"https:\/\/volcanicinternet.com\/en\/making-complex-tables-accessible\/"},"wordCount":729,"commentCount":0,"publisher":{"@id":"https:\/\/volcanicinternet.com\/en\/#organization"},"image":{"@id":"https:\/\/volcanicinternet.com\/en\/making-complex-tables-accessible\/#primaryimage"},"thumbnailUrl":"https:\/\/volcanicinternet.com\/app\/uploads\/2026\/08\/Making-complex-tables-accessible.png","articleSection":["Accessibility"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/volcanicinternet.com\/en\/making-complex-tables-accessible\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/volcanicinternet.com\/en\/making-complex-tables-accessible\/","url":"https:\/\/volcanicinternet.com\/en\/making-complex-tables-accessible\/","name":"HTML Tables: A Guide to Semantics and Screen Reader Support","isPartOf":{"@id":"https:\/\/volcanicinternet.com\/en\/#website"},"primaryImageOfPage":{"@id":"https:\/\/volcanicinternet.com\/en\/making-complex-tables-accessible\/#primaryimage"},"image":{"@id":"https:\/\/volcanicinternet.com\/en\/making-complex-tables-accessible\/#primaryimage"},"thumbnailUrl":"https:\/\/volcanicinternet.com\/app\/uploads\/2026\/08\/Making-complex-tables-accessible.png","datePublished":"2026-08-27T05:00:00+00:00","description":"Learn how to build accessible HTML tables with proper headers, row groups, captions, and multi-level relationships for screen reader.","breadcrumb":{"@id":"https:\/\/volcanicinternet.com\/en\/making-complex-tables-accessible\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/volcanicinternet.com\/en\/making-complex-tables-accessible\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/volcanicinternet.com\/en\/making-complex-tables-accessible\/#primaryimage","url":"https:\/\/volcanicinternet.com\/app\/uploads\/2026\/08\/Making-complex-tables-accessible.png","contentUrl":"https:\/\/volcanicinternet.com\/app\/uploads\/2026\/08\/Making-complex-tables-accessible.png","width":1000,"height":500},{"@type":"BreadcrumbList","@id":"https:\/\/volcanicinternet.com\/en\/making-complex-tables-accessible\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Inici","item":"https:\/\/volcanicinternet.com\/en\/"},{"@type":"ListItem","position":2,"name":"Making complex tables accessible"}]},{"@type":"WebSite","@id":"https:\/\/volcanicinternet.com\/en\/#website","url":"https:\/\/volcanicinternet.com\/en\/","name":"Volcanic Internet","description":"P\u00e0gines web, aplicacions m\u00f2bils, desenvolupament a mida","publisher":{"@id":"https:\/\/volcanicinternet.com\/en\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/volcanicinternet.com\/en\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/volcanicinternet.com\/en\/#organization","name":"Volcanic Internet","url":"https:\/\/volcanicinternet.com\/en\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/volcanicinternet.com\/en\/#\/schema\/logo\/image\/","url":"https:\/\/volcanicinternet.com\/app\/uploads\/2026\/08\/volcanic_logo.png","contentUrl":"https:\/\/volcanicinternet.com\/app\/uploads\/2026\/08\/volcanic_logo.png","width":642,"height":80,"caption":"Volcanic Internet"},"image":{"@id":"https:\/\/volcanicinternet.com\/en\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/volcanicinternet","https:\/\/x.com\/volcanictech","https:\/\/es.linkedin.com\/company\/volcanic-internet"],"description":"Implantaci\u00f3n de IA con Claude, desarrollo web y accesibilidad digital","areaServed":["ES","EU","LATAM"],"knowsAbout":["Claude IA","Desarrollo Web","Accesibilidad Web"]},{"@type":"Person","@id":"https:\/\/volcanicinternet.com\/en\/#\/schema\/person\/409c516eedd21dff3ffd020f75ba42fe","name":"Fran Rosa","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/1d51829327994fc3b0c6f1d6d853c8242a493a21590d75432104e00e4425ba2b?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/1d51829327994fc3b0c6f1d6d853c8242a493a21590d75432104e00e4425ba2b?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/1d51829327994fc3b0c6f1d6d853c8242a493a21590d75432104e00e4425ba2b?s=96&d=mm&r=g","caption":"Fran Rosa"},"description":"Senior developer and advocate focused on peope-first development","url":"https:\/\/volcanicinternet.com\/en\/author\/fran-rosa\/"}]}},"taxonomy_info":{"category":[{"value":33,"label":"Accessibility"}]},"featured_image_src_large":["https:\/\/volcanicinternet.com\/app\/uploads\/2026\/08\/Making-complex-tables-accessible.png",1000,500,false],"author_info":{"display_name":"Fran Rosa","author_link":"https:\/\/volcanicinternet.com\/en\/author\/fran-rosa\/"},"comment_info":0,"category_info":[{"term_id":33,"name":"Accessibility","slug":"accessibility","term_group":0,"term_taxonomy_id":33,"taxonomy":"category","description":"","parent":0,"count":19,"filter":"raw","cat_ID":33,"category_count":19,"category_description":"","cat_name":"Accessibility","category_nicename":"accessibility","category_parent":0}],"tag_info":false,"_links":{"self":[{"href":"https:\/\/volcanicinternet.com\/en\/wp-json\/wp\/v2\/posts\/6559","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/volcanicinternet.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/volcanicinternet.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/volcanicinternet.com\/en\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/volcanicinternet.com\/en\/wp-json\/wp\/v2\/comments?post=6559"}],"version-history":[{"count":20,"href":"https:\/\/volcanicinternet.com\/en\/wp-json\/wp\/v2\/posts\/6559\/revisions"}],"predecessor-version":[{"id":6626,"href":"https:\/\/volcanicinternet.com\/en\/wp-json\/wp\/v2\/posts\/6559\/revisions\/6626"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/volcanicinternet.com\/en\/wp-json\/wp\/v2\/media\/6604"}],"wp:attachment":[{"href":"https:\/\/volcanicinternet.com\/en\/wp-json\/wp\/v2\/media?parent=6559"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/volcanicinternet.com\/en\/wp-json\/wp\/v2\/categories?post=6559"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/volcanicinternet.com\/en\/wp-json\/wp\/v2\/tags?post=6559"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}