Writing accurate <th> for accessible <table> - html

I am following the UN's accessibility guidelines to write accessible table.
I have this table. I made what -I think- should be a <th> bold.
This is the HTML:
<table width="100%">
<thead>
<tr>
<th>Year</th>
<th>1991</th>
<th>1995</th>
<th>2000</th>
<th>2002</th>
<th>2007</th>
</tr>
</htead>
<tbody>
<tr>
<th>Indicator 1</th>
<td>3.0</td>
<td>11.0</td>
<td>7.8</td>
<td>4.0</td>
<td>4.7</td>
</tr>
<tr>
<th>Indicator 2</th>
<td>9.0</td>
<td>23.4</td>
<td>19.5</td>
<td>9.4</td>
<td>9.1</td>
</tr>
<tr>
<th>Indicator 3</th>
<td>18.7</td>
<td>32.0</td>
<td>30.0</td>
<td>20.1</td>
<td>21.8</td>
</tr>
</tbody>
</table>
But I am not sure it is accurate. I think this makes more sense:
<table>
<tbody>
<tr>
<th id="year">Year</th>
<td headers="year" id="year-1991">1991</td>
<td headers="year" id="year-1995">1995</td>
<td headers="year" id="year-2000">2000</td>
<td headers="year" id="year-2002">2002</td>
<td headers="year" id="year-2007">2007</td>
</tr>
<tr>
<th id="indicator-1">Indicator 1</th>
<td headers="indicator-1 year-1991">3.0</td>
<td headers="indicator-1 year-1995">11.0</td>
<td headers="indicator-1 year-2000">7.8</td>
<td headers="indicator-1 year-2002">4.0</td>
<td headers="indicator-1 year-2007">4.7</td>
</tr>
<tr>
<th id="indicator-2">Indicator 2</th>
<td headers="indicator-2 year-1991">9.0</td>
<td headers="indicator-2 year-1995">23.4</td>
<td headers="indicator-2 year-2000">19.5</td>
<td headers="indicator-2 year-2002">9.4</td>
<td headers="indicator-2 year-2007">9.1</td>
</tr>
<tr>
<th id="indicator-3">Indicator 3</th>
<td headers="indicator-3 year-1991">18.7</td>
<td headers="indicator-3 year-1995">32.0</td>
<td headers="indicator-3 year-2000">30.0</td>
<td headers="indicator-3 year-2002">20.1</td>
<td headers="indicator-3 year-2007">21.8</td>
</tr>
</tbody>
</table>
What do you think? Does anyone have experience with tables and accessibility? Please provide references if possible. Thanks.
Note: I am aware of the summary attribute but I removed it here for simplicity.

For a table with a simple structure like this, your markup (the first, simple version) is sufficient for accessibility. A table with similar structure appears in HTML and XHTML Techniques for WCAG 2.0, item Using table markup to present tabular information, with no extra markup, just th for header cells.
Special techniques may be need for structurally more complicated tables.
However, a data table should normally have a caption element for accessibility and usability. It helps the user get key information about the table as a whole. Instead of a caption, a heading or just text before the table could be used for the purpose, but they do not associate with the table (at the markup level) the same way.

I found that using the scope attribute makes more sense:
<table width="100%">
<thead>
<tr>
<th scope="col">Year</th>
<th scope="col">1991</th>
<th scope="col">1995</th>
<th scope="col">2000</th>
<th scope="col">2002</th>
<th scope="col">2007</th>
</tr>
</htead>
<tbody>
<tr>
<th scope="row">Indicator 1</th>
<td>3.0</td>
<td>11.0</td>
<td>7.8</td>
<td>4.0</td>
<td>4.7</td>
</tr>
<tr>
<th scope="row">Indicator 2</th>
<td>9.0</td>
<td>23.4</td>
<td>19.5</td>
<td>9.4</td>
<td>9.1</td>
</tr>
<tr>
<th scope="row">Indicator 3</th>
<td>18.7</td>
<td>32.0</td>
<td>30.0</td>
<td>20.1</td>
<td>21.8</td>
</tr>
</tbody>
Reference: Use the th element to specify row and column headers in data tables | 456 Berea St

Related

HTML table, are headers Attribute columns identifiers?

