Proper HTML Table Structure? - html

Almost embarrassed to ask, because I have never had a need to use tables much before...
Now I have a project that will require massive organized tables, go figure.
Suppose I have a table like this:
<table border="1px" style="width:300px">
<thead>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Age</th>
</tr>
</thead>
<tbody>
<tr>
<td>Jill</td>
<td>Smith</td>
<td>50</td>
</tr>
<tr>
<td>Eve</td>
<td>Jackson</td>
<td>94</td>
</tr>
<tr>
<td>John</td>
<td>Doe</td>
<td>80</td>
</tr>
</tbody>
</table>
First of all, from what I have read, <thead> and <tbody> seem to be optional for grouping purposes, but is this basic set up correct?
It looks fine when displayed in a browser, but I wonder if my code actually structures elements correctly in the DOM? I.E. does the DOM correctly associate the <th>First Name</th> with the <td>'s that contain the first name data? I ask because I am going to need to rely on that to sort the tables later with javascript.
I apologize if this is really simple question. If there is a reference to a "proper table structure" article, i will accept that as well.

Your HTML markup is fine, except you should favor CSS classes rather than inline styles, and the border attribute is usually better as a style.
If you are ever curious if you have valid markup, you can use a validator tool to check. There is one available here, provided by W3C: http://validator.w3.org/
HTML is a presentational markup. There is no data association implicit in any given element -- that is to say, the td which you know contains the first name does not in any way associate itself with the heading which labels it visually. As far as HTML is concerned, you don't have data, just a bunch of words which it shapes and boxes and moves around on the screen.
This extends to javascript -- there is no association between the heading and table cells in DOM.
That said, sorting tables are a very common UI pattern, and you can find a large number of examples as well as existing plugins. I highly recommend that you consider an established plugin if you are going to use this for anything other than a learning experience. The plugin author has, presumably, already considered all the many ins and outs, gotchyas, and cross-browser considerations that you would have to take in to account if you tried to craft your own.
Documentation
MDN Tables - https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_started/Tables
MDN <table> element - https://developer.mozilla.org/en-US/docs/Web/HTML/Element/table
MDN HTMLTableElement - https://developer.mozilla.org/en-US/docs/Web/API/HTMLTableElement

