Equal width and intrinsic width tables - css

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;
}

Related

Firefox doesn't style :empty elements

Here is a snippet with a sample code:
table {
border-collapse: collapse;
}
th, td {
border: 1px solid gray;
padding: 3px 6px;
}
[contenteditable]:empty:not(:focus)::before {
content: attr(data-placeholder);
color: gray;
font-size: .9rem;
}
<table>
<thead>
<tr>
<th>Firstname</th>
<th>Lastname</th>
</tr>
</thead>
<tbody>
<tr>
<td contenteditable="true" data-placeholder="Firstname"></td>
<td contenteditable="true" data-placeholder="Lastname"></td>
</tr>
<tr>
<td>John</td>
<td>Doe</td>
</tr>
</tbody>
</table>
In Chrome and Safari, it works pretty much as expected:
For some reason, in Firefox, the contenteditable tds don't get the placeholder:
How can I fix this issue?
EDIT: It seems this is issue is more related to :empty than [contenteditable] as this code kinda works:
[contenteditable]:not(:focus)::before {
content: attr(data-placeholder);
color: gray;
font-size: .9rem;
}
But then the placeholder is always shown, hence not being an actual "placeholder" anymore.
Firefox has incompatibility with td:empty not because there is an issue with the css engine but because the way Firefox handles contenteditable is by adding a br tag into the region.
An alternate way to do this would be to change the html to use inputs that you disable when content is present.
table {
border-collapse: collapse;
}
th,
td {
border: 1px solid gray;
padding: 0;
}
table input {
border: none;
}
[placeholder] {
color: gray;
font-size: .9rem;
}
<table>
<thead>
<tr>
<th>Forename</th>
<th>Surname</th>
</tr>
</thead>
<tbody>
<tr>
<td><input placeholder="Forename"></td>
<td><input placeholder="Surname"></td>
</tr>
<tr>
<td><input placeholder="Forename" value="John" disabled></td>
<td><input placeholder="Forename" value="Doe" disabled></td>
</tr>
</tbody>
</table>
As #DreamTeK mentioned, Firefox seems to add a <br> in empty contenteditable elements.
His answer, using input instead of contenteditable is valid.
In case you have no choice but to use contenteditable, here is a fix in JS to remove this unwanted br:
// VanillaJS
document.addEventListener("DOMContentLoaded", () => {
document.querySelectorAll('[contenteditable]').forEach((elt) => {
if (elt.children.length === 1 && elt.firstChild.tagName === "BR") {
elt.firstChild.remove();
}
})
});
// jQuery
/*
$(document).ready(() => {
$('[contenteditable]').each((_, elt) => {
if ($(elt).children().length === 1 && $(elt).has('br')) {
$(elt).html('');
}
});
});
*/
table {
border-collapse: collapse;
}
th, td {
border: 1px solid gray;
padding: 3px 6px;
}
[contenteditable]:empty:not(:focus)::before {
content: attr(data-placeholder);
color: gray;
font-size: .9rem;
}
<table>
<thead>
<tr>
<th>Firstname</th>
<th>Lastname</th>
</tr>
</thead>
<tbody>
<tr>
<td contenteditable="true" data-placeholder="Firstname"></td>
<td contenteditable="true" data-placeholder="Lastname"></td>
</tr>
<tr>
<td>John</td>
<td>Doe</td>
</tr>
</tbody>
</table>

Set the first tr to fixed without losing the width

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;.

HTML Hide Table rows

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>

Create transparent HTML table [closed]

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>

Drawing box shadow around table thead

As you can see in this fiddle, http://jsfiddle.net/S8Bne/64/, I am trying to draw a box shadow around the table (just the outside out it). The approach that I've taken is to create a div with slightly larger height than the thead area and give it a box shadow. However, I can't quite get it positioned properly. How can I do so?
Any solutions are welcome.
This is happening because your thead is not inside the div.
I added some height to the div to show...
Problem: http://jsfiddle.net/jasongennaro/S8Bne/54/
Add this
-webkit-box-shadow:#8A0000 2px 2px 10px;
box-shadow:#8A0000 2px 2px 10px;
to
.geniusPicks table tr#picksHeading th
And it works.
Working Example: http://jsfiddle.net/jasongennaro/S8Bne/55/
So no need for the div
If you want to add shadow to thead without using div, try the following code
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 100%;
}
table thead{
display:block;
position:relative;
box-shadow: 0px 1px 3px 0px #cccccc;
}
td, th {
border: 1px solid #dddddd;
text-align: left;
padding: 8px;
}
table tr{
display:table;
table-layout:fixed;
width:100%;
}
<table>
<thead>
<tr>
<th>Company</th>
<th>Owner</th>
<th>Country</th>
</tr>
</thead>
<tbody>
<tr>
<td>Alfred Trading</td>
<td>Alfred Thomas</td>
<td>Germany</td>
</tr>
<tr>
<td>Centro Moctezuma</td>
<td>Francisco Chang</td>
<td>Mexico</td>
</tr>
<tr>
<td>Ernst Handel</td>
<td>Roland Mendel</td>
<td>Australia</td>
</tr>
<tr>
<td>Island Trading</td>
<td>Helena Bennett</td>
<td>UK</td>
</tr>
<tr>
<td>Laughing Bacchus</td>
<td>John Cook</td>
<td>Canada</td>
</tr>
<tr>
<td>Magazzini Alimentari Riuniti</td>
<td>Giovanni Rovelli</td>
<td>Italy</td>
</tr>
</tbody>
</table>

Resources