I want to give to each of my table <th>'s an identifier, so It won't matter the other when I am using the <td> (while I know the identifier), I found this (HTML headers Attribute), which seems like what I need:
<table>
<tr>
<th id="name">Name</th>
<th id="email">Email</th>
</tr>
<tr>
<td headers="name">John Doe</td>
<td headers="email">someone#example.com</td>
</tr>
</table>
But I change the order of the <td>'s like this, first the email and then the name:
<table>
<tr>
<th id="name">Name</th>
<th id="email">Email</th>
</tr>
<tr>
<td headers="email">someone#example.com</td>
<td headers="name">John Doe</td>
</tr>
</table>
And as you can see the result that I get is the same.
The header attribute has no effect on presentation; it will not swap table cells around. The header attribute simply denotes which <th> cells the <td> cells relate to for the purposes of enhancing screen readers:
This allows screen readers to speak the headers associated with each data cell when the relationships are too complex to be identified using the <th> element alone or the <th> element with the scope attribute.
Note that each <td> cell can relate to more than one header cell, if the table contains more than one header row. For example:
<table>
<tr>
<th rowspan="2" id="h">Homework</th>
<th colspan="3" id="e">Exams</th>
<th colspan="3" id="p">Projects</th>
</tr>
<tr>
<th id="e1" headers="e">1</th>
<th id="e2" headers="e">2</th>
<th id="ef" headers="e">Final</th>
<th id="p1" headers="p">1</th>
<th id="p2" headers="p">2</th>
<th id="pf" headers="p">Final</th>
</tr>
<tr>
<td headers="h">15%</td>
<td headers="e e1">15%</td>
<td headers="e e2">15%</td>
<td headers="e ef">20%</td>
<td headers="p p1">10%</td>
<td headers="p p2">10%</td>
<td headers="p pf">15%</td>
</tr>
</table>
In order to swap table cells around, you'd be much better off using either flexbox (making use of flex-direction) or a JavaScript solution.

how to write accessible html table?

A table on my site has been flagged by an accessibility plugin (aXe). After some tinkering, it ended up saying that I had to fix the following two things:
<th> elements should only be used when there is a single row and
single column of headers
Table has cells whose rowspan attribute is not equal to 1
How can I reasonably build a table with nested levels of information without violating at least one of those?
My table code is:
<table>
<tbody>
<tr>
<th scope="col" rowspan="2">Type Of</th>
<th scope="col" colspan="2">Blue</th>
<th scope="col" colspan="2">Green</th>
</tr>
<tr>
<td scope="col" class="centered">Light Blue</td>
<td scope="col" class="centered">Dark Blue</td>
<td scope="col" class="centered">Light Green</td>
<td scope="col" class="centered">Dark Green</td>
</tr>
<tr>
<th scope="row">Type 1</th>
<td class="centered">Y</td>
<td class="centered">Y</td>
<td class="centered">Y</td>
<td class="centered">N</td>
</tr>
<tr>
<th scope="row">Type 2</th>
<td class="centered">Y</td>
<td class="centered">Y</td>
<td class="centered">Y</td>
<td class="centered">N</td>
</tr>
<tr>
<th scope="row">Type 3</th>
<td class="centered">Y</td>
<td class="centered">Y</td>
<td class="centered">Y</td>
<td class="centered">N</td>
</tr>
</tbody>
</table>
Accessibility tools are free to invent their own rules, but this tool is wrong saying you should remove table headers th when you use rowspan or colspan. It's totally wrong. Check that you have the last version of this tool : this is an awful advice.
In your case, you can use the following technique to mark column headers:
H43: Using id and headers attributes to associate data cells with header cells in data tables
Your have one problem in your example:
Your headers in your second line are not marked as column headers (th) (and headers attribute should only reference th with id).
You markup should be something like:
<table>
<thead>
<tr>
<th rowspan="2" id="typeof">Type Of</th>
<th colspan="2" id="blue">Blue</th>
<th colspan="2" id="green">Green</th>
</tr>
<tr>
<th id="lightblue">Light</th>
<th id="darkblue">Dark</th>
<th id="lightgreen">Light</th>
<th id="darkgreen">Dark</th>
</tr>
</thead>
<tbody>
<tr>
<th id="type1" headers="typeof">Type 1</th>
<td headers="type1 lightblue" title="Yes">Y</td>
<td headers="type1 darkblue" title="Yes">Y</td>
<td headers="type1 lightgreen" title="Yes">Y</td>
<td headers="type1 darkgreen" title="No">N</td>
</tr>
<tr>
<th id="type2" headers="typeof">Type 2</th>
<td headers="type2 lightblue" title="Yes">Y</td>
<td headers="type2 darkblue" title="Yes">Y</td>
<td headers="type2 lightgreen" title="Yes">Y</td>
<td headers="type2 darkgreen" title="No">N</td>
</tr>
<tr>
<th id="type3" headers="typeof">Type 3</th>
<td headers="type3 lightblue" title="Yes">Y</td>
<td headers="type3 darkblue" title="Yes">Y</td>
<td headers="type3 lightgreen" title="Yes">Y</td>
<td headers="type3 darkgreen" title="No">N</td>
</tr>
</tbody>
</table>
Also, I added a title attribute in order to add a speakable alternative for screen readers (you could have used aria-label but title adds a tooltip for other people, except it is not keyboard friendly). Better choice would be to have here a full word.
I'm not sure what tool you are using, but have you tried using col and colgroup elements? There is some basic information here from W3C about irregular headers in data tables.
Also, I put together a quick JSFiddle based on your table if you want to look at that: https://jsfiddle.net/dngvc84o/

