Screen reader pronouncing state/country codes and numbers - html

I have a table that contains location information. I wanted to hear how a screen reader would interpret my markup. Sure enough it read 'CA' as the letters C and A. It also did the same thing for the table cell with an age, it read '23' as 2 3. Is there a way to mark these items and others like that in a way that screen readers will read them as 'California' and 'twenty three' without actually spelling them out?
EDIT: Added the title attr alongside with the regular text. The screenreader reads: "Age, group, twenty three, 2 3"
I also tried adding an aria-hidden="true" to a span nested inside of the <td> but it completely skipped the td and the span and moved onto the next element.
Markup:
<table>
<tbody>
<tr>
<th scope="row">First Name</th>
<td>John</td>
</tr>
<tr>
<th scope="row">Age</th>
<td title="Twenty Three">23</td>
</tr>
<tr>
<th scope="row">State</th>
<td tithe="California">CA</td>
</tr>
</tbody>
</table>
ARIA-hidden:
<table>
<tbody>
<tr>
<th scope="row">Age</th>
<td title="Twenty Three"><span aria-hidden="true">23</span></td>
</tr>
</tbody>
</table>

yes, you can use a title attribute to make it easyer for people with screen readers
<table>
<tbody>
<tr>
<th scope="row">First Name</th>
<td>John</td>
</tr>
<tr>
<th scope="row">Age</th>
<td title="twentythree">23</td>
</tr>
<tr>
<th scope="row">State</th>
<td title="California">CA</td>
</tr>
</tbody>
</table>
A screen reader will read the title text rather then the content, so you can add screen reader friendly text for any table cell

Related

Accessible Table with Sub Headings / Category Separation

