How to distribute free space between <table> columns evenly? - html

I want to make my html table to take the full window width in a way that th elements content does not overlap + there are even spacing between column headings (see the picture).
The space must scale with window width up to 0 (all words are hugging each other). How to do it?
big screen example:
small screen example:
By default the spacing between th elements gets proportional to the width of the elements.
If I use table-layout: fixed the width of the columns will be equal, i.e. space between them unti-proportional to width.
P.S. I need to use border-spacing: 0 because I need to highlight full table rows and with positive border-spacing the table background will be visible inbetween cells.
P.P.S. the question is specifically about table layout. I know I can do anything with grid and flex box, but I'm trying to use right tags for right content, and in this case I have a table data, i.e. the solution should work with "display: table".
table {
width: 80%;
background: gray;
}
th {
text-align: left;
}
.auto {
background: #90EE90;
}
.fixed {
table-layout: fixed;
background: #ADD8E6;
}
<table class="auto">
<thead>
<tr>
<th>1</th>
<th>333</th>
<th>999999999</th>
<th>22</th>
</tr>
</thead>
<tbody>
<tr>
<td>aa</td>
<td>aa</td>
<td>aa</td>
<td>aa</td>
</tr>
</tbody>
</table>
<table class="fixed">
<thead>
<tr>
<th>1</th>
<th>333</th>
<th>999999999</th>
<th>22</th>
</tr>
</thead>
<tbody>
<tr>
<td>aa</td>
<td>aa</td>
<td>aa</td>
<td>aa</td>
</tr>
</tbody>
</table>

