I have a basic table with scrollable body. Doing that I had to set thead and tbody display:block and I also set the width for th and td.
For some reason the first column th doesn't line up with the first column tds.
Can anyone tell me what causes that?
CSS
thead,
tbody {
display: block;
}
thead {
text-align: left;
}
tbody {
background: yellow;
overflow-y: auto;
height: 6em;
}
thead th,
tbody td {
width: 4em;
padding: 2px;
}
thead tr th:first-child,
tbody tr td:first-child {
width: 8em;
background: salmon;
font-weight: normal;
}
Here is the Fiddle
The width property for DIV & TABLE works differently.
Use max-width & min-width to achieve the results you want:
thead tr th:first-child,
tbody tr td:first-child {
width: 8em;
min-width: 8em;
max-width: 8em;
word-break: break-all;
}
Edit:
(Editing the answer clarify the working of width in HTML, please point out if I got something wrong or missed anything!)
In divs the width property is used to define the size of the element and the content is fitted in accordingly, irrespective of parent and sibling width.
But in the case of a table, the size of an element is calculated according to content, and the width property gets a lower priority. Even sibling size is taken into consideration. Thus we have to use additional properties, like min-width and max-width to force the size we want!
Related
I have created a scrollable table that I want to use in jsfiddle but I cannot get the table cells to have a fixed height or max height. You will probably need to shrink your browser width to see what I am talking about when looking at my example here:
https://jsfiddle.net/trleithoff/jz62aenk/5/
table, tr td {
border: 1px solid black;
overflow: hidden;
text-overflow: ellipsis;
max-height: 30px;
height: 30px;
}
tbody {
display: block;
height: 125px;
overflow: auto;
}
thead, tbody tr {
display: table;
width: 100%;
table-layout: fixed;
}
In the first table cell (row 1 column 1) there is too much text and the ellipsis is working but it is working per line and not the entire text block. Does anyone know how to force a fixed height on a table cell?
table-cells won't work with overflow: hidden. Just wrap content in table-cell in div with max-height and overflow: hidden
tbody tr td div{
max-height: 30px;
overflow: hidden;
}
After reading many posts about having a fixed theader with a scrollabe tbody, most answers point to adjusting the tbody to display: block. However, display block makes my columns on the righter side have a skewed alignment the further right the column goes. I am dealing with dynamic data so sometimes my table is rendered with 16 columns, but sometimes it could be up to 25 columns. I want all the columns aligned properly, while maintaining a fixed thead with a scrollable tbody. Here is my CSS:
table {
overflow: hidden;
width: 100%;
height: 810px;
table-layout: fixed;
display: flex;
flex-direction: column;
align-items: center;
overflow: hidden;
}
thead,
tbody {
width: 100%;
}
tbody {
flex: 1;
overflow-y: scroll;
width: 100%;
}
th {
cursor: pointer;
}
th {
}
td {
display: flex;
justify-content: center;
}
td,
th {
padding: 0;
}
tr {
width: 100%;
display: flex;
}
tr th {
flex: 1;
}
tr td {
flex: 1;
}
Here is a small Codepen example: https://codepen.io/anon/pen/xMmqxK
The Codepen skew is less prominent than the skew on my website, so it's a bit hard to notice. Any help would be much appreciated. If I posted a screenshot you would be able to see the problem more, however, I cannot due to a corporate envrionment. Thanks again.
The main problem here is that the <th>s are text-align:center but the <td>s are text-align:left. This is why the skew increase when there is more space in each column.
Easiest solution is to remove padding-left: 10px from <tbody> (only included in your CopePen) and set <td>s to text-align: center.
If you need to have left-aligned <td>s then you can do the reverse and set your <th>s to text-align:left.
I am trying for a vertical scroll bar inside tbody with a fixed header. I tried solution provided in the link.
HTML table with 100% width, with vertical scroll inside tbody
table {
width: 100%;
border-spacing: 0;
}
thead, tbody, tr, th, td { display: block; }
thead tr {
/* fallback */
width: 97%;
/* minus scroll bar width */
width: -webkit-calc(100% - 16px);
width: -moz-calc(100% - 16px);
width: calc(100% - 16px);
}
tr:after { /* clearing float */
content: ' ';
display: block;
visibility: hidden;
clear: both;
}
tbody {
height: 100px;
overflow-y: auto;
overflow-x: hidden;
}
tbody td, thead th {
width: 19%; /* 19% is less than (100% / 5 cols) = 20% */
float: left;
}
It works fine if scroll bar appears.But if the rows are few and the scroll bar doesn't appear, then thead is not aligned with tbody. How can I fix the issue with css?
Once your tbody data move-out from assigned height, your y-axis get's activated.
tbody {
height: 50px;
display: inline-block;
width: 100%;
overflow-y:scroll;
}
That's because the CSS above reduces the width of the thead tr's width to 97% or (100% - the width of the scrollbar) to accomodate for the reduced width of the tbody because of the scrollbar in tbody only. If there is no scrollbar in tbody then the tbody remains fully 100% wide but the thead is still being narrowed.
You wish to fix is with the CSS, well the CSS cannot recognize the fact that there are not enough rows to for the scrollbar to show. You will be able to fix it using JavaScript though - just look in the answer you have cited, there are examples of using JavaScript to apply the width of the tbody columns to thead just at the beginning of the answer.
EDIT
Or force vertical scrollbar at all times, such that the width of the tbody doesn't change regardless of the row count:
tbody {
# ... other attributes
overflow-y: scroll;
}
taken from:
Force Vertical Scrollbar
Use tbody max-height:100px instead of height:100px
tbody {
max-height: 100px;
overflow-y: auto;
overflow-x: hidden;
}
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;
}
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}