How to make tbody width fixed regardless of scrollbar presence? - html

thead{
width: calc(100% - 17px);
display:block;
}
tbody{
display:block;
overflow-y: auto;
height:100px;
}
http://jsfiddle.net/mkgBx/
I can adjust width of thead to match that of tbody + scrollbar.
However, in cases when scrollbar is not displayed, tbody stretches further to the right.
Is there any way to fix tbody width?

I don't think you can set the tbodys width to ignore the presence of the scrollbar. Would a change to the structure of the mark-up be acceptable?
CSS
table{
font: 11px arial;
width: 245px;
}
th, td{
border:1px solid #000;
}
div {
height:90px;
width: 262px; /*table width + 17px */
overflow-y: auto;
}
HTML
<table>
<thead>
<tr>
<th style="width:165px">Name</th>
<th>Country</th>
</tr>
</thead>
</table>
<div>
<table>
<tbody>
<tr>
<td style="width:165px">Mart Poom</td>
<td>Estonia</td>
</tr>
<tr>
<td>David Loria</td>
<td>Kazakhstan</td>
</tr>
<tr>
<td>Wojciech Szczęsny</td>
<td>Poland</td>
</tr>
<tr>
<td>Gianluigi Buffon</td>
<td>Italy</td>
</tr>
<tr>
<td>Igor Akinfeev</td>
<td>Russia</td>
</tr>
</tbody>
</table>
</div>
http://jsfiddle.net/nF2NL/1/
This allows the div to provide the scrolling and the table to remain a set width.

You need to use JavaScript to handle this. Check if the scrollbar appears and adjust the width of the tbody accordingly.
Here's the JS code relevant to this where t is the tbody element:
if (t.clientHeight == t.scrollHeight)
{
t.style.width = "224px";
}
I've modified your JSFiddle to show you how it can work in your case.

I would not explicitly declare the <tbody> and <thead> tags for your table, as this is unnecessary. One solution to your problem would be to make the row (<tr>) of <th>s position: fixed. Someone else had a similar problem here: How to make a tables header static when scrolling

with width 100% it adapts to the table with, doesn't matter if it has a scroll or not.
thead{
width: 100%;
display:block;
}

Related

Why td size is different in some condition

When I try to make html tables, I wonder why
tdsize is different between filled cells and others.Does this come
from padding?
How to set to same size in each cells even if any content will be
filled?
If someone experienced same issue,please let me know. Thanks
td {
padding: 5px;
border: 1px solid black;
}
<table>
<td>1</td>
<td></td>
</table>
Your table has no fixed width, so the cells inside will only take up the space that their content requires.
If your table has a fixed width however, you can use table-layout to ensure all of the cells remain the same size:
Note also that you are missing required markup from your table:
table{
table-layout: fixed;
width: 10rem;
}
td {
padding: 5px;
border: 1px solid black;
};
<table>
<tbody>
<tr>
<td>1</td>
<td></td>
</tr>
</tbody>
</table>

Dynamic columns fixed length with auto scroll

I am using angular js 1.3 here. What I have is a modal up which when clicked adds an column to existing table, the name of the column is based upon the selection made in the modal. One can add as many columns here. All this works fine. What my issue is that I am not sure how to maintain fixed column width and scrolling.
The width of the column keeps decreasing when more columns are added and even the scrolling does not comes out properly.
Sorry the code is a lot so just posting some code together with jsfiddle here:
http://jsfiddle.net/aman1981/u1vbeos5/107/
<div class="panel-body">
<table class="table table-bordered">
<colgroup>
<col class="unique-id">
</colgroup>
<thead>
<tr>
<th class="unique-id">Name #</th>
<th contenteditable="true" ng-repeat="c in targetTable.columns" ng-model="c.label"></th>
<!--<th class="view-next-set">...</th>-->
<td class="center add-column"><a href ng-click="open()">+ Add Column</a></td>
</tr>
</thead>
<tbody>
<tr ng-repeat="r in targetTable.rows">
<td contenteditable="true" class=""></td>
<td contenteditable="true" ng-repeat="column in targetTable.columns" ng-model="r[column.id]" ng-blur="!r.id? addNewRow(r[column.id], r): undefined"></td>
<!--<td class="blank" colspan="2"></td>-->
</tr>
</tbody>
</table>
</div>
Also here is the image:
https://imgur.com/a/qCn1AO7
So you can set a minimum width fot your .table td and .table th
.table td,
.table th {
min-width: 120px;
}
And you can set the overflow of you .panel-body as auto:
.panel-body {
overflow: auto;
}
http://jsfiddle.net/u1vbeos5/116/
You have to set min-width and max-width to th and oveflow: auto to .panel-body....
Check below CSS
.table th {
max-width: 120px;
min-width: 120px;
}
.panel-body{
overflow: auto;
}
What I end up doing was to add the below classes to TD and Panel:
.fixed-width {
min-width: 50px !important;
width: 50px !important;
}
.panel-body {
overflow: auto;
}

How to make a table column be a minimum width but with a max-width