A probably a bit hacky only css solution would be to insert empty th/td elements and give them a realive width of 100% / amount of filled columns. Here 4 columns -> gap-width: 25% (use calc() if odd amount)
table {
width: 80%;
border-spacing: 0
}
th {
text-align: left;
}
th,
td {
border: 1px solid teal;
}
.gap {
width: 25%;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<table>
<thead>
<tr>
<th>1</th>
<th class="gap"></th>
<th>333</th>
<th class="gap"></th>
<th>999999999</th>
<th class="gap"></th>
<th>22</th>
<th class="gap"></th>
</tr>
</thead>
<tbody>
<tr>
<td>aa</td>
<td class="gap"></td>
<td>aa</td>
<td class="gap"></td>
<td>aa</td>
<td class="gap"></td>
<td>aa</td>
<td class="gap"></td>
</tr>
</tbody>
</table>
</body>
</html>

Related

Select Columns only conaitaing numbers in CSS

I am working with a table that has some columns containing numeric values. I want the heading as well as the data of the column (<th> and <td>) to be aligned right.
I don't know how to select only the columns containing numeric values in <td>.
console.log("hi");
table {
table-layout: fixed;
border-collapse: collapse;
border-top: 1px solid gray;
border-bottom: 1px solid gray;
}
tbody, thead, tfooter {
text-align: left;
}
tfoot {
border-top: 1px solid gray;
}
tbody tr:nth-child(odd) {
background-color: rgb(222, 227, 224);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Hello!</title>
<link rel="stylesheet" href="/style.css" />
</head>
<body>
<table>
<caption>
A summary of the UK's most famous punk bands
</caption>
<thead>
<tr>
<th scope="col">Band</th>
<th scope="col">Year formed</th>
<th scope="col">No. of Albums</th>
<th scope="col">Most famous song</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Buzzcocks</th>
<td>1976</td>
<td>9</td>
<td>Ever fallen in love (with someone you shouldn't've)</td>
</tr>
<tr>
<th scope="row">The Clash</th>
<td>1976</td>
<td>6</td>
<td>London Calling</td>
</tr>
<tr>
<th scope="row">The Damned</th>
<td>1976</td>
<td>10</td>
<td>Smash it up</td>
</tr>
<tr>
<th scope="row">Sex Pistols</th>
<td>1975</td>
<td>1</td>
<td>Anarchy in the UK</td>
</tr>
<tr>
<th scope="row">Sham 69</th>
<td>1976</td>
<td>13</td>
<td>If the kids are united</td>
</tr>
<tr>
<th scope="row">Siouxsie and the Banshees</th>
<td>1976</td>
<td>11</td>
<td>Hong Kong Garden</td>
</tr>
<tr>
<th scope="row">Stiff Little Fingers</th>
<td>1977</td>
<td>10</td>
<td>Suspect Device</td>
</tr>
<tr>
<th scope="row">The Stranglers</th>
<td>1974</td>
<td>17</td>
<td>No More Heroes</td>
</tr>
</tbody>
<tfoot>
<tr>
<th scope="row" colspan="2">Total albums</th>
<td colspan="2">77</td>
</tr>
</tfoot>
</table>
</body>
</html>
In your HTML it appears only the 2nd and 3rd columns are the ones that are numeric.
You can use CSS' nth child selector and target the 2nd and 3rd cols in each row.
table tbody tr td:nth-child(2) {
text-align: right;
}
table tbody tr td:nth-child(3) {
text-align: right;
}
You can use the same method for any column in your table footer. But if your table can be more complex then the best option is to use JavaScript to loop over the <td> and check if its content is numbers only and then add a class or inline style to it.
Reference: https://developer.mozilla.org/en/docs/Web/CSS/:nth-child

Why doesn't the body become the width I specify?

Why is this sample table, the body does not have the specified width?
<html>
<head>
<style type="text/css">
table{
border-collapse:collapse;
}
table,th, td{
border: 4px, solid;
}
#article{
background-color: #FDF8AB;
border: 3px solid #85A110;
width: 760px;
margin-top: 20px;
margin-left: auto;
margin-right: auto;
}
</style>
</head>
<body id="article">
<div>
<table>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Date</th>
<th>Notes</th>
</tr>
<tr>
<td>Jill</td>
<td>Smith</td>
<td>20-12-2013</td>
<td>AAAa</td>
</tr>
<tr>
<td>Jill</td>
<td>Smith</td>
<td>20-12-2013</td>
<td>AAAa</td>
</tr>
<tr>
<td>Eve </td>
<td>Jackson</td>
<td>20-12-2013</td>
<td>AAAa</td>
</tr>
<tr>
<td>John </td>
<td>Doe</td>
<td>20-12-2013</td>
<td>AAAa</td>
</tr>
<tr>
<td>Adam </td>
<td>Johnson</td>
<td>20-12-2013</td>
<td>AAAa</td>
</tr>
</table>
</div>
</body>
</html>
You are using
#article {
background-color: #FDF8AB; /* Other Styles */
}
So when you are not using any background color for your html element, the next parent level element is body and so you are confused, provide a background color to html element and you'll see the difference
Demo
My Suggestion:
You should not use fixed width for body tag, let it be width: 100%; which it is, by default, as it's a block level element, instead, wrap your table inside a container div, use fixed width and auto margins for this div which will give you the desired effect and also in a neat way
The Right Way
You should place everything within the body into a div or section container/wrapper.
You define a width on the wrapper.
You apply a style to the body of text-align center.
So that the div#container or section#content has a defined width and margin:0 auto;.
Also if you have a 3px border, your width with be width + border left + border right. So that's where the extra 6 pixels are coming from.

How do you modify the colspan property when hiding columns via CSS?