Trying to span both rows and columns in an HTML table

I am trying to create a table in HTML that does both row and column spanning. I've nailed most of it, but the upper right has two blank rows that I would like to span. Here's what I have so far (it's a confusion matrix--that's an understatement):
<table>
<tr>
<th colspan="2"></th>
<th colspan="2">Class</th>
</tr>
<tr>
<th colspan="2"></th>
<td>Loyal</td>
<td>Churn</td>
</tr>
<tr>
<th rowspan="2">Pred. class</th>
<td>Predicted loyal</td>
<td>TN</td>
<td>FN</td>
</tr>
<tr>
<td>Predicted churn</td>
<td>FP</td>
<td>TP</td>
</tr>
</table>
Is that possible? Thanks for any assistance.
You mean the upper left right?
<table>
<tr>
<th colspan="2" rowspan="2"></th>
<th colspan="2">Class</th>
</tr>
<tr>
<td>Loyal</td>
<td>Churn</td>
</tr>
<tr>
<th rowspan="2">Pred. class</th>
<td>Predicted loyal</td>
<td>TN</td>
<td>FN</td>
</tr>
<tr>
<td>Predicted churn</td>
<td>FP</td>
<td>TP</td>
</tr>
</table>
http://jsfiddle.net/j0Ln2uwm/

Shrinking one cell in a table

I am trying to shrink one cell in the table, but it refuses to shring..here is my table.
<table cellspacing="0" style="position: absolute;width: 990px;margin-left: 8px;" align="center">
<thead>
<tr class='no-wrap'>
<th width="20%"></th>
<th width="10%">Our Rating</th>
<th width="10%">Users' Rating</th>
<th width="30%">Review</th>
<th width="30%">Price</th>
</tr>
</thead>
<tbody>
<tr>
<td width="20%"></td>
<td width="10%">Our Rating</td>
<td width="10%">Users' Rating</td>
<td width="30%">Review</th>
<td width="30%">Price</td>
</tr>
</tbody>
</table>
The problem is that the review part doesnt shrink..even when I give it a lower percentage..why is that?
You have incorrect HTML syntax.
You need to wrap your table row elements in tr:
<tbody>
<tr>
<td></td>...
</tr>
</tbody>
Also you have a </th> where you should have a <td> on your 2nd row, 4th cell (Review):
<td width="30%">Review</th>

Adding a <th> element within a <th> element

I have an html table with one of the headers spanning over 2 columns. How can I add sub-headers to each of the 2 columns ?
For e.g. in the attached image, I want the 'Contact' column to have sub-headers 'Phone' and 'Address' for the respective columns.
The same way you would if you were drawing out the table on paper:
<table>
<thead>
<tr>
<th rowspan="2">Name</th>
<th rowspan="2">Email</th>
<th colspan="2">Contact</th>
</tr>
<tr>
<th>Phone</th>
<th>Address</th>
</tr>
</thead>
<tbody>
<!-- your data goes here -->
</tbody>
</table>
You need to have two separate header rows:
<tr>
<th rowspan="2">Name</th>
<th rowspan="2">Email</th>
<th colspan="2">Contact</th>
</tr>
<tr>
<th>Number</th>
<th>Address</th>
</tr>
Add another row and put sub headers in <td /> tags. Maybe give the row a class and style the td text? That way they won't look identical to the real headers, that might cause confusion.
<table>
<tr>
<th>Title 1</th><th>Title 2</th><th colspan="2">Title 3</th>
</tr>
<tr>
<td>content</td><td>content</td><th>subtitle 1</th><th>subtitle 2</th>
</tr>
<tr>
<td>content</td><td>content</td><td>content</td><td>content</td>
</tr>
</table>