In the following code I tried to make a long table scrollable ( with <thead> fixed ).
But the columns are not filling the table's width anymore, and thead columns are even not aligned with tbodys ones.
How to solve this ? is there another way to do the trick.
The code is here
<table>
<thead>
<tr>
<th>ROW 01</th>
<th>ROW 02</th>
</tr>
</thead>
<tbody>
<tr><td>LINE 01</td><td><img src="http://placehold.it/90x90"/></td></tr>
<tr><td>LINE 02</td><td><img src="http://placehold.it/90x90"/></td></tr>
<tr><td>LINE 03</td><td><img src="http://placehold.it/90x90"/></td></tr>
</tbody>
</table>
CSS here
table{width: 100%; background: #efefef; border-collapse: collapse }
thead, tbody{display: block}
thead{background: #555; color: white;}
tbody{height: 120px; overflow: auto}
td, th{ border: 1px solid red; }
You can try to turn your <tr> in display:table;+table-layout:fixed; It will help but columns may break from a row to another unless you set a fixed width to one or the other cell.
DEMO
Your CSS turns like:
table {
width: 100%;
background: #efefef;
border-collapse: collapse
}
thead, tbody {
display: block
}
thead {
background: #555;
color: white;
padding-right:1em;/* average width of the scroll bar of tbody */
}
tbody {
height: 120px;
overflow: auto
}
tr {/* here make those the table */
display:table;
table-layout:fixed;
width:100%;
}
td, th {/* set a width to go along with table-layout */
border: 1px solid red;
}
add this to your CSS
td:nth-child(1), th:nth-child(1) { min-width: 200px; } /* or the width you need, you may use percentages */
td:nth-child(2), th:nth-child(2) { min-width: 200px; }
since the browser adds a scrollbar, it needs to add the space for that element, thus, the misalignment will ALWAYS happen. The good news is that, in fact, you need to declare only the first column, so if you plan to use only 1 columns, just use something like this:
td:nth-child(1), th:nth-child(1) { width:20%; min-width: 200px; }
and it will be enough.
There's no way that I know to do this without declaring the width for AT LEAST the first column
try
thead, tbody{display:auto}
Related
This question came to my mind not because i am doing a project or something. It just popped up in my head.
I have read (from some posts on stack overflow) that position:relative does not affect table elements and that top,left,bottom,right wont work.
I tried this and found that it does affect the th element as shown in below snippet in some way. top and left properties actually worked on th.
But one thing isnt so clear about this effect, why is it that the border of the th stayed at its place and only the th migrated??? Any ideas as to why this happens?
I would really like to know if the border could be moved along with the th.
table {
border-collapse: collapse;
}
th {
border: 4px solid green;
position: relative;
top: 30px;
left: 30px;
}
<table>
<tr>
<th>THIS</th>
</tr>
</table>
Here is a fiddle
Setting position on tr, th, td elements is not a cross-browser idea. so instead of that, put your content inside a container inside your th element and position relatively that container.
<th><div>THIS</div></th>
And the style would be:
th > div { border: 4px solid green;position: relative;top: 30px;left: 30px; }
Working Fiddle
You just need to add display: block; to your th and it gets the position. You cannot position the th alone since it just moves the content.
table {
border-collapse: collapse;
}
th {
display: block;
border: 4px solid green;
position: relative;
top: 30px;
left: 30px;
}
<table>
<tr>
<th>THIS</th>
</tr>
</table>
this fixed-header table deforms column when resizing window horizontally. Is there way to stop that?
<!DOCTYPE html>
<html>
<head>
<style>
table {
width: 100%;
table-layout: fixed;
border-collapse: collapse;
}
table th {
border-left: 1px solid blue;
}
table th,
table td {
padding: 5px;
text-align: left;
border-left:1px solid blue;
}
table th, table td {
width: 150px;
}
table thead tr {
display: block;
position: relative;
}
table tbody {
display: block;
overflow: auto;
width: 100%;
height: 300px;
}
</style>
</head>
<body>
<table>
<thead>
<tr>
<th>id</th>
<th>pick_up_location</th>
<th>destination</th>
<th>instruction</th>
<th>created_at</th>
<th>status</th>
</tr>
</thead>
<tbody>
<tr>
<td>12322</td>
<td>Whanga Road</td>
<td>Crescent Street</td>
<td>Call when arrive</td>
<td>123442342331</td>
<td>comming</td>
</tr>
</tbody>
</table>
</body>
</html>
Keep in mind this fixed-header table. Mean when you have 100 rows. you can scroll the row but the header position is fixed. The display block attributes can not be removed.
UPDATE:
With Mark answer, the table looks fine but still deform at small screen. A screenshot of it
To don't have problems with resizing you have to work in height and width with %.
Like : width: 30%;
height: 40%;
Hope help you.
Do not apply an explicit width or height to tag. Instead, give it:
max-width:100%;
max-height:100%;
just modify the last two ccs declarations as follows:
table{
display: block;
position: relative;
}
table tbody {
position : relative;
overflow: auto;
width: 100%;
height: 300px;
}
Adding word-break: break-all; to all the cells makes your code work (almost, since all characters are not of the same width)
See https://jsfiddle.net/3wn1zzfn/
Your problem is that when it is not possible to fit all cells in a table, the width: 150px; is overridden, and widths are now based on length of the line.
The problem here is that you are applying display: block, you shouldn't use it on tables. Also remove px values on tables. use %, or remove it at all
Remove these lines of code:
table th,
table td {
/*width: 150px*/
}
table thead tr {
/*display: block;
position: relative;*/
}
table tbody {
/*display: block;*/
overflow: auto;
width: 100%;
height: 300px;
}
Here a codepen to show it:
http://codepen.io/sandrina-p/pen/qNYork?editors=1100
--EDIT--
before -1 please can you tell me what's wrong with my solution, to improve it?
Given this table:
<table>
<tr>
<td rowspan="2"><a>Hello</a></td>
<td><a>World</a></td>
</tr>
<tr>
<td><a>!</a></td>
</tr>
</table>
I want to style the a element in every td to be 100 percent height:
table, td {
border: 1px solid black;
}
td {
height:400px;
}
a {
background-color: red;
height: 100%;
display:block;
}
This (JsFiddle) works fine on IE and Chrome. However Firefox seems to have a problem with the colspan.
So I tried to change the given fixed height on tr instead of td:
table, td {
border: 1px solid black;
height: 100%
}
tr {
height:400px;
}
a {
background-color: red;
height: 100%;
display:block;
}
This (JsFiddle) works fine on Firefox and Chrome, but not on IE.
On the right side is, what I want:
How can I make this work in all Browsers?
if you want more control over the TDs, i would highly suggest to use the display option of table and table-cell:
.table-wrapper{
position:relative;
display:table;
width:100%;
height:400px;
border:1px solid #000;
}
.table-wrapper a{
position:relative;
display:table-cell;
height:100%;
text-align:center;
vertical-align:middle;
}
you can easily choose the width, and control the content of "table-cell". This is supported by IE9.
link of demo:https://jsfiddle.net/keinchy/mq3nafje/6/
I want a pure CSS solution with a fixed table header and same column width for <th> and <td> with different content. I have taken an example and modified it to get column with different content: http://jsfiddle.net/jd72op9n/4/
table tbody,table thead {
display: block; /* comment to get same column with*/
}
table tbody {
overflow: auto;
height: 100px;
}
It seems that I cannot have both:
If take http://jsfiddle.net/jd72op9n/4/ I get a fixed header but the columns for th and td are not the same.
If I remove "display: block", I get the correct column but not fixed header.
Do you have a solution to get both?
I guess the only way is to strictly specify the width of the cells like this:
table th, table td{
width: 80px;
}
tbody{
width: 100%;
margin-right: 20px;
}
Please try this fiddle
And if you want to change width to certain cell, for example the 4th with the long text, you can add this css rule:
th:nth-child(4), td:nth-child(4){
width: 120px;
}
http://jsfiddle.net/patelnirpendra/2bs886p0/
css :
table tbody,table thead {
display: block;
}
table{
border: 1px solid black;
table-layout: fixed;
}
th, td {
border: 1px solid black;
overflow: hidden;
width: 150px;
}
I have a html <table> that have dynamic width (changes with window size), and a fixed width <span> (500px).
I want to display both next to each other so that both would fill the whole width of the parent container
I want to do so only using CSS (not js)
I have been playing around with CSS but it seems to be ruining the table's width
HTML
<div class='container'>
<table class='table'>....</table>
<span class='span'>....</span>
</div>
CSS
.container {
......
}
.table {
.....
}
.span {
width: 500px;
display: inline-block; //or block if neccessary
}
You may give a try with the table-layout propertie to .container and span.
Browsers should create themselves the element missing to produce the first table-cell.
DEMO
span {
display:table-cell;
width:500px;
border:solid;
}
table {
border:solid;
margin:0;
width:100%;
}
.container {
display:table;
width:100%;
table-layout:fixed;
}
This should work
because of table-layout:fixed
and because browser should create themselves the missing element (like a tbody is always produced in a <table> when missing or when in a document is missing either tags like html or body ).
Demo
css
body, html {
margin:0;
padding:0;
}
.container {
}
table {
width: calc(100% - 500px);
border-collapse: collapse;
float: left;
}
/* Zebra striping */
tr:nth-of-type(odd) {
background: #eee;
}
th {
background: #333;
color: white;
font-weight: bold;
}
td, th {
padding: 6px;
border: 1px solid #ccc;
text-align: left;
}
.span {
display: inline-block;
width: 500px;
height: 100px;
background: red;
}
html
<div class='container'>
<table>
<thead>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>etc</th>
</tr>
</thead>
<tbody>
<tr>
<td>Gaurav</td>
<td>Singh</td>
<td>etc</td>
</tr>
<tr>
<td>Gaurav</td>
<td>Singh</td>
<td>etc</td>
</tr>
</tbody>
</table> <span class='span'>....</span>
</div>