I am trying to implement "the unseen column" responsive table technique by assigning a class to a specific column that I can hide if the browser is too narrow.
Truncated dummy html example:
<!doctype html>
<html>
<head>
<style>
table {
width:100%;
background-color:#000;
border-spacing: 1px;
}
table tr {
background-color:#fff;
}
table tr:nth-child(2n+1) {
background-color: #ccc;
}
table tr.Title
{
color:#fff;
background-color:#0e228c;
}
table tr.ColumnHeadings
{
background-color:#e4e0d4;
}
#media only screen and (max-width: 1024px) {
.VolumeCell {display:none;}
}
</style>
</head>
<body>
<table>
<tr class="Title">
<th colspan="6">Stock Prices</th>
</tr>
<tr class="ColumnHeadings">
<th>Code</th>
<th>Company</th>
<th>Price</th>
<th>Change</th>
<th>Change %</th>
<th class="VolumeCell">Volume</th>
</tr>
<tr>
<td>AAC</td>
<td>Austrailian Agricultural Company Ltd</td>
<td>$1.39</td>
<td>-0.01 </td>
<td>-0.36%</td>
<td class="VolumeCell">9,395</td>
</tr>
<tr>
<td>AAD</td>
<td>Ardent Liesure Grp.</td>
<td>$1.15</td>
<td>+0.02 </td>
<td>1.32%</td>
<td class="VolumeCell">56,431</td>
</tr>
<tr>
<td>AAX</td>
<td>Ausenco Ltd.</td>
<td>$4.00</td>
<td>-0.04 </td>
<td>-.99%</td>
<td class="VolumeCell">90,641</td>
</tr>
</table>
</body>
</html>
This is all fine and dandy, except there is a single pixel border or space remaining on the far right of the table in some browsers, specifically Chrome 26. I've tried tweaking the border-collapse and border on many of the table elements in the media query. I've also tried setting negative margins to account for the pixel. Being the anal-retentive person I am, I can't let it go, but I would prefer not to use jQuery to solve this problem.
So how can I account for the missing column?
In case one has similar problem, but for colspan not expanding the whole row, in which case caption makes no sense.
A simple trick is to not hide desired columns with display: none;, but rather do
width: 0px;
This way column will still exist for colspan, all though not visible.
You can't modify the colspan attribute from CSS. If you really needed to change the value, you would have to modify the DOM.
However, instead of the "Title" class that you are using to encompass all the columns, you can use a <caption> element which does exactly what you want. It effectively is the title of the table. See http://www.quackit.com/html_5/tags/html_caption_tag.cfm
Here is a modified version of your markup that uses the caption element. When resized in Chrome it behaves how you would like.
table {
width:100%;
background-color:#000;
border-spacing: 1px;
}
table tr {
background-color:#fff;
}
table tr:nth-child(2n+1) {
background-color: #ccc;
}
caption
{
color:#fff;
background-color:#0e228c;
}
table tr.ColumnHeadings
{
background-color:#e4e0d4;
}
#media screen and (max-width: 1024px) {
.VolumeCell {display:none;}
}
<table>
<caption>
Stock Prices
</caption>
<tr class="ColumnHeadings">
<th>Code</th>
<th>Company</th>
<th>Price</th>
<th>Change</th>
<th>Change %</th>
<th class="VolumeCell">Volume</th>
</tr>
<tr>
<td>AAC</td>
<td>Austrailian Agricultural Company Ltd</td>
<td>$1.39</td>
<td>-0.01 </td>
<td>-0.36%</td>
<td class="VolumeCell">9,395</td>
</tr>
<tr>
<td>AAD</td>
<td>Ardent Liesure Grp.</td>
<td>$1.15</td>
<td>+0.02 </td>
<td>1.32%</td>
<td class="VolumeCell">56,431</td>
</tr>
<tr>
<td>AAX</td>
<td>Ausenco Ltd.</td>
<td>$4.00</td>
<td>-0.04 </td>
<td>-.99%</td>
<td class="VolumeCell">90,641</td>
</tr>
</table>

Table with 3 columns. Fixed center column width. How to have shared width on other two columns?