I want that a table column uses the minimum of place but after a certain width, it should wrap.
Here is what I have:
<table id="#table">
<tr>
<td>Content with a fix with</td>
<td class="min">This content should only use the necessary place but wrap after 200px</td>
</tr>
</table>
<style>
#table{
width: 100%;
}
.min {
width: 1%;
white-space: nowrap;
}
</style>
This makes the column use only the place which it needs but it it ets too long, it will make the table endless longer and I want to set the maximum of the allowed space.
Edit:
I think that with js it would be possible to calculate the width and change the css but I would prefer a solution without javascript or jquery.
Edit 2: I forgot to mention that the table has a width of 100%. So if I follow the given answer, the table cell has its autowidth (which is too wide) and a max-width so if the text is short, the td has a white space which I do not want.
Edit 3: Here is an image which explains better than me.
#billTable{
width:100%;
}
#numberTd{
text-align: center;
width:18%;
}
#weightTd{
text-align: center;
width:20%;
}
#nameTd{
text-align: left;
width: 1%;
white-space: nowrap;
}
#kgPriceTd{
text-align: right;
width:20%;
}
#priceTd {
text-align: right;
}
<div style="width:550px;">
<table>
<tr>
<th id='numberTd'>Packetzahl</th>
<th id='weightTd'>Kg</th>
<th id='nameTd'>Artikel</th>
<th id='kgPriceTd'>CHF / Kg</th>
<th id='priceTd' colspan="2">Total</th>
</tr>
<tr>
<td id='numberTd'>1</td>
<td id='weightTd'>0.688</td>
<td id='nameTd' class='min'>Siedfleisch</td>
<td id='kgPriceTd'>44.00</td>
<td id='priceTd'>8.2</td>
</tr>
</table>
</div>
You can control max width of an element by using max-width
https://developer.mozilla.org/en-US/docs/Web/CSS/max-width
The max-width CSS property sets the maximum width of an element. It prevents the used value of the width property from becoming larger than the value specified by max-width.
.min {
max-width: 200px;
}
<table>
<tr>
<td>Content with a fix with</td>
<td class="min">This content should only use the necessary place but wrap after 200px</td>
</tr>
</table>
You can apply width in percentages for the flexible columns, space it out so it looks good or make your table not 100%
Use the CSS property "max-width". I've attached an example with a border that shows this in use.
table, td {
border:1px solid #555;
border-collapse:collapse;
}
.min {
max-width:200px;
}
<table>
<tr>
<td>Content with a fix with</td>
<td class="min">This content should only use the necessary place but wrap after 200px</td>
</tr>
</table>

div inside table row not expanding 100%

I am appending a div in a table after table row,Its is not expending 100%,but always stick to first td.
<div style="width:100%;border:1px solid red;height:30px;">Test Div</div>
Note: i can place my div inside td by using colspan,but i have dynamic no of table columns,so i think i can't use colspan
Can you guys have please look at this ?
Logically you can not append DIV in between rows of table. If you want to have a div having 100% of width then use colspan property on TD and then add div in it.
Below is example as per your table structure, you need to have a new row as shown below instead of only DIV :
<tr>
<td colspan=6>
<div style="width:100%;border:1px solid red;height:30px;">Test Div</div>
</td>
</tr>
As pointed out by Nishesh Pratap, the right way to do it is to add dynamic colspan value.
But if you really want to go the CSS way only, you can play with the white-space rule. It will allow your text to overflow above the next TDs.
Keep in mind that this rule will also allow the text to overflow outside the table.
.forbidWrap{
white-space: nowrap;
border: 1px solid blue;
display: inline-block;
}
table{
table-layout: fixed;
width: 600px;
border-collapse: collapse;
text-align: left;
position: relative;
}
th{
background-color: #666;
color: white;
}
td{
border-bottom: 1px solid #ccc;
}
<table>
<tr>
<th>head</th>
<th>head</th>
<th>head</th>
<th>head</th>
</tr>
<tr>
<td>
<div class="forbidWrap">
The content of this div will overflow on other columns
</div>
</td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>7282</td>
<td>782</td>
<td>785</td>
<td>1589</td>
</tr>
</table>

td widths, not working?

