Responsive Design with HTML Tables, make first Column appear - html

I currently have a problem making my HTML table responsive.
I have a html table where I have 4 columns, each with 25% width. On the desktop, the table looks great.
The first column has 10 rows, in each row there's a description text. The next 3 columns are product columns, where each one of them has a product with some information about it.
Since I can't show that many columns on a mobile phone, I'd like to basically have only the first column (description) + a product column shown on my mobile phone. Because otherwise, people don't know what the information stands for in the product column.
I hope someone can help me, thanks!
I already made up the table with the CSS, and tried to make each column 50% on mobile phones.
But the problem is that the first column should appear next to every product column.
Here is what I already have:
<table>
<thead>
<tr>
<th class="col-25">Preview</th>
<th class="col-25">Product 1</th>
<th class="col-25">Product 2</th>
<th class="col-25">Product 3</th>
</tr>
</thead>
<tbody>
<tr>
<th class="col-25">Description</th>
<td class="col-25">Product name 1</td>
<td class="col-25">Product name 2</td>
<td class="col-25">Product name 3</td>
</tr>
<tr>
<th class="col-25">Price</th>
<td class="col-25">Product price 1</td>
<td class="col-25">Product price 2</td>
<td class="col-25">Product price 3</td>
</tr>
</tbody>
</table>
CSS:
.table {
width: 100%;
border-collapse:collapse;
table-layout: fixed;
}
.col-25 {
width: 25%;
}

Okay, this is kind of tricky but I have a few solutions for your problem.
Try to use CSS breakpoints
If your device hits a certain width you hide the following columns.
https://www.w3schools.com/howto/howto_css_media_query_breakpoints.asp
Use Bootstrap
Bootstrap has already breakpoints built-in. You could build your table with their fantastic grid system.
https://getbootstrap.com/docs/4.3/getting-started/introduction/
https://getbootstrap.com/docs/4.1/layout/grid/
If you would post your example, I could take a further look but I think these two tips should give you an idea of how you can solve this problem yourself.
(Sorry for my bad english)

Related

How to change HTML table tab order from horizontal to vertical without tabindex?

I have an HTML table like this:
*----------*----------*
| Cell 1 | Cell 4 |
*----------*----------*
| Cell 2 | Cell 5 |
*----------*----------*
| Cell 3 | Cell 6 |
*----------*----------*
How do I change the tab order to properly run from Cell 1 to Cell 6 without using tabindex? I ask this knowing that the WAI-ARIA guidelines discourage the use of tabindex to change the tab order of cells.
I've considered breaking the table into two elements -- left and right -- so that they will have the correct order in the DOM. However, this solution does not seem to maintain the aspects of a natural HTML table (such as equal height across rows of cells).
The following works from a tab perspective but does not work for a screen reader. I'm using a <button> in the table just to demonstrate the tabbing order.
<table>
<tr>
<th>header 1</th>
<th>header 2</th>
</tr>
<tr>
<td>
<table>
<tr>
<td><button>cell 1</button></td>
</tr>
<tr>
<td><button>cell 2</button></td>
</tr>
<tr>
<td><button>cell 3</button></td>
</tr>
</table>
</td>
<td>
<table>
<tr>
<td><button>cell 4</button></td>
</tr>
<tr>
<td><button>cell 5</button></td>
</tr>
<tr>
<td><button>cell 6</button></td>
</tr>
</table>
</td>
</tr>
</table>
To tab vertically, you have to group cell1-cell3 in a container and cell4-cell6 in another container, then display the two containers side by side. Since you can't have a container span across rows in a table, you have to use a (nested) table as the container. The first cell of the main table is a nested table, so tabbing goes through the nested table (cell1-cell3) first. Then tabbing goes to the second cell of the main table, which again is a nested table (cell4-cell6).
You could try to simplify it and put cell1-cell3 in a <div> and have that <div> be the first cell of the main table, but then cell1-cell3 would not, individually, be in separate data cells, but that's up to you if that's important.
<table>
<tr>
<th>header 1</th>
<th>header 2</th>
</tr>
<tr>
<td>
<div>
<button>cell 1</button><br>
<button>cell 2</button><br>
<button>cell 3</button>
</div>
</td>
<td>
<div>
<button>cell 4</button><br>
<button>cell 5</button><br>
<button>cell 6</button>
</div>
</td>
</tr>
</table>
Getting back to the screen reader, there are keyboard shortcuts to traverse through all the cells of a table. On a PC, using JAWS or NVDA, it's ctrl+alt+arrow.
So ctrl+alt+RightArrow will let me traverse across a row. Even if you used ill-advised positive values for tabindex to control the vertical tabbing order, it will not affect the way a screen reader can navigate through a table. So if there's significant meaning in reading the table vertically, the screen reader user will lose that meaning and may not understand your table.
A few questions to consider:
Are the two columns related?
Is the table a "real" table in that it's displaying data, or is the table being used for layout purposes?
Are there column headers?
Tabbing vertically might not be necessary if the purpose of tabbing vertically can be conveyed by having sufficient row headers. Most tables have column headers but ofttimes, row headers are left off. They are very useful.
<table>
<tr>
<th scope="col">name</th>
<th scope="col">age</th>
<th scope="col">height</th>
</tr>
<tr>
<th scope="row">dave</th>
<td>12</td>
<td>4'8"</td>
</tr>
<tr>
<th scope="row">fred</th>
<td>13</td>
<td>4'9"</td>
</tr>
<tr>
<th scope="row">henry</th>
<td>14</td>
<td>4'10"</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.

