Change first column of table to a row header appearance using CSS - html

I'm kind of thinking this might not be possible using only CSS, but I just wanted to ask: Is it possible using only CSS to change the first <td> to appear as if it was a header for the entire column?
Sadly, I'm not able to easily change the html, and I can't easily run javascript to change the DOM, so I'm stuck with the following html structure:
<table>
<thead>
<tr>
<th>Hide this</th>
<th>text</th>
<th>value</th>
</tr>
</thead>
<tbody>
<tr>
<td>term a</td>
<td>Value of a</td>
<td>123</td>
</tr>
<tr>
<td>term b</td>
<td>Value of b</td>
<td>345</td>
</tr>
</tbody>
</table>
And I would love for it resemble a output like:
Some similar question, but which doesn't quite match my request:
HTML colspan in CSS
Change columnspan using CSS

If you are locked into creating a hacky solution, you can rewrite some css classes to use grid instead of using the table setup in the html.
Since html is just an data wrapper and css is the styling, you should theoretically solve most styling issues with css only.
This hacky soution overwrites all tr, td, and th elements to use grid instead.
we can restyle the tr width of the content to have 2 colums using
tr {
grid-template-columns: 1fr 1fr;
}
After that we can get the first child of an tr and style that to have full width of the container. in this example spanning from the first and the second element of the grid.
tbody tr td:first-child {
background: lightblue;
grid-column-start: 1;
grid-column-end: 3;
text-align: center;
}
This will give you an rendering looking like this, using only css to restyle the html.
tr,
td,
th {
display: grid;
}
table {
border: 1px solid gray;
}
td {
border: 1px solid gray;
}
tr {
grid-template-columns: 1fr 1fr;
}
thead tr th:first-child {
display: none;
}
tbody tr td:first-child {
background: lightblue;
grid-column-start: 1;
grid-column-end: 3;
text-align: center;
font-weight: bold;
}
<table>
<thead>
<tr>
<th>Hide this</th>
<th>text</th>
<th>value</th>
</tr>
</thead>
<tbody>
<tr>
<td>term a</td>
<td>Value of a</td>
<td>123</td>
</tr>
<tr>
<td>term b</td>
<td>Value of b</td>
<td>345</td>
</tr>
</tbody>
</table>
Again this should be a last effort since you will overwrite lots of basic styling, and force a more static rendering of the data.

Related

CSS Highlight Table Row But Not When Hovering First 3 Cells