Best html table structure and css concept :
<table cellpadding="0" cellspacing="0" width="100%" class="table">
<thead>
<tr>
<th>Header1</th>
<th>Header2</th>
<th>Header3</th>
</tr>
</thead>
<tfoot>
<tr>
<th>Footer1</th>
<th>Footer2</th>
<th>Footer3</th>
</tr>
</tfoot>
<tbody>
<tr>
<td>data1</td>
<td>data2</td>
<td>data3</td>
</tr>
<tr>
<td>data1</td>
<td>data2</td>
<td>data3</td>
</tr>
<tr>
<td>data1</td>
<td>data2</td>
<td>data3</td>
</tr>
<tr>
<td>data1</td>
<td>data2</td>
<td>data3</td>
</tr>
<tr>
<td>data1</td>
<td>data2</td>
<td>data3</td>
</tr>
</tbody>
</table>
css code and structure
<style>
html, body{font-family:Arial, Helvetica, sans-serif; font-size:12px;}
.table{border-collapse:collapse; width:100%}
.table thead th, .table tfoot th{text-align:center; background:#999; color:#FFFFFF;}
.table th, .table td{padding:5px; border:1px solid #ddd;}
.table tr:nth-child(even){background:#eee;}
</style>

Related

Making a table responsive using CSS

I have a table to represent some data in html page.I'm trying to make this table as responsive by CSS.
<table>
<tr>
<thead>
<th>Name</th>
<th>Age</th>
<th>Tell</th>
</thead>
<tbody>
<tr>
<td>Maya</td>
<td>22</td>
<td>2222555666</td>
</tr>
</tbody>
</tr>
</table>
I used to to do that by this way:
table thead {display:none}
table tr, table td{display:block}
table td:nth-of-type(1)::before {content: "Name";}
There is a problem, this way can be helpful when I know there are how many <td></td> and what the content of <th></th> is , but in this case I do not know the number of <td></td> and also the content of <th></th>?
What can I do?

Text size is really big in one column of a table, really small in the others

My webpage does not have any css or text formatting, but the column text is coming out really huge, and in the worst place, too.
<table border="1">
<tr>
<th>Clinical Trials ID</th>
<th>Official Title</th>
<th>Contact Name</th>
<th>Affiliation</th>
<th>Phone</th>
<th>email</th>
</tr>
<tr>
<td>NCT01951326</td>
<td>A Randomized, Double Blind, Placebo-controlled, Multicenter, Parallel Group Study to Assess the Efficacy and Safety of Fixed-dose Combination RHB-104 in Subjects With Moderately to Severely Active Crohn's Disease</td>
<td> Ira N Kalfus, MD</td>
<td>RedHill Biopharma</td>
<td> </td>
<td></td>
</tr>
</table>
I can't post screenshots because I don't have enough rep
Thanks for your help
I have probably got your error.
Your code seems to be missing a meta tag. Add this to your head tag:
<meta name="viewport" content="width=device-width, initial-scale=1.0">
And you'll be good to go.
Hope it helps. Cheers!!
Set a width for your td otherwise it will take all the space it gets free to take.
<table border="1">
<tr>
<th>Clinical Trials ID</th>
<th>Official Title</th>
<th>Contact Name</th>
<th>Affiliation</th>
<th>Phone</th>
<th>email</th>
</tr>
<tr>
<td>NCT01951326</td>
<td width="40%">A Randomized, Double Blind, Placebo-controlled, Multicenter, Parallel Group Study to Assess the Efficacy and Safety of Fixed-dose Combination RHB-104 in Subjects With Moderately to Severely Active Crohn's Disease</td>
<td> Ira N Kalfus, MD</td>
<td>RedHill Biopharma</td>
<td> </td>
<td></td>
</tr>
</table>
A little bit of CSS can fix this problem. The calc function might be especially useful:
th{
width: calc(100%/6);
}
<table border="1">
<tr>
<th>Clinical Trials ID</th>
<th>Official Title</th>
<th>Contact Name</th>
<th>Affiliation</th>
<th>Phone</th>
<th>email</th>
</tr>
<tr>
<td>NCT01951326</td>
<td>A Randomized, Double Blind, Placebo-controlled, Multicenter, Parallel Group Study to Assess the Efficacy and Safety of Fixed-dose Combination RHB-104 in Subjects With Moderately to Severely Active Crohn's Disease</td>
<td> Ira N Kalfus, MD</td>
<td>RedHill Biopharma</td>
<td> </td>
<td></td>
</tr>
</table>

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>

HTML Tables - can I have an additional tbody before the thead?

I need add to some elements on top of a table in line with the columns of the said table.
This table contains a <thead> (which is required due to jquery.tablesorter plugin). I assumed that if I put another <tbody> on top of the <thead> I would be able to keep these elements in line with the rest of the columns, but both chrome and firefox render every <tbody> below the <thead>.
Example:
<table>
<tbody>
<tr>
<td>1</td><td>1</td><td>1</td>
</tr>
</tbody>
<thead>
<tr>
<th>head</th><th>head</th><th>head</th>
</tr>
</thead>
<tbody>
<tr>
<td>2</td><td>2</td><td>2</td>
</tr>
<tr>
<td>3</td><td>3</td><td>3</td>
</tr>
<tr>
<td>4</td><td>4</td><td>4</td>
</tr>
</tbody>
</table>
Although I understand this, I still need to find a way to have these elements stay in line with specific columns.
You can use multiple rows in <thead> like this:-
<table>
<thead>
<tr> <td>1</td> <td>1</td> </tr>
<tr> <td>head</td> <td>head</td> </tr>
</thead>
</table>
I recommend that you use an id (#) marker to identify that part that you want the js to work off and have the js use that id.
With that, have the thead first and the tbody last.
The variations you are describing may work - in the browser you using now, on the OS you are ok - and may be compliant a certain version of the HTML spec- but putting things in an unusual order is (in my expereince) just the kind of thing to not work, or work the same, everywhere and to eventually be the cause of much frustration, especially as the site grows in complexity.
One solution is to use another table inside one tr, in your thead. Althought, this is a totally ugly solution.
You can also place a div above your table using CSS.
Correct table structure is:
<table>
<thead>
<tr>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td></td>
</tr>
</tbody>
<tfoot>
<tr>
<th></th>
<th></th>
</tr>
</tfoot>
</table>
<thead> will always be on the top and <tfoot> will always be at the bottom.
Using jQuery you can swap <thead> and <tbody> content by:
$(document).ready(function() {
$('#myTrigger').click(function() {
var top = $('thead').html();
var mid = $('tbody').html();
$('thead').html(mid);
$('tbody').html(top);
});
});