this is my fiddlejs: [https://jsfiddle.net/uj8gbeL1/]
Im trying to make fixed the first row of the table, but when i try to set the style postion:fixed, this row has a different width
How can i fix this issues without setting a "static" width to every th element?
You will solve this by using:
<tr class="globalTr" style="position:sticky;top:0;z-index:1">
Or better, put it in the css:
.globalTr:first-child {
position: sticky;
top: 0;
z-index: 1;
}
However, your code could be formatted a lot better.
Here is an example, please read the comments in the html:
div {
width: 100%;
height: 200px;
overflow: auto;
}
table {
font-family: sans-serif;
border-collapse: collapse;
}
thead {
position: sticky;
top: 0;
z-index: 1;
}
th, td {
border: 1px solid #369;
padding: 10px;
}
th {
background: #369;
color: white;
}
td {
background: aliceblue;
}
<div>
<table>
<thead>
<tr>
<th>Heading1</th> <!-- th is for headings -->
<th>Heading2</th>
</tr>
</thead>
<!-- use thead and tbody -->
<tbody>
<tr>
<td>Content</td> <!-- td is for cells -->
<td>Content</td>
</tr>
<tr>
<td>Content</td>
<td>Content</td>
</tr>
<tr>
<td>Content</td>
<td>Content</td>
</tr>
<tr>
<td>Content</td>
<td>Content</td>
</tr>
<tr>
<td>Content</td>
<td>Content</td>
</tr>
<tr>
<td>Content</td>
<td>Content</td>
</tr>
</tbody>
</table>
</div>
Use CSS position:sticky;top:0; instead of position:fixed;.
Related
All the tables in my app are designed to be the size of their content.
When there are multiple tables on a page, because they are a different width the lack of alignment looks bad.
I want to have the less wide table expand to be the width of the wider table. This is easy with a div containing both tables set to width: fit-content and the tables set to 100%. e.g.:
<div>
<table>standard table code here</table>
<table>standard table code here</table>
</div>
div {
width: fit-content;
}
table {
width: 100%;
}
The problem is that I want any excess free space on the narrower table to appear on the right, rather than being distributed among the whole table (as shown in this example).
What I would like to achieve looks something like this:
Using CSS grid this would be easy by using the fr unit to take up any available space (Codepen example here using CSS subgrid so does not work in Chrome yet). While I can achieve the layout I want I need to implement it with a HTML table to be semantically correct. Is this possible?
Perhaps relevant: sometimes the columns in the table will be text-align: right.
If you know that the text won't need to be split on multiple lines you can set the last column width to 100% and use white-space: nowrap as below
table {
border: solid 1px #EDEEEF;
border-collapse: seperate;
border-spacing: 0;
text-align: left;
border-radius: 3px;
width: 100%;
}
td,
th {
padding-left: 40px;
white-space:nowrap;
}
td:last-child {
width:100%;
}
td:first-child,
th:first-child {
padding-left: 16px;
}
td:last-child,
th:last-child {
padding-right: 16px;
}
thead th {
background-color: #F7F7F8;
color: #585858;
border-bottom: solid 1px #EDEEEF;
}
td {
color: #686868;
}
tr:not(:last-child) td {
border-bottom: solid 1px #F7F7F8;
}
td,
th {
padding-block: 8px;
}
.align-right {
text-align: right;
}
thead th:first-child {
border-top-left-radius: 2px;
/* needs to be 1px less than the border-radius of the table */
}
thead th:last-child {
border-top-right-radius: 2px;
}
tr:hover {
background-color: #F7F7F8;
}
div {
width: fit-content;
}
.mt-medium {
margin-top: 24px;
}
<div>
<table class="smaller-table">
<thead>
<tr>
<th>Name</th>
<th>Lorem ipsum</th>
<th class="align-right">Mean</th>
</tr>
</thead>
<tbody>
<tr>
<td>something</td>
<td>something else</td>
<td class="align-right">23</td>
</tr>
<tr>
<td>something</td>
<td>something else</td>
<td class="align-right">23</td>
</tr>
<tr>
<td>something</td>
<td>something else</td>
<td class="align-right">23</td>
</tr>
</tbody>
</table>
<table class="mt-medium">
<thead>
<tr>
<th>Name</th>
<th>Lorem ipsum</th>
<th>Lorem ipsum</th>
<th>Lorem ipsum</th>
<th class="align-right">Mean</th>
</tr>
</thead>
<tbody>
<tr>
<td>something</td>
<td>something else</td>
<td>lorem ipsum</td>
<td>lorem ipsum</td>
<td class="align-right">23</td>
</tr>
<tr>
<td>something</td>
<td>something else</td>
<td>lorem ipsum</td>
<td>lorem ipsum</td>
<td class="align-right">23</td>
</tr>
<tr>
<td>something</td>
<td>something else</td>
<td>lorem ipsum</td>
<td>lorem ipsum</td>
<td class="align-right">23</td>
</tr>
</tbody>
</table>
</div>
I solved this with empty table cells in an extra column on the right set to:
.spacer {
width: 100%;
}
This forces the text in all the other table cells to wrap, which you can change with:
th, td {
white-space: nowrap;
}
So I am trying to add an incrementing number to the first cell of a HTML table. Which I have done using examples found in this forum. What I want to do next is hide any row that only contains the number in the first cell. The only real option I have available is css but I am unsure if it is possible. The code I have so far is
table {
border-collapse: collapse;
counter-reset: rowNumber;
}
table tr:not(:first-child) {
counter-increment: rowNumber;
}
table td > *:empty {
display: none;
}
tr > td:empty {
background-color: yellow;
}
table tr td:first-child::before {
content: counter(rowNumber);
min-width: 1em;
margin-right: 0.5em;
}
<table border="1px" empty-cells:hide;>
<tr>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td>Test</td>
</tr>
<tr>
<td></td>
<td>Test</td>
</tr>
<tr>
<td></td>
<td>Test</td>
</tr>
</table>
please check below snippet meets your requirement.
http://bootsnipp.com/user/snippets/D2ZDA
Here I'm hiding all sibling TR elements if the first TR is empty.
Using CSS, you can not control parent as there are no parent selectors.
Here is the code -
table {
border-collapse: collapse;
}
table tr:not(:first-child) {
counter-increment: rowNumber;
}
tr > td:first-child:empty,
tr > td:first-child:empty ~ td {
display: none;
}
table tr td:first-child::before {
content: counter(rowNumber);
min-width: 1em;
margin-right: 0.5em;
}
<table border="1px" empty-cells:hide;>
<tr>
<td>Has Text</td>
<td>Test</td>
</tr>
<tr>
<td></td>
<td>Test</td>
</tr>
<tr>
<td>Has Text</td>
<td>Test</td>
</tr>
<tr>
<td></td>
<td>Test</td>
</tr>
</table>
Building on #CharanKumar answer, what you could do is remove the first column, and apply the numbering to the row with text. You could then add some padding and a border-right to simulate a separate cell.
It would look like below:
table {
border-collapse: collapse;
}
table tr:not(:first-child) {
counter-increment: rowNumber;
}
tr > td:first-child:empty,
tr > td:first-child:empty ~ td {
display: none;
}
table tr td:first-child::before {
content: counter(rowNumber);
min-width: 1em;
margin-right: 0.5em;
border-right: 1px solid black;
padding: 1px 5px 1px 1px;
}
<table border="1px" empty-cells:hide;>
<tr>
<td></td>
</tr>
<tr>
<td>Test</td>
</tr>
<tr>
<td>Test</td>
</tr>
<tr>
<td>Test</td>
</tr>
</table>
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I would like to create HTML table like this example.
How I can preserve the header gray and make the data to look like the same way?
Here is a working snippet.
border-spacing removes the spacing between cells
tr:first-of-type targets only the first row to apply background color
td:nth-child(odd) targets only the first column to make all fields bold
table{
border-spacing:0;
}
tr:first-of-type{
background:lightgray;
}
td:nth-child(odd){
font-weight:bold;
}
th,td{
padding:5px;
}
<table>
<tr>
<td>Plan / Feature</td>
<td>Standard</td>
</tr>
<tr>
<td>Plan Type</td>
<td>Annual</td>
</tr>
<tr>
<td>Email Support</td>
<td>Yes</td>
</tr>
</table>
Try this:
CSS:
table {
border-collapse: collapse;
}
table th, table thead tr {
background: #ccc;
font-weight: bold;
}
table tr td:first-child {
font-weight: bold;
}
table tr td {
background-color: transparent;
}
Example HTML:
<table>
<thead>
<tr>
<th>Header 1</th>
<th>Header 2</th>
</tr>
</thead>
<tbody>
<tr>
<td>Column 1</td>
<td>Column 2</td>
</tr>
<tr>
<td>Column 1</td>
<td>Column 2</td>
</tr>
</tbody>
</table>
JSFiddle
You can style the header of a table with css
<table>
<tr>
<th>header</th>
<th>header</th>
</tr>
<tr>
<td>content</td>
<td>content</td>
</tr>
</table>
th { background-color: #ff0000; }
Or see this fiddle: http://jsfiddle.net/h4817knp/6/
Edit: To avoid the gaps in the header add
table { border-collapse: collapse; }
to the css
http://jsfiddle.net/1yn99g13/1/
You just set the background colour on the elements you want it to appear on.
There's nothing complicated about this.
table, tbody, tr, th, td { background: transparent; }
thead { background: #aaa; }
You should, of course, use CSS:
You need to get rid of the default spacing in the table:
table {
border-collapse: collapse;
border-spacing: 0;
}
You need to set the background color of the table head element:
table thead {
background-color: lightgrey;
}
You need to define your cell sizes:
td {
width: 100px;
height: 25px;
}
Working Fiddle
table {
border-collapse: collapse;
border-spacing: 0;
}
td {
width: 100px;
height: 25px;
}
table thead {
background-color: lightgrey;
}
<table>
<thead>
<tr>
<td>HeaderA</td>
<td>HeaderB</td>
</tr>
</thead>
<tbody>
<tr>
<td>Item 1</td>
<td>Value</td>
</tr>
</tbody>
</table>
Is it possible to change apply css for the table cells under a table header that is selected? I don't care how th got selected I just want to use css only to apply something to those table cells where their table header is selected like italicized and underline.
<table>
<tr>
<th>col1</th>
<th class="selected">col2</th>
</tr>
<tr>
<td>cell1a</td>
<td>cell2b</td>
</tr>
<tr>
<td>cell1aa</td>
<td>cell2ba</td>
</tr>
</table>
css: (prototype...)
for the column position of the th row that is selected on this table
apply this css to the column position of all the td elements of this table
{
font-style:italic;
text-decoration: underline;
}
HERE is an article on how to color the whole row on mouse hover.
HERE is a post that gives an example how to style an element on click with css, by utilizing a checkbox
combining those two from above, i wrote you a simple example on how to achieve your goal: FIDDLE
basically you just put checkboxes in your th and use their checked state to color the entire column by inserting a huge styled background using ::after selector and hiding its overflow:
you can style the checkboxes as you see fit. put an image instead or make them disappear if you like.
HTML:
<table>
<tbody>
<tr>
<th></th>
<th><input type="checkbox">50kg</input></th>
<th><input type="checkbox">55kg</input></th>
<th><input type="checkbox">60kg</input></th>
<th><input type="checkbox">65kg</input></th>
<th><input type="checkbox">70kg</input></th>
</tr>
<tr>
<th>160cm</th>
<td>20</td>
<td>21</td>
<td>23</td>
<td>25</td>
<td>27</td>
</tr>
<tr>
<th>165cm</th>
<td>18</td>
<td>20</td>
<td>22</td>
<td>24</td>
<td>26</td>
</tr>
<tr>
<th>170cm</th>
<td>17</td>
<td>19</td>
<td>21</td>
<td>23</td>
<td>25</td>
</tr>
<tr>
<th>175cm</th>
<td>16</td>
<td>18</td>
<td>20</td>
<td>22</td>
<td>24</td>
</tr>
</tbody>
CSS:
input[type="checkbox"] {
margin: 0;
border: 0 none;
padding: 0;
}
table {
border-spacing: 0;
border-collapse: collapse;
overflow: hidden;
z-index: 1;
}
td, th {
cursor: pointer;
padding: 10px;
position: relative;
}
th input[type="checkbox"]:checked::after {
background-color: #ffa;
content: '\00a0';
height: 10000px;
left: 0;
position: absolute;
top: -5000px;
width: 100%;
z-index: -1;
}
I'm trying to create a table to display an individual's BMI.
As a part of this, I'd like, on :hover, for the <tr> and <col> (or <colgroup>) to be highlighted also, in order for the intersection to be more apparent.
As the table will feature both metric and imperial measurements, the :hover doesn't have to stop at the cell (from any direction) and would, in fact, be a bonus if it extended from one axis to the other. I'm also using the XHTML 1.1 Strict doctype, if this makes a difference?
So... an example (the real table's... larger), but this should be representative:
<script>
tr:hover {background-color: #ffa; }
colgroup:hover,
col:hover {background-color: #ffa; }
</script>
...
<table>
<col class="weight"></col><colgroup span="3"><col class="bmi"></col></colgroup>
<tr>
<th></th>
<th>50kg</th>
<th>55kg</th>
<th>60kg</th>
</tr>
<tr>
<td>160cm</td>
<td>20</td>
<td>21</td>
<td>23</td>
</tr>
<tr>
<td>165cm</td>
<td>18</td>
<td>20</td>
<td>22</td>
</tr>
<tr>
<td>170cm</td>
<td>17</td>
<td>19</td>
<td>21</td>
</tr>
</table>
Am I asking the impossible, do I need to go JQuery-wards?
Here's a pure CSS method using no JavaScript.
I used ::before and ::after pseudo-elements to do the row and column highlighting. z-index keeps the highlighting below the <td>s in case you need to handle click events. position: absolute allows them to leave the confines of the <td>. overflow: hidden on the <table> hides the highlight overflow.
It wasn't necessary, but I also made it select just the row or column when you're in the headers. The .row and .col classes take care of this. If you wish the simplify, you can remove them.
This works in all modern browsers (and degrades gracefully on older browsers by doing nothing).
Demo: http://jsfiddle.net/ThinkingStiff/rUhCa/
Output:
CSS:
table {
border-spacing: 0;
border-collapse: collapse;
overflow: hidden;
z-index: 1;
}
td, th, .row, .col {
cursor: pointer;
padding: 10px;
position: relative;
}
td:hover::before,
.row:hover::before {
background-color: #ffa;
content: '\00a0';
height: 100%;
left: -5000px;
position: absolute;
top: 0;
width: 10000px;
z-index: -1;
}
td:hover::after,
.col:hover::after {
background-color: #ffa;
content: '\00a0';
height: 10000px;
left: 0;
position: absolute;
top: -5000px;
width: 100%;
z-index: -1;
}
HTML:
<table>
<tr>
<th></th>
<th class="col">50kg</th>
<th class="col">55kg</th>
<th class="col">60kg</th>
<th class="col">65kg</th>
<th class="col">70kg</th>
</tr>
<tr>
<th class="row">160cm</th>
<td>20</td><td>21</td><td>23</td><td>25</td><td>27</td>
</tr>
<tr>
<th class="row">165cm</th>
<td>18</td><td>20</td><td>22</td><td>24</td><td>26</td>
</tr>
<tr>
<th class="row">170cm</th>
<td>17</td><td>19</td><td>21</td><td>23</td><td>25</td>
</tr>
<tr>
<th class="row">175cm</th>
<td>16</td><td>18</td><td>20</td><td>22</td><td>24</td>
</tr>
</table>
There is a very decent jQuery plugin I've come across located here which does a very good job of this kind of thing with loads of examples. Preferentially I'd use that.
AFAIK CSS Hovers on TR's aren't supported in IE anyway, so at best the TR part of that will only work in Firefox.
Never even seen a :hover work on a col/colgroup so not sure if that's possible...
Think you might be stuck with a Javascript implementation.
Theres an example here that works (rows & cols) in Firefox
but again its broken in IE... cols don't work.
Live answer (https://jsfiddle.net/craig1123/d7105gLf/)
There are already CSS and JQuery answers; however, I have written a simple pure javascript answer.
I first find all the col and td tags, get the column index of each cell by doing element.cellIndex, and then add a CSS class with a background on mouseenter and removing it on mouseleave.
HTML
<table id='table'>
<col />
<col />
<col />
<col />
<thead>
<tr>
<th>Name</th>
<th>Age</th>
<th>Birthdate</th>
<th>Preferred Hat Style</th>
</tr>
</thead>
<tbody>
<tr>
<td>Abraham Lincoln</td>
<td>204</td>
<td>February 12</td>
<td>Stovepipe</td>
</tr>
<tr>
<td>Winston Churchill</td>
<td>139</td>
<td>November 30</td>
<td>Homburg</td>
</tr>
<tr>
<td>Rob Glazebrook</td>
<td>32</td>
<td>August 6</td>
<td>Flat Cap</td>
</tr>
</tbody>
</table>
CSS
body {
font: 16px/1.5 Helvetica, Arial, sans-serif;
}
table {
width: 80%;
margin: 20px auto;
border-collapse: collapse;
}
table th {
text-align: left;
}
table tr, table col {
transition: all .3s;
}
table tbody tr:hover {
background-color: rgba(0, 140, 203, 0.2);
}
table col.hover {
background-color: rgba(0, 140, 203, 0.2);
}
tr, col {
transition: all .3s;
}
tbody tr:hover {
background-color: rgba(0,140,203,.2);
}
col.hover {
background-color: rgba(0,140,203,.2);
}
JS
const col = table.getElementsByTagName('col');
const td = document.getElementsByTagName('td');
const columnEnter = (i) => col[i].classList.add('hover');
const columnLeave = (i) => col[i].classList.remove('hover');
for (const cell of td) {
const index = cell.cellIndex;
cell.addEventListener('mouseenter', columnEnter.bind(this, index));
cell.addEventListener('mouseleave', columnLeave.bind(this, index));
}
Here is a fiddle
I came accross this neat way of doing it its from css-tricks.com I also prepared a fiddle whilst messing around with it nothing fancy but u can get the idea its with the same code provided by that css-trick page
//The Html
<table>
<colgroup></colgroup>
<colgroup></colgroup>
<colgroup></colgroup>
<colgroup></colgroup>
<colgroup></colgroup>
<thead>
<tr>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
//The Js
$(function(){
$("table").delegate('td','mouseover mouseleave', function(e) {
if (e.type == 'mouseover') {
$(this).parent().addClass("hover");
$("colgroup").eq($(this).index()).addClass("hover");
}
else {
$(this).parent().removeClass("hover");
$("colgroup").eq($(this).index()).removeClass("hover");
}
});
})
Check out the fiddle here