EDIT: To the person who tagged this as having nothing to do with ADA. This question has everything to do with ADA. I have tons of websites with tables formatted like that which I am trying to figure out how to make them understandable to someone using a screen reader.
Hello I am trying to figure out a way to make a table which has subheadings / separator rows to announce the proper headings when being read by a screen reader.
The first table works as I would like, announcing the rowgroup's TH and then the column heading. However the second table doesn't announce as I was hoping. For example, Jill announces "Field Techs, Name, Jill" Instead of "Office, Name, Jill" as I had expected.
I've tried scope="col" and scope="colgroup" but neither helped. Is this even possible? or just a badly structured table?
Thank you for reading and any help/advice you may offer!
table thead, table th { background:#d3d3d3; }
table { margin-bottom:40px; }
<!-- This table's headings seem to work properly -->
<table width="100%" cellspacing="0" cellpadding="4" >
<thead>
<tr>
<td> </td>
<th id="name_col" scope="col" width="50%">Name</th>
<th id="position_col" scope="col" width="50%">Position</th>
</tr>
</thead>
<tbody>
<tr>
<th id="office_row" scope="rowgroup" rowspan="2">Office</th>
<td headers="office_row name_col">Jill</td>
<td headers="office_row position_col">Office Manager</td>
</tr>
<tr>
<td headers="office_row name_col">Robert</td>
<td headers="office_row position_col">Project Manager</td>
</tr>
<tr>
<th id="field_row" scope="rowgroup" rowspan="2">Field Techs</th>
<td headers="field_row name_col">Jason</td>
<td headers="field_row position_col">Tech</td>
</tr>
<tr>
<td headers="field_row name_col">Mike</td>
<td headers="field_row position_col">Tech</td>
</tr>
</tbody>
</table>
<!-- This table's headings don't announce correctly. Jill announces "Field Techs, Name, Jill"-->
<table width="100%" cellspacing="0" cellpadding="4" >
<thead>
<tr>
<th id="name_col" scope="col" width="50%">Name</th>
<th id="position_col" scope="col" width="50%">Position</th>
</tr>
<tr>
<th id="office_group" colspan="2">Office</th>
</tr>
</thead>
<tbody>
<tr>
<td headers="office_group name_col">Jill</td>
<td headers="office_group position_col">Office Manager</td>
</tr>
<tr>
<td headers="office_group name_col">Robert</td>
<td headers="office_group position_col">Project Manager</td>
</tr>
</tbody>
<thead>
<tr>
<th id="field_group" colspan="2">Field Techs</th>
</tr>
</thead>
<tbody>
<tr>
<td headers="field_group name_col">Jason</td>
<td headers="field_group position_col">Tech</td>
</tr>
<tr>
<td headers="field_group name_col">Mike</td>
<td headers="field_group position_col">Tech</td>
</tr>
</tbody>
</table>
table can only have zero or one thead element (see documentation).
Permitted contents : An optional caption element, followed by zero or more colgroup elements, followed by an optional thead element
By having multiple thead elements only the last one is considered by your browser and your screenreader. You can use ARIA attributes and roles to handle multiple separated heading lines (using for instance aria-labelledby attribute to specify the heading).
One example from WCAG:
ARIA9: Using aria-labelledby to concatenate a label from several text nodes
You are using both the scope method and header/id's method in one table, which will create problems. Also, as others have pointed out, you're using multiple <th> and <tbody> elements, which isn't good either.
I've prepared some code samples here on how to correctly code this table using both the scope method and header/id's method:
https://jsfiddle.net/oody1b8x/
It's worth noting that <th> and <tbody> are not accessibility-related elements, even though they appear to be. These are essentially only used when printing. It lets the printer know that the header rows can be repeated on the next page if the table requires pagination.
Also -- don't use ARIA for this purpose; it will only create more problems. The native HTML semantics are perfectly capable of communicating how this data is structured.

HTML5 - 2017 right way to order <tbody> and <tfoot> elements?

everyone!
I've saw in many articles and courses that the <tfoot> in a table element should be placed before the <tbody> element. Right... But, when I do it this way, the validator (https://validator.w3.org) tell me it's wrong, and that I can't use the <tfoot> in this context. So I decided to put the <tfoot> after the <tbody> and the validator don't found any errors in my code.
So... What is the correct way to do it, anyway?
I also found that spec that seems to be contradicted to its own: https://www.w3.org/TR/html51/tabular-data.html#the-tfoot-element
The <tfoot> spec rules were changed in December 2015 to disallow <tfoot> before <tbody> due to the accessibility issues it was causing.
As far as the W3C spec goes, the place to look for the relevant requirement is actually in the part of the spec that states the rules for what is allowed in the <table> element, which says:
In this order: optionally a caption element, followed by zero or more colgroup elements, followed optionally by a thead element, followed by either zero or more tbody elements or one or more tr elements, followed optionally by a tfoot element, optionally intermixed with one or more script-supporting elements.
Notice that it says tfoot is allowed after tbody but no longer says it’s allowed before tbody.
A <table> element. The <tfoot> must appear after any <caption>, <colgroup>, <thead>, <tbody>, or <tr> element. Note that this is the requirement as of HTML5.
The element cannot be placed after any <tbody> and <tr> element. Note that this directly contradicts the above normative requirement from HTML5.
<table border="1" align="center">
<caption>A table</caption>
<thead>
<tr>
<th colspan="3">Invoice #123456789</th>
<th>14 January 2025
</tr>
<tr>
<td colspan="2">
<strong>Pay to:</strong><br> Acme Billing Co.<br> 123 Main St.<br> Cityville, NA 12345
</td>
<td colspan="2">
<strong>Customer:</strong><br> John Smith<br> 321 Willow Way<br> Southeast Northwestershire, MA 54321
</td>
</tr>
</thead>
<tbody>
<tr>
<th>Name / Description</th>
<th>Qty.</th>
<th>#</th>
<th>Cost</th>
</tr>
<tr>
<td>Paperclips</td>
<td>1000</td>
<td>0.01</td>
<td>10.00</td>
</tr>
<tr>
<td>Staples (box)</td>
<td>100</td>
<td>1.00</td>
<td>100.00</td>
</tr>
</tbody>
<tfoot>
<tr>
<th colspan="3">Subtotal</th>
<td> 110.00</td>
</tr>
<tr>
<th colspan="2">Tax</th>
<td> 8% </td>
<td>8.80</td>
</tr>
<tr>
<th colspan="3">Grand Total</th>
<td>$ 118.80</td>
</tr>
</tfoot>
</table>

How can I make a HTML table with headers in one vertical column?

I want to make a HTML file that has the headers in one vertical column, and the data in the column to the right. There will only be 2 columns in total. I've looked at the html docs and seen stuff about scope, but I'm not entirely sure how to use it in this context. Example:
The HTML is pretty straightforward, just be sure to use the [scope] attribute to specify the correct orientation of the table.
<table>
<tbody>
<tr>
<th scope="row">City</th>
<td>$city</td>
</tr>
<tr>
<th scope="row">Latitude</th>
<td>$latitude</td>
</tr>
<tr>
<th scope="row">Longitude</th>
<td>$longitude</td>
</tr>
<tr>
<th scope="row">Country</th>
<td>$country</td>
</tr>
</tbody>
</table>
From the docs for the [scope] attribute:
The row state means the header cell applies to some of the subsequent cells in the same row(s).
You can create the tables with elements proceeded by elements like so:
<table>
<tr>
<th scope="row">Category 1</th><td>data1</td>
</tr>
<tr>
<th scope="row">Category 2</th><td>data2</td>
</tr>
<tr>
<th scope="row">Category 3</th><td>data3</td>
</tr>
Here is an example of it in action:
vertical headers

strucure of component inside table html

I want to make a table of orders, for each row there's an arrow that show a bill details related to each order and hide when I click again on the button.
How can I make the structure of the table?
I make like this
<table id="customerTable">
<thead>
<tr>
<td>customer name </td>
<td>order date</td>
<td>sale point</td>
<td>total</td>
</tr>
</thead>
<tr>
<td>customer name </td>
<td>order date</td>
<td>sale point</td>
<td>total</td>
<td>show details</td>
</tr>
//also loop here as the number of bills
<tr>
<td>bill order/td>
<td>product</td>
<td>price</td>
</tr>
I don't think like this structure is correct, and making div inside a table doesn't work, any suggestion please?
Possible structure:
<table id="customerTable">
<thead>
<tr>
<td>customer name </td>
<td>order date</td>
<td>sale point</td>
<td>total</td>
<td></td>
</tr>
</thead>
<tbody>
<tr class="master">
<td>customer name </td>
<td>order date</td>
<td>sale point</td>
<td>total</td>
<td>
show details
</td>
</tr>
<tr class="detail">
<td colspan=5>
<!-- new <table> with your details of this row -->
</td>
</tr>
<!-- ... more rows ... --->
</tbody>
</table>
Example: http://jsfiddle.net/J7szf/
Example 2: http://jsfiddle.net/J7szf/1/
You can probably use a popup near the "Show Details" Link
Example : http://jsfiddle.net/vdcUA/93/
If you want the content to be displayed in the table itself , provide here some idea on how u want the content displayed
In your example, you have an extra unneeded <tr> before your loop. You should have a standard table structure but hide / show the details depending on a click.
You'd better use:
styling with css and classes the standard row and the details
using js to hide / show rows
Actually, you could use jquery plugins to do this kind of stuff. See this example of datatables grouping rows
Jqgrid can also make some row grouping
[EDIT] The easiest way to define your HTML structure is to get inspired from the HTML in these jquery plugin examples

HTML Table issue

I have a HTML table issue that I'd like to understand better.
Let's assume that I have a 3 row HTML
<table>
<tr>
<td style="text-align:right;">A1</td>
<td>A2</td>
</tr>
<tr>
<td style="text-align:right;">B1</td>
<td>B2</td>
</tr>
<tr>
<td colspan="2">A very loooooooong string here</td>
</tr>
</table>
With a very long text, the contents in the first 2 rows appear like they are nearly centered. However, if I move the whole "A very long string" <td> into a separate <table> inside the row, I see that the other content doesn't center. Why is the display different when the <td> content is inside another table?
If your question ends up with 2 tables, with the original like this:
<table>
<tr>
<td style="text-align:right;">A1</td>
<td>A2</td>
</tr>
<tr>
<td style="text-align:right;">B1</td>
<td>B2</td>
</tr>
</table>
And the looooong text into its own:
<table>
<tr>
<td colspan="2">A very loooooooong string here</td>
</tr>
</table>
Then the reason why the first two lines of the first table no longer look like they're centred is because they're not - ONLY if you're comparing relative to the second table.
If you debug with border="1" in your TABLE attributes, you will see that the table that they are contained in collapses to the widest possible table data cell. Because of this, they don't look like they're centred, even though they still are.
Add some arbitrary width to the first table and you will see that they are still centred.
Can you please provide your second example? When I created the following, it still looked the same. There's a chance you didn't properly embed the table within a table cell with a colspan of 2.
<table border="1">
<tr>
<td style="text-align:right;">A1</td>
<td>A2</td>
</tr>
<tr>
<td style="text-align:right;">B1</td>
<td>B2</td>
</tr>
<tr>
<td colspan="2">
<table border="1"><tr>
<td>A very loooooooong string here</td>
</tr></table>
</td>
</tr>
</table>
When explaining an issue with HTML, it is best to indicate which browsers were used to test...
Anyway, I did a quick test with FF3 and IE6, and I don't see the behavior you describe: with nested table, the long string has slightly more padding but the other content is still visually centered.
You should show your other code. Mine is:
<table>
<tr>
<td style="text-align:right;">A1</td>
<td>A2</td>
</tr>
<tr>
<td style="text-align:right;">B1</td>
<td>B2</td>
</tr>
<tr>
<td colspan="2"><table><tr><td>A very loooooooong string here</td></tr></table></td>
</tr>
</table>
I think I know what you mean, is the second part of your question based on:
<table>
<tr>
<td style="text-align:right;">A1</td>
<td>A2</td>
</tr>
<tr>
<td style="text-align:right;">B1</td>
<td>B2</td>
</tr>
<tr>
<table><td colspan="2">A very loooooooong string here</td></table>
</tr>
</table>
then I guess the reason the table contents are rendered left-aligned is that the inner table tags are hiding the colspan from the outer table.
The answer is to stop using html to style your table and to use CSS instead!