I would like to highlight a row (change the background color) when i hover over any cell excluding the first 3 cells on the row (button cells). I also need to exclude the first row from the grid as that is the header row. (Images show desired behavior)
I have tried using many different :hover css selectors. But i cant seem to find the combination that allows me to highlight the row when hovering over any cell except the first 3.
table tr:hover td {
background-color: #e6e600;
}
<table>
<tr>
<th></th>
<th></th>
<th></th>
<th>Name</th>
<th>Age</th>
<th>Gender</th>
</tr>
<tr>
<td><button></button></td>
<td><button></button></td>
<td><button></button></td>
<th>Joe</th>
<th>37</th>
<th>Male</th>
</tr>
</table>
Thanks!!
The 4th, 5thth, and 6th
columns were all <th>, the cells that are in the <tbody> should be <td>, so that is corrected. Also, I added a <thead> to it as well and an extra <tr> to show that the highlight affects each <tr> separately.
In order to meet the following criteria:
no JavaScript
valid HTML and CSS only
the 4th, 5thth, and 6th <td> of any <tr> within the <tbody> should all be highlighted at once if any one of them is hovered over.
the 1st, 2nd, and 3rd <td> of any <tr> within the <tbody> should never trigger any effects when hovering over them.
A sub-table could be used to isolate the last 3 columns:
in the <tbody>, remove the last 2 <td> of each <tr>.
add colspan="3" to the last <td> of each <tr> within the <tbody>
add a <table> into each of those <td colspan="3">
add a <tr> into that <table>
add 3 <td> into that <tr>
Figure I - a sub-table
<td class='col' colspan='3'>
<table class='sub'>
<tr><td>Joe</td><td>37</td><td>Male</td></tr>
</table>
</td>
table {
table-layout: fixed;
border-collapse: collapse;
}
th {
width: 5%;
}
th:nth-of-type(4) {
width: 50%;
}
th:nth-of-type(5) {
width: 5%;
}
th:nth-of-type(6) {
width: 15%;
}
td {
border: 1px solid #000;
background: transparent;
text-align:center;
}
.col {
padding: 0;
border: 0;
outline: 1px solid #000;
outline-offset: 0;
}
.sub tr:hover td {
background: #fc0;
}
.sub {
table-layout: fixed;
border-collapse: collapse;
min-width: 100%;
padding: 0;
border: 0.5px solid #000;
}
.sub td {
padding: 5px;
border: 1px solid 0.5px;
text-align: left;
}
.sub td:first-of-type {
width: 70%;
border-left: 0;
}
.sub td:nth-of-type(2) {
width: 10%;
text-align: center;
}
.sub td:last-of-type {
width: 20%;
}
<table>
<thead>
<tr>
<th></th>
<th></th>
<th></th>
<th>Name</th>
<th>Age</th>
<th>Gender</th>
</tr>
</thead>
<tbody>
<tr>
<td><button>A</button></td>
<td><button>B</button></td>
<td><button>C</button></td>
<td class='col' colspan='3'>
<table class='sub'>
<tr><td>Joe</td><td>37</td><td>Male</td></tr>
</table>
</td>
</tr>
<tr>
<td><button>A</button></td>
<td><button>B</button></td>
<td><button>C</button></td>
<td class='col' colspan='3'>
<table class='sub'>
<tr><td>Jill</td><td>37</td><td>Female</td></tr>
</table>
</td>
</tr>
</tbody>
</table>
It is not fully possible without JS as CSS has no parent selector. A few browsers (Safari and Chrome Desktop) already included the :has()-selector but as said, it is not fully supported yet.
The closest thing you an do without scripting is to highlight all th in a row. That said, you can use the tr:hover selector to check for a hover on the entire row. This means the hover will also trigger if you hover the first 3 elements. The background-highlighting therefore will only be used on the th. To exclude the first row you can use the :not()-selector:
table tr:not(:nth-child(1)):hover th {
background-color: #e6e600;
}
<table>
<tr>
<th></th>
<th></th>
<th></th>
<th>Name</th>
<th>Age</th>
<th>Gender</th>
</tr>
<tr>
<td><button></button></td>
<td><button></button></td>
<td><button></button></td>
<th>Joe</th>
<th>37</th>
<th>Male</th>
</tr>
</table>

css: display column as row in mobile view

I want to display table column as row, when someone open page in mobile (less than 480px).
This is my table structure.
table, th, td {
border: 1px solid black;
}
table {
border-collapse: collapse;
}
#media(max-width: 480px) {
.main td {
display: table-row;
}
}
<p>
In desktop View
</p>
<table class="main">
<tr>
<td>R1 Col 1</td>
<td>R1 Col 2</td>
</tr>
<tr>
<td>R2 Col 1</td>
<td>R2 Col 2</td>
</tr>
<tr>
<td>R3 Col 1</td>
<td>R3 Col 2</td>
</tr>
</table>
I tried to do using css like.
#media(max-width: 480px) {
.main td {
display: table-row;
}
}
But it is not working. In Mobile view I want output like this, Second column should display below first column.
Note: I can't change table to div.
This is my expected output:
You will need to break the table-layout via resets on display.
grid or flex can then allow you to reorder your elements
example
table,
th,
td {
border: 1px solid black;
}
table {
border-collapse: collapse;
}
#media(max-width: 480px) {
.main tbody {
display: grid;
}
.main tr {
display: contents;
border:solid red
}
.main td {
display: block;
}
.main tr td + td {
order: 1;
}
}
<p>
In desktop View
</p>
<table class="main">
<tr>
<td>R1 Col 1</td>
<td>R1 Col 2</td>
</tr>
<tr>
<td>R2 Col 1</td>
<td>R2 Col 2</td>
</tr>
<tr>
<td>R3 Col 1</td>
<td>R3 Col 2</td>
</tr>
</table>
explanation :
the browser will generate a tbody wrapper, you can reset display from than one and keep the table display behavior on the <table>element so it keeps shrinking. Let's make that tbody a grid (defaut of display:grid is to draw a single column).
tr are in the way, display:contents will remove them virtually, so the cells (td) can be (virtually) direct child of tbody and be reorder via .. order. You can give here via tr >:nth-child(x){order:X;} an order to each cells.
ressource:
https://css-tricks.com/snippets/css/complete-guide-grid/
https://developer.mozilla.org/en-US/docs/Web/CSS/display
display contents
These elements don't produce a specific box by themselves. They are replaced by their pseudo-box and their child boxes. Please note that the CSS Display Level 3 spec defines how the contents value should affect "unusual elements" — elements that aren’t rendered purely by CSS box concepts such as replaced elements.
If you can't change the table structure then it is very difficult achieve the desired result. But if it is fixed row and column then you can use some CSS trick to bring the result.
You can reduce the browser width and see the below snippet.
#media(max-width: 480px) {
.main td{
margin-top:63px
}
.main td:last-child {
position:absolute;
left:8px;
}
}
table, th, td {
border: 1px solid black;
}
table {
border-collapse: collapse;
}
#media(max-width: 480px) {
.main td{
margin-top:63px
}
.main td:last-child {
position:absolute;
left:8px;
}
}
<p>
In desktop View
</p>
<table class="main">
<tr>
<td>R1 Col 1</td>
<td>R1 Col 2</td>
</tr>
<tr>
<td>R2 Col 1</td>
<td>R2 Col 2</td>
</tr>
<tr>
<td>R3 Col 1</td>
<td>R3 Col 2</td>
</tr>
</table>
JS FIDDLE DEMO
adding display block to td and tr will force them to behave like block level element, try if it works for you
table, th, td {
border: 1px solid black;
}
table {
border-collapse: collapse;
}
#media(max-width: 480px) {
.main tr, .main td {
display: block;
}
}
<table class="main">
<tr>
<td>R1 Col 1</td>
<td>R1 Col 2</td>
</tr>
<tr>
<td>R2 Col 1</td>
<td>R2 Col 2</td>
</tr>
<tr>
<td>R3 Col 1</td>
<td>R3 Col 2</td>
</tr>
</table>

