HTML table caption as part of header row - html

I would like to create a table header row that includes a title on the left as well as "Sample header" on the right. For accessibility and to be semantically correct, the title should probably be in a <caption> tag, but "Sample header" isn't part of the title so it probably shouldn't be inside of <caption>. The caption can't be inside the row since it has to be the first element after <table>.
Here is the HTML structure:
<table>
<caption>Caption</caption>
<thead>
<tr class="sample">
<th colspan="2">Sample header</th>
</tr>
<tr>
<th>Column1</th>
<th>Column2</th>
</tr>
</thead>
<tbody>
<tr>
<td>Data1</td>
<td>Data2</td>
</tr>
</tbody>
</table>
The caption ends up as a separate line above the table, while I would like it to be on the same line as "Sample header".
Here is a sample of what I'm trying to achieve: http://jsfiddle.net/vueLL5ce/5/. It sets 'caption`'s position to relative and manually moves it where I want. The two main problems with this approach is that repositioning the caption still leaves its original space above the table and I'm working with pixels which vary between browsers so it won't necessarily line up correctly.
Is there a good way of achieving this? Am I stuck with including the header info inside of <caption> (and styling to look like a table row) or creating a regular table row and not using <caption>?

Move background color from div to table and it should remove the color from the top for you. see attached fiddle here
table {
border: solid 1px Black;
width: 100%;
background-color: #FFFFDD;
}
I would remove the caption, use the column head and separate the two items with there own class then align them in your css. Updated the example here This way you don't have the spacing issue at all.

I think I found a cross-browser solution. The key is to set line-height: 0 (plain 0 doesn't work in IE6, but I don't need to support it). Firefox also wouldn't let me reposition the caption directly, so I had to add another span. I still don't like dealing with pixels directly, so any suggestions on that end would be great.
Fiddle: http://jsfiddle.net/vueLL5ce/8/
HTML:
<div>
<table>
<caption><span>Caption</span></caption>
<thead>
<tr class="captionRow">
<th colspan="2">Sample header</th>
</tr>
<tr>
<th>Column1</th>
<th>Column2</th>
</tr>
</thead>
<tbody>
<tr>
<td>Data1</td>
<td>Data2</td>
</tr>
</tbody>
</table>
</div>
CSS:
div {
background-color: #FFFFDD;
}
table {
border: solid 1px Black;
width: 100%;
}
table caption {
line-height: 0;
text-align: left;
}
table caption span {
position: relative;
left: 4px;
top: 14px;
}
table th {
background-color: #CCC;
}
.captionRow th {
text-align: right;
}

Related

How to force table header (and its column) to be smaller than its limit with CSS?

I made a table and with 6 columns the first of which I have given "id = 'Day'" in the style sheet I made the width of it 50px but this is taking up too much space on the screen. When I try to change it to something smaller it will not get smaller than 50px. Is there a way to force it to be smaller than 50px? Code bellow.
th#Day {
width: 20px;
}
table {
width: 200px;
}
<table>
<tr>
<th id="Day">Day</th>
<th>Event</th>
<th>Time</th>
<th>Location</th>
<th>Phone Number</th>
<th>URL</th>
</tr>
</table>
The width of the table does not effect the width of the Day column but I am not able to make the Day column smaller than 50 px as mentioned above.
I have tried setting the min-width to be smaller but that does not change it and have not found any solutions on popular sites.
From the tests I have done, it seems that the problem is in the table's size. By commenting it is possible to modify the width of the columns (which cannot be less than its content, from what I am noticing, it's a new thing for me too) but otherwise, as you can see, it works
https://codepen.io/loremaru/pen/vYawPpq
#Day {
width: 30px;
border: 1px solid red;
}
#Event{
width: 50px;
border: 1px solid blue;
}
table {
/* width: 200px; */
}
<table>
<tr>
<th id="Day">Day</th>
<th id="Event">Event</th>
<th>Time</th>
<th>Location</th>
<th>Phone Number</th>
<th>URL</th>
</tr>
</table>

Unicode symbol in table cell fails vertical-align of CSS?

Every time I have a unicode symbol in one table cell,
vertical-align: middle;
in my CSS stops working. As a result, the text "floats higher" than middle.
Notice how text in the upper row is vertically aligned in the middle, whereas Sun Jun 4 23:52:31 2017 in the lower row floats higher than middle because of the folder unicode symbol.
Relevant part of CSS
table, td, th {
border: 2px solid #D0D0D0;
}
table {
border-collapse: collapse;
}
td {
vertical-align: bottom;
}
Relevant part of HTML
<td>📂 viz_coreOpt_3D<span style="float:right;">  Sun Jun 4 23:52:31 2017</span></td>
The folder icon is the reason that one line in height exceeds the other. I suggest to set the line height not less than the height of the icon.
table, td, th {
border: 2px solid #D0D0D0;
}
table {
border-collapse: collapse;
}
td {
line-height: 1.5em;
vertical-align: bottom;
}
<table>
<tr>
<td>
📂 viz_coreOpt_3D
<span style="float:right;">  Sun Jun 4 23:52:31 2017</span>
</td>
</tr>
</table>
Are you using the tag? You should be as you need to let the table know how to separate your rows.
your table setup in html should look something like this:
<table>
<thead> <!-- this is optional -->
<tr>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody> <!-- once again this is optional -->
<tr>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
this will give you a table with two rows. One a header row and one a normal row. if you want them to be aligned within the boxes you can center the text with text-align: center; to the middle of the cell width wise and then use vertical-align: middle; to make it align vertically within the cell of the table.
what is causing the problem with your initial solution is the use of float. This will move it to the right and the top of the element because float

html number of columns in table

I am trying to create the following html table:
I can't work out why my current implementation is not yielding my desired result. As you can see in the snippet, the last <td> in the second <tr> spans 2 cols, and not the middle <td>.
table{
width: 100%;
}
table tr td {
background-color: #ddd;
}
table tr td[colspan="2"]{
background-color: #0a0;
}
table tr td[colspan="4"]{
font-size: 16px;
text-align:center;
background-color: #8C0000;
color: #fff;
}
<table>
<tbody>
<tr>
<td colspan="4"><b>Full width column</b></td>
</tr>
<tr>
<td>Column 1</td>
<td colspan="2">Column 2</td>
<td>Column 3</td>
</tr>
</tbody>
</table>
In researching I found the following from: https://www.w3.org/TR/WD-html40-970917/struct/tables.html
There are several ways to determine the number of columns:
Count the number of columns as specified by COL and COLGROUP elements which can only occur at the start of the table (after the
optional CAPTION).
Scan each row in turn to compute the number of columns needed for each row, taking into account cells that span multiple rows and/or
columns. Set the number of columns for the table to be the maximum
number of columns from each row. For any row that has less than this
number of columns, the end of that row should be padded with empty
cells. The "end" of a row depends on the directionality of the table.
[deprecated] Use the cols attribute on the TABLE element. This is the weakest method since it doesn't provide any additional information about
column widths. This may not matter, however, if the author uses style
sheets to specify widths.
So what have I misunderstood about this functionality?
Please also note, that I am aware that I can use css to specifically set the widths of the <td>'s I want to know why my current implementation is not working.
In fact the second td does span two columns, but the width of columns in a simple HTML table depends on the contents of the table cells. If you add the following style attributes containing widths to the tds, their widths are distributed as desired (i.e. 25/50/25%):
(Note: You could/should also apply CSS classes to those tds and create external CSS rules for those classes)
table{
width: 100%;
}
table tr td[colspan="4"]{
font-size: 16px;
text-align:center;
background-color: #008CD1;
color: #fff;
}
<table>
<tbody>
<tr>
<td colspan="4"><b>Nonverbal skills</b></td>
</tr>
<tr>
<td style="width: 25%; background-color: #888;">energised</td>
<td colspan="2" style="width: 50%; background-color: green;">Gestures</td>
<td style="width: 25%; background-color: #888;">Under energised</td>
</tr>
</tbody>
</table>
table.table td:nth-child(1) {text-align: center; font-weight: bold; width: 70px;}

Freeze the top row for an html table only (Fixed Table Header Scrolling)

I want to make an html table with the top row frozen (so when you scroll down vertically you can always see it).
Is there a clever way to make this happen without javascript?
Note that I do NOT need the left column frozen.
I know this has several answers, but none of these really helped me. I found this article which explains why my sticky wasn't operating as expected.
Basically, you cannot use position: sticky; on <thead> or <tr> elements. However, they can be used on <th>.
The minimum code I needed to make it work is as follows:
table {
text-align: left;
position: relative;
}
th {
background: white;
position: sticky;
top: 0;
}
With the table set to relative the <th> can be set to sticky, with the top at 0
NOTE: It's necessary to wrap the table with a div with max-height:
<div id="managerTable" >
...
</div>
where:
#managerTable {
max-height: 500px;
overflow: auto;
}
This is called Fixed Header Scrolling. There are a number of documented approaches:
http://www.imaputz.com/cssStuff/bigFourVersion.html
You won't effectively pull this off without JavaScript ... especially if you want cross browser support.
There are a number of gotchyas with any approach you take, especially concerning cross browser/version support.
Edit:
Even if it's not the header you want to fix, but the first row of data, the concept is still the same. I wasn't 100% which you were referring to.
Additional thought
I was tasked by my company to research a solution for this that could function in IE7+, Firefox, and Chrome.
After many moons of searching, trying, and frustration it really boiled down to a fundamental problem. For the most part, in order to gain the fixed header, you need to implement fixed height/width columns because most solutions involve using two separate tables, one for the header which will float and stay in place over the second table that contains the data.
//float this one right over second table
<table>
<tr>
<th>Header 1</th>
<th>Header 2</th>
</tr>
</table>
<table>
//Data
</table>
An alternative approach some try is utilize the tbody and thead tags but that is flawed too because IE will not allow you put a scrollbar on the tbody which means you can't limit its height (so stupid IMO).
<table>
<thead style="do some stuff to fix its position">
<tr>
<th>Header 1</th>
<th>Header 2</th>
</tr>
</thead>
<tbody style="No scrolling allowed here!">
Data here
</tbody>
</table>
This approach has many issues such as ensures EXACT pixel widths because tables are so cute in that different browsers will allocate pixels differently based on calculations and you simply CANNOT (AFAIK) guarantee that the distribution will be perfect in all cases. It becomes glaringly obvious if you have borders within your table.
I took a different approach and said screw tables since you can't make this guarantee. I used divs to mimic tables. This also has issues of positioning the rows and columns (mainly because floating has issues, using in-line block won't work for IE7, so it really left me with using absolute positioning to put them in their proper places).
There is someone out there that made the Slick Grid which has a very similar approach to mine and you can use and a good (albeit complex) example for achieving this.
https://github.com/6pac/SlickGrid/wiki
According to Pure CSS Scrollable Table with Fixed Header , I wrote a DEMO to easily fix the header by setting overflow:auto to the tbody.
table thead tr{
display:block;
}
table th,table td{
width:100px;//fixed width
}
table tbody{
display:block;
height:200px;
overflow:auto;//set tbody to auto
}
My concern was not to have the cells with fixed width. Which seemed to be not working in any case.
I found this solution which seems to be what I need. I am posting it here for others who are searching of a way. Check out this fiddle
Working Snippet:
html, body{
margin:0;
padding:0;
height:100%;
}
section {
position: relative;
border: 1px solid #000;
padding-top: 37px;
background: #500;
}
section.positioned {
position: absolute;
top:100px;
left:100px;
width:800px;
box-shadow: 0 0 15px #333;
}
.container {
overflow-y: auto;
height: 160px;
}
table {
border-spacing: 0;
width:100%;
}
td + td {
border-left:1px solid #eee;
}
td, th {
border-bottom:1px solid #eee;
background: #ddd;
color: #000;
padding: 10px 25px;
}
th {
height: 0;
line-height: 0;
padding-top: 0;
padding-bottom: 0;
color: transparent;
border: none;
white-space: nowrap;
}
th div{
position: absolute;
background: transparent;
color: #fff;
padding: 9px 25px;
top: 0;
margin-left: -25px;
line-height: normal;
border-left: 1px solid #800;
}
th:first-child div{
border: none;
}
<section class="">
<div class="container">
<table>
<thead>
<tr class="header">
<th>
Table attribute name
<div>Table attribute name</div>
</th>
<th>
Value
<div>Value</div>
</th>
<th>
Description
<div>Description</div>
</th>
</tr>
</thead>
<tbody>
<tr>
<td>align</td>
<td>left, center, right</td>
<td>Not supported in HTML5. Deprecated in HTML 4.01. Specifies the alignment of a table according to surrounding text</td>
</tr>
<tr>
<td>bgcolor</td>
<td>rgb(x,x,x), #xxxxxx, colorname</td>
<td>Not supported in HTML5. Deprecated in HTML 4.01. Specifies the background color for a table</td>
</tr>
<tr>
<td>border</td>
<td>1,""</td>
<td>Specifies whether the table cells should have borders or not</td>
</tr>
<tr>
<td>cellpadding</td>
<td>pixels</td>
<td>Not supported in HTML5. Specifies the space between the cell wall and the cell content</td>
</tr>
<tr>
<td>cellspacing</td>
<td>pixels</td>
<td>Not supported in HTML5. Specifies the space between cells</td>
</tr>
<tr>
<td>frame</td>
<td>void, above, below, hsides, lhs, rhs, vsides, box, border</td>
<td>Not supported in HTML5. Specifies which parts of the outside borders that should be visible</td>
</tr>
<tr>
<td>rules</td>
<td>none, groups, rows, cols, all</td>
<td>Not supported in HTML5. Specifies which parts of the inside borders that should be visible</td>
</tr>
<tr>
<td>summary</td>
<td>text</td>
<td>Not supported in HTML5. Specifies a summary of the content of a table</td>
</tr>
<tr>
<td>width</td>
<td>pixels, %</td>
<td>Not supported in HTML5. Specifies the width of a table</td>
</tr>
</tbody>
</table>
</div>
</section>
You can use CSS position: sticky; for the first row of the table
MDN ref:
.table-class tr:first-child>td{
position: sticky;
top: 0;
}
you can use two divs one for the headings and the other for the table. then use
#headings {
position: fixed;
top: 0px;
width: 960px;
}
as #ptriek said this will only work for fixed width columns.
It is possible using position:fixed on <th> (<th> being the top row).
Here's an example
The Chromatable jquery plugin allows a fixed header (or top row) with widths that allow percentages--granted, only a percentage of 100%.
http://www.chromaloop.com/posts/chromatable-jquery-plugin
I can't think of how you could do this without javascript.
update: new link -> http://www.jquery-plugins.info/chromatable-00012248.htm
I use this:
tbody{
overflow-y: auto;
height: 350px;
width: 102%;
}
thead,tbody{
display: block;
}
I define the columns width with bootstrap css col-md-xx. Without defining the columns width the auto-width of the doesn't match the . The 102% percent is because you lose some sapce with the overflow
Using css zebra styling
Copy paste this example and see the header fixed.
<style>
.zebra tr:nth-child(odd){
background:white;
color:black;
}
.zebra tr:nth-child(even){
background: grey;
color:black;
}
.zebra tr:nth-child(1) {
background:black;
color:yellow;
position: fixed;
margin:-30px 0px 0px 0px;
}
</style>
<DIV id= "stripped_div"
class= "zebra"
style = "
border:solid 1px red;
height:15px;
width:200px;
overflow-x:none;
overflow-y:scroll;
padding:30px 0px 0px 0px;"
>
<table>
<tr >
<td>Name:</td>
<td>Age:</td>
</tr>
<tr >
<td>Peter</td>
<td>10</td>
</tr>
</table>
</DIV>
Notice the top padding of of 30px in the div leaves
space that is utilized by the 1st row of stripped data
ie tr:nth-child(1) that is "fixed position"
and formatted to a margin of -30px

Styling specific columns and rows

I'm trying to style some specific parts of a 5x4 table that I create. It should be like this:
Every even numbered row and every odd numbered row should get a different color.
Text in the second, third, and fourth columns should be centered.
I have this table:
<table>
<caption>Some caption</caption>
<colgroup>
<col>
<col class="value">
<col class="value">
<col class="value">
</colgroup>
<thead>
<tr>
<th id="year">Year</th>
<th>1999</th>
<th>2000</th>
<th>2001</th>
</tr>
</thead>
<tbody>
<tr class="oddLine">
<td>Berlin</td>
<td>3,3</td>
<td>1,9</td>
<td>2,3</td>
</tr>
<tr class="evenLine">
<td>Hamburg</td>
<td>1,5</td>
<td>1,3</td>
<td>2,0</td>
</tr>
<tr class="oddLine">
<td>München</td>
<td>0,6</td>
<td>1,1</td>
<td>1,0</td>
</tr>
<tr class="evenLine">
<td>Frankfurt</td>
<td>1,3</td>
<td>1,6</td>
<td>1,9</td>
</tr>
</tbody>
<tfoot>
<tr class="oddLine">
<td>Total</td>
<td>6,7</td>
<td>5,9</td>
<td>7,2</td>
</tr>
</tfoot>
</table>
And I have this CSS file:
table, th, td {
border: 1px solid black;
border-collapse: collapse;
padding: 0px 5px;
}
#year {
text-align: left;
}
.oddLine {
background-color: #DDDDDD;
}
.evenLine {
background-color: #BBBBBB;
}
.value {
text-align: center;
}
And this doesn't work. The text in the columns are not centered. What is the problem here? And is there a way to solve it (other than changing the class of all the cells that I want centered)?
P.S.: I think there's some interference with .evenLine and .oddLine classes. Because when I put "background: black" in the class "value", it changes the background color of the columns in the first row. The thing is, if I delete those two classes, text-align still doesn't work, but background attribute works perfectly. Argh...
Use CSS pseudo classes.
tr:nth-child(even){
background: #EEEEEE;
}
tr:nth-child(odd) {
background: #FFFFFF;
}
td:nth-child(2), td:nth-child(3), td:nth-child(4) {
text-align: center;
}
I actually found out about the even and odd options for this like a couple hours ago. Hope you'll be as happy to use them as I was :D
Edit: Fixed the last line from tr to td and here's a fiddle
To answer why your code isn't working, W3schools has the answer.
"Note: Firefox, Chrome, and Safari only support the span and width attributes of the colgroup element.
Add the style attribute to the tag, and let CSS take care of backgrounds, width and borders. These are the ONLY CSS properties that work with the tag."
So text-align has no effect. Colgroup is just too old. You gotta get with the times man :P