How to make full width of rows when have different count of columns

How can I achieve result like in image below via CSS / HTML?
As you see first 2 rows have 2 columns, 3-4 rows have 3 columns, 5-6 rows should be full width. Problem is that I can't get different widths for different rows. Should I add class for each td and specify It's width manually? Maybe there is another way? I provided simplified sample, for reality there are over than 150 fields in table.
Here I've created JS FIDDLE too see structure of table.
<table class="tbl">
<tr>
<th>UserID </th>
<th>FirstName </th>
<th>LastName </th>
<th>Picture </th>
</tr>
<tr>
<td>UserID</td>
<td>FirstName</td>
<td>LastName</td>
<td>Picture</td>
</tr>
<tr>
<th>Rank </th>
<th>RankApplied </th>
<th>DateApplied </th>
<th>DateAvailability </th>
<th>VesselsType </th>
</tr>
<tr>
<td>Rank</td>
<td>RankApplied</td>
<td>DateAvailability</td>
<td>VesselsType</td>
</tr>
<tr>
<th>DOB </th>
<th>POB </th>
<th>Nationality </th>
<th>English </th>
</tr>
<tr>
<td>DOB</td>
<td>POB</td>
<td>Nationality</td>
<td>English</td>
</tr>
....
It's possible with several techniques.
Personally I would choose flexbox styling.
With flex: 1 1 auto; for grid-items they grow and shrink like you want.
I've put a quick example for this layout on fiddle
I use there display: flex even for the body but just to center the hole grid.
Update:
I updated the fiddle link for a more 'dynamic' layout.

Table row span cell span

This is an assignment I need help with. I hate tables as is, but this is what it says:
"The first row in each table consists of one table cell which spans two columns that contain the real estate listing name. The second row in each table consists of two table cells."
My code:
<table>
<tr>
<th>
<h3>TEST</h3>
</th>
</tr>
<th rowspan="2"></th>
<td>Something here !</td>
</tr>
</table>
Just wanted to verify if I did this correctly? Here's the full code:
http://jsfiddle.net/4jzUc/
also, it's supposed to look like this: http://screencloud.net/v/aA5Y
You want to span the column, not the row (colspan vs rowspan). I think this is what you are looking for.
<table>
<tr>
<th colspan="2">
Title
</th>
</tr>
<tr>
<td>First cell</td>
</tr>
<tr>
<td>Second cell</td>
</tr>
</table>
No, your markup is not correct. It does not even comply with the HTML table model, as you can see by using http://validator.nu on your document with <!doctype html> slapped at the start. Still less it does do what the assignment calls for.
The assignment as such is very simple: you just a table with two rows and two columns, just so that the first row has only one cell, which spans two columns:
<table>
<tr><td colspan=2>Real estate name
<tr><td>A table cell <td>Another table cell
</table>
You could use th instead of the first td, since it is kind of a header cell, but beware then that this makes its content bold and centered by default (you can override this is in CSS).
As per the “supposed to look like” link, it seems that you are supposed to put an img element only in the first cell of the second row, and the second cell there contains text and a ul element. And a little bit of CSS too. Note that for this output, you will need to align the second row vertically to the top (using the HTML valign attribute or the CSS vertical-align property).
correct code:
<table>
<tr>
<th>
<h3>TEST</h3>
</th>
<th rowspan="2">RowSpan2!</th>
</tr>
<tr>
<td>Something here !</td>
</tr>
<tr>
<td>Something Else !</td>
</tr>
</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