What is the best way to style a vertical table with split background

How can I organize and style this data on a split background using css and html?
that layout of yours (if that's what you want right?), you need to collapse your table border for that, to avoid white gaps. add a special class for tr that represents the thead and style it accordingly. follow the pattern with <tr><th></th><td></td></tr>. use text-align to center them with right to th and left to td.
td, th {
padding: 8px;
font-size: 12px;
width: 250px;
}
th { background: #E9EADA; text-align: right; }
td { background: #FCFCFC; text-align: left; }
.table-header > * {
font-size: 16px;
color: #238E98;
}
table { border-collapse: collapse; }
<table>
<tr>
<th>First name</th>
<td>John</td>
</tr>
<tr>
<th>Last Name</th>
<td>Doe</td>
</tr>
<tr class="table-header">
<th>Details</th>
<td>---</td>
</tr>
<tr>
<th>Age</th>
<td>33</td>
</tr>
</table>

Remove Excess space between th and td Elements

I am using a table to display data .I am trying to remove space from the left and right of th and td element.
I have tried checking on stack overflow and other places but they all remove vertical spaces between cells. What i want to remove is remove space from left and right.
#contact_search{
border-collapse: collapse;
}
#contact_search tr td, #contact_search tr th{
/* text-align: center; */
border: 1px solid #006;
line-height: 1;
}
<table id="contact_search" >
<thead>
<tr>
<th>Nametest</th>
<th>Country</th>
<th>City</th>
<th>Category</th>
<th>Work</th>
<th>Mobile</th>
<th>Email</th>
<th>Trades</th>
</tr>
</thead>
<tbody>
<td>John Doe</td>
<td>Australia</td>
<td>Auckland</td>
<td>Corporate Client</td>
<td>3275020</td>
<td>9926104</td>
<td>johndoe#example.com</td>
<td>None</td>
</tbody>
</table>
This is what i get
table
The red circle is what i want to remove.
The CSS causing the padding is not included in your example. Run this snippet and look at the output. Other CSS you are importing is causing the table width.
In Chrome, right click on one of the table cells and go inspect. Look at the styles in the devtools to see where it is coming from.
#contact_search{
border-collapse: collapse;
}
#contact_search tr td, #contact_search tr th{
/* text-align: center; */
border: 1px solid #006;
line-height: 1;
}
<table id="contact_search" >
<thead>
<tr>
<th>Nametest</th>
<th>Country</th>
<th>City</th>
<th>Category</th>
<th>Work</th>
<th>Mobile</th>
<th>Email</th>
<th>Trades</th>
</tr>
</thead>
<tbody>
<td>John Doe</td>
<td>Australia</td>
<td>Auckland</td>
<td>Corporate Client</td>
<td>3275020</td>
<td>9926104</td>
<td>johndoe#example.com</td>
<td>None</td>
</tbody>
</table>
If you use Firefox, use the Inspector. This way you can see which css attribute influences the table elements. For other browsers there should be similar possibilities.
See e.g. for Chrome, Edge
Sorry about the problem you are experiencing but I cant see it from my end. I wrote a new html file and copied your contents without any edits into it like you can see below but the issue was not detected. You too can try out and see for yourself.
#contact_search{
border-collapse: collapse;
}
#contact_search tr td, #contact_search tr th{
/* text-align: center; */
border: 1px solid #006;
line-height: 1;
}
<table id="contact_search" >
<thead>
<tr>
<th>Nametest</th>
<th>Country</th>
<th>City</th>
<th>Category</th>
<th>Work</th>
<th>Mobile</th>
<th>Email</th>
<th>Trades</th>
</tr>
</thead>
<tbody>
<td>John Doe</td>
<td>Australia</td>
<td>Auckland</td>
<td>Corporate Client</td>
<td>3275020</td>
<td>9926104</td>
<td>johndoe#example.com</td>
<td>None</td>
</tbody>
</table>
Possible reasons include:
browser issue (try to use a different browser, clear history on your browser)
you never saved your edits
your css has table attribute already added to it at the top making browser inherit them hence ignoring those for #contact_search
You could try out this for yourself in your css by the way
#contact_search{
border-collapse: collapse!important;
}
#contact_search tr td, #contact_search tr th{
/* text-align: center; */
border: 1px solid #006!important;
line-height: 1!important;
}
please note the keyword !important for css for overriding attributes.