So I have this code here:
<table>
<tr>
<td width="200px" valign="top">
<div class="left_menu">
<div class="menu_item">
Home
</div>
</div>
</td>
<td width="1000px" valign="top">Content</td>
</tr>
</table>
with the CSS
.left_menu {
background: none repeat scroll 0 0 #333333;
border-radius: 5px 5px 5px 5px;
font-family: Arial,Helvetica,sans-serif;
font-size: 12px;
font-weight: bold;
padding: 5px;
}
.menu_item {
background: none repeat scroll 0 0 #CCCCCC;
border-bottom: 1px solid #999999;
border-radius: 5px 5px 5px 5px;
border-top: 1px solid #FFFFCC;
cursor: pointer;
padding: 5px;
}
It works fine on my browser and I have tested it in every browser both mac and PC, but someone is complaining that the td with the width of 200 keeps changing width. I have no idea what he is talking about. Does anyone know why he or she is seeing the width change on the td?
It should be:
<td width="200">
or
<td style="width: 200px">
Note that if your cell contains some content that doesn't fit into the 200px (like somelongwordwithoutanyspaces), the cell will stretch nevertheless, unless your CSS contains table-layout: fixed for the table.
EDIT
As kristina childs noted on her answer, you should avoid both the width attribute and using inline CSS (with the style attribute). It's a good practice to separate style and structure as much as possible.
<table style="table-layout:fixed;">
This will force the styled width <td>. If the text overfills it, it will overlap the other <td> text. So try using media queries.
Width and/or height in tables are not standard anymore; as Ianzz says, they are deprecated. Instead the best way to do this is to have a block element inside your table cell that will hold the cell open to your desired size:
<table>
<tr>
<td valign="top">
<div class="left_menu">
<div class="menu_item">
Home
</div>
</div>
</td>
<td valign="top" class="content">Content</td>
</tr>
</table>
CSS
.content {
width: 1000px;
}
.left_menu {
background: none repeat scroll 0 0 #333333;
border-radius: 5px 5px 5px 5px;
font-family: Arial,Helvetica,sans-serif;
font-size: 12px;
font-weight: bold;
padding: 5px;
width: 200px;
}
.menu_item {
background: none repeat scroll 0 0 #CCCCCC;
border-bottom: 1px solid #999999;
border-radius: 5px 5px 5px 5px;
border-top: 1px solid #FFFFCC;
cursor: pointer;
padding: 5px;
}
This problem is quite easily solved using min-width and max-width within a css rule.
HTML
<table>
<tr>
<td class="name">Peter</td>
<td class="hobby">Photography</td>
<td class="comment">A long comment about something...</td>
</td>
</table>
CSS
.name {
max-width: 80px;
min-width: 80px;
}
This will force the first column to be 80px wide. Usually I only use max-width without min-width to reign in text that is very occasionally too long from creating a table that has a super wide column that is mostly empty. The OP's question was about setting to a fixed width though, hence both rules together. On many browsers width:80px; in CSS is ignored for table columns. Setting the width within the HTML does work, but is not the way you should do things.
I would recommend using min and max width rules, and not set them the same but rather set a range. This way the table can do it's thing, but you can give it some hints on what to do with overly long content.
If I want to keep the text from wrapping and increasing the height of a row - but still make it possible for a user to see the full text, I use white-space: nowrap; on the main rule, then apply a hover rule that removes the width and nowrap rules so that the user can see the full content when they over their mouse over it.
Something like this:
CSS
.name {
max-width: 80px;
white-space: nowrap;
overflow: hidden;
}
.name:hover {
max-width: none;
white-space: normal;
overflow:auto;
}
It just depends on exactly what you are trying to achieve. I hope this helps someone.
PS As an aside, for iOS there is a fix for hover not working - see CSS Hover Not Working on iOS Safari and Chrome
You can't specify units in width/height attributes of a table; these are always in pixels, but you should not use them at all since they are deprecated.
You can try the "table-layout: fixed;" to your table
table-layout: fixed;
width: 150px;
150px or your desired width.
Reference:
https://css-tricks.com/fixing-tables-long-strings/
You can use within <td> tag css : display:inline-block
Like: <td style="display:inline-block">
try this:
word-break: break-all;
try to use
word-wrap: break-word;
hope this help
I use
<td nowrap="nowrap">
to prevent wrap
Reference: https://www.w3schools.com/tags/att_td_nowrap.asp
Note that adjusting the width of a column in the thead will affect the whole table
<table>
<thead>
<tr width="25">
<th>Name</th>
<th>Email</th>
</tr>
</thead>
<tr>
<td>Joe</td>
<td>joe#email.com</td>
</tr>
</table>
In my case, the width on the thead > tr was overriding the width on table > tr > td directly.
I tried with many solutions but it didn't work for me so I tried flex with the table and it worked fine for me with all table functionalities like border-collapse and so on only change is display property
This was my HTML requirement
<table>
<thead>
<tr>
<th>1</th>
<th colspan="3">2</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td colspan="3">2</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td colspan="2">3</td>
</tr>
</tbody>
</table>
My CSS
table{
display: flex;
flex-direction: column;
}
table tr{
display: flex;
width: 100%;
}
table > thead > tr > th:first-child{
width: 20%;
}
table > thead > tr > th:last-child{
width: 80%;
}
table > tbody tr > td:first-child{
width: 10%;
}
table > tbody tr > td{
width: 30%;
}
table > tbody tr > td[colspan="2"]{
width: 60%;
}
table > tbody tr > td[colspan="3"]{
width: 90%;
}
/*This is to remove border making 1px space on right*/
table > tbody tr > td:last-child{
border-right: 0;
}
If you don't set the table to have table-layout: fixed and a certain width, then the table cells will stretch beyond their own width if content is wider. That's what he/she was complaining about.
Use
<table style="table-layout:fixed;">
It will force table to set to 100% width.Then use this code
$('#dataTable').dataTable( {
bAutoWidth: false,
aoColumns : [
{ sWidth: '45%' },
{ sWidth: '45%' },
{ sWidth: '10%' },
]
});
(table id is dataTable and having 3 column)
to specify length to each cell