i have a 100% width table with 3 columns. The center column must be 600px width. How can I have the other two equal width while using up the remaining space?
<table style="width: 100%">
<tr>
<td>left</td>
<td style="width: 600px">center</td>
<td>right</td>
</tr>
</table>
Currently, depending on the content of left or right columns, they are always uneven. I have tried setting 50% width on the left and right as well as other numbers and min-width trials.
Please no jQuery/Javascript.
New answer to this old question.
Give the middle column th a max-width and min-width instead of width
Give the left and right th a width of 50%.
Don't give the table a width at all.
I have fixed this examples middle column width at 300px.
jsBin Example!
CSS
table {
border-collapse: collapse;
}
th, td {
border: solid 1px #CCC;
padding: 10px;
}
.fixed {
max-width: 300px;
min-width: 300px;
}
.fluid {
width: 50%;
}
HTML
<table>
<thead>
<tr>
<th class="fluid">First Column</th>
<th class="fixed">Fixed Column</th>
<th class="fluid">Third Column</th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
The use of "colgroup" tag could be a great help for this.
<table class="fixed-center-table" border="1">
<thead>
<colgroup>
<col>
<col id="middle-column">
<col>
</colgroup>
<tr>
<th>First Column</th>
<th></th>
<th>Third Column</th>
</tr>
</thead>
<tbody>
<tr>
<td>AAAAAA</td>
<td>BBBB</td>
<td>CCCCC</td>
</tr>
<tr>
<td>AAAAAA</td>
<td>BBBB</td>
<td>CCCCC</td>
</tr>
<tr>
<td>AAAAAA</td>
<td>BBBB</td>
<td>CCCCC</td>
</tr>
</tbody>
</table>
.fixed-center-table {
table-layout: fixed;
width: 100%;
border-collapse: collapse;
}
.fixed-center-table td{
text-align: center;
}
col#middle-column {
width: 600px;
}
I guess "align=center" used with center column may help you.

Fixed column width with horizontal scrolling doesn't show when the column widths larger than container

I am trying to have a table with fixed column widths and horizontal scrolling when the width of the columns is greater than the containing block.
The only time the fixed column widths work is when the sum of column widths < containing block (i.e. no scroll)
Otherwise, the fixed column widths seem to get ignored. Anyone know how to do this? here's my html and css.
<div class="scroll-content-grid21">
<div class="ExtraScrollableContainerDiv">
<table class="regular" style="width:1440px">
<tr>
<th>Item #</th>
<th>Description</th>
<th>Rate</th>
<th>Qty</th>
<th>Price</th>
<th>Amount</th>
<th>Prev Qty</th>
<th>Prev Amt</th>
etc. more columns
</tr>
<%
for (int i = 0; i < this.Model.BusinessObject.Items.Count; i++)
{
%>
<tr>
<td style="width:80px"><%: this.Model.BusinessObject.Items[i].SnapshotReferenceNumber %></td>
<td style="width:240px"><%: this.Model.BusinessObject.Items[i].SnapshotShortDescription%></td>
<td style="width:80px"><%: this.Model.BusinessObject.Items[i].SnapshotUnitRate%></td>
<td style="width:80px"><%: this.Model.BusinessObject.Items[i].SnapshotQuantity%></td>
<td style="width:80px"><%: this.Model.BusinessObject.Items[i].SnapshotUnitOfMeasureId%></td>
<td style="width:80px"><%: this.Model.BusinessObject.Items[i].SnapshotAmount%></td>
<td style="width:80px"><%: this.Model.BusinessObject.Items[i].PreviousToDateQuantity%></td>
<td style="width:80px"><%: this.Model.BusinessObject.Items[i].PreviousToDateAmount%></td>
etc. more columns
</tr>
</table>
div.scroll-content-grid21
{
overflow : auto;
width: 1072px; /* notice, smaller than the table width */
height: 500px;
}
table.regular
{
table-layout:fixed;
margin-top: 0.1em;
margin-bottom: 0.1em;
border-collapse: collapse;
text-align: left;
}
The first thing I can see is that you need to give width to your table header cells (th) as well. try this to see if it helps. Also have you given {overflow-x:auto} to td and th ?
Here's a sample for anyone else who needs it:
<html>
<head>
<style>
div.outer
{
width : 500px;
overflow : auto;
}
table
{
table-layout:fixed;
width: 100%; /* same as containing div */
}
th, td
{
border: solid 1px #ccc;
}
</style>
</head>
<body>
<div class="outer">
<div class="scrollable">
<table>
<thead>
<th style="width:50px">One</th>
<th style="width:300px">Two</th>
<th style="width:200px">Three</th>
<th style="width:200px">Four</th>
<th style="width:200px">Five</th>
</thead>
<tbody>
<tr>
<td>001</td>
<td>My really long description here</td>
<td>10.0 units</td>
<td>$100.00 dollars</td>
<td>$1000.00 total</td>
</tr>
<tr>
<td>002</td>
<td>This is number 2</td>
<td>5 units</td>
<td>$5.00 dollars</td>
<td>$25.00 total</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>