Why are table borders not collapsing when caption is positioned?

In this fiddle http://jsfiddle.net/jnddfyeq/ I have two tables with border-collapse: collapse. In the first one everything works as expected. In the second one I position the caption with position: absolute and now the borders between the thead and tbody do not collapse.
This happens in Firefox 38 and IE8 (not in a fiddle.) I have not tested other browsers. Is this behavior standard? If so why?
UPDATE: Same thing happens in Safari.
It's not really that the borders don't collapse. It seems that what's happening is that even if the caption is displayed out of the table, there is still an invisible cell being added to the table.
The specification mention that this can happen, it's not exactly clear what should happen in this case, but it's clear that a table follows a pretty strict layout structure and that it will compensate in the background when messing with that layout. See:
Note. Positioning and floating of table cells can cause them not to be
table cells anymore, according to the rules in section 9.7. When
floating is used, the rules on anonymous table objects may cause an
anonymous cell object to be created as well.
Here: http://www.w3.org/TR/CSS2/tables.html#table-layout
If you look at the computed style of your absolute caption you'll see it's not a cell anymore, so it's probably replaced by an anonymous cell. And I guess that since table head are always at the top by definition, this anonymous cell is placed automatically below it, in the table body group. If you set coordinates to 0, you'll see exactly where it ends up. And if you play with borders, you'll see also what happens.
See snippet:
console.log('first caption:', window.getComputedStyle(document.getElementsByTagName('caption')[0]).display, '\nabsolute caption:',
window.getComputedStyle(document.getElementsByTagName('caption')[1]).display)
body
{
margin: 0;
}
table {
border-collapse: collapse;
margin-bottom: 1em;
border-spacing: 12px;
background-color: yellow;
margin-left: 0px;
}
th {
padding: 0.5em;
border: 10px dotted green;
background: #8cf;
}
td {
padding: 0.5em;
border: 15px dotted red;
background: #8cf;
}
caption.abs {
position: absolute;
left: 0;
}
tr
{
background-color: pink;
}
table.realnoncollapse {
border-collapse: separate;
margin-bottom: 1em;
border-spacing: 12px;
background-color: yellow;
}
<table>
<caption>Chill Table</caption>
<thead>
<tr id="tr1">
<th>Chiller</th>
<th>Chillness</th>
</tr>
</thead>
<tbody>
<tr>
<td>The Dude</td>
<td>Way chill</td>
</tr>
<tr>
<td>This Guy</td>
<td>Pretty chill</td>
</tr>
</tbody>
</table>
<table>
<caption class="abs">No chill</caption>
<thead>
<tr >
<th>Chiller</th>
<th>Chillness</th>
</tr>
</thead>
<tbody>
<tr>
<td>The Dude</td>
<td>Way chill</td>
</tr>
<tr>
<td>This Guy</td>
<td>Pretty chill</td>
</tr>
</tbody>
</table>
<table class="realnoncollapse">
<caption class="abs">No chill</caption>
<thead>
<tr >
<th>Chiller</th>
<th>Chillness</th>
</tr>
</thead>
<tbody>
<tr>
<td>The Dude</td>
<td>Way chill</td>
</tr>
<tr>
<td>This Guy</td>
<td>Pretty chill</td>
</tr>
</tbody>
</table>