Fit cell width to content - html

Given the following markup, how could I use CSS to force one cell (all cells in column) to fit to the width of the content within it rather than stretch (which is the default behaviour)?
td.block {
border: 1px solid black;
}
<table style="width: 100%;">
<tr>
<td class="block">this should stretch</td>
<td class="block">this should stretch</td>
<td class="block">this should be the content width</td>
</tr>
</table>
I realize I could hard code the width, but I'd rather not do that, as the content which will go in that column is dynamic.
Looking at the image below, the first image is what the markup produces. The second image is what I want.

I'm not sure if I understand your question, but I'll take a stab at it:
td {
border: 1px solid #000;
}
tr td:last-child {
width: 1%;
white-space: nowrap;
}
<table style="width: 100%;">
<tr>
<td class="block">this should stretch</td>
<td class="block">this should stretch</td>
<td class="block">this should be the content width</td>
</tr>
</table>

Setting
max-width:100%;
white-space:nowrap;
will solve your problem.

For me, this is the best autofit and autoresize for table and its columns (use css !important ... only if you can't without)
.myclass table {
table-layout: auto !important;
}
.myclass th, .myclass td, .myclass thead th, .myclass tbody td, .myclass tfoot td, .myclass tfoot th {
width: auto !important;
}
Don't specify css width for table or for table columns.
If table content is larger it will go over screen size to.

There are many ways to do this!
correct me if I'm wrong but the question is looking for this kind of result.
<table style="white-space:nowrap;width:100%;">
<tr>
<td class="block" style="width:50%">this should stretch</td>
<td class="block" style="width:50%">this should stretch</td>
<td class="block" style="width:auto">this should be the content width</td>
</tr>
</table>
The first 2 fields will "share" the remaining page (NOTE: if you add more text to either 50% fields it will take more space), and the last field will dominate the table constantly.
If you are happy to let text wrap you can move white-space:nowrap; to the style of the 3rd field will be the only way to start a new line in that field.
alternatively, you can set a length on the last field ie. width:150px, and leave percentage's on the first 2 fields.
Hope this helps!

Setting CSS width to 1% or 100% of an element according to all specs I could find out is related to the parent. Although Blink Rendering Engine (Chrome) and Gecko (Firefox) at the moment of writing seems to handle that 1% or 100% (make a columns shrink or a column to fill available space) well, it is not guaranteed according to all CSS specifications I could find to render it properly.
One option is to replace table with CSS4 flex divs:
https://css-tricks.com/snippets/css/a-guide-to-flexbox/
That works in new browsers i.e. IE11+ see table at the bottom of the article.

First, setting
td {
max-width: 0;
overflow: hidden;
text-overflow: ellipsis;
}
ensures that your your table cells will stretch.
Now you only need
td.fit {
width: 0;
min-width: fit-content;
}
on your fitting cells.
Note that now the table will only overflow in width if content of all fitting cells is too much to fit into a table-width of 100%.
table {
white-space: nowrap;
width: 100%;
}
td {
border: 1px solid black;
}
td {
max-width: 0;
overflow: hidden;
text-overflow: ellipsis;
}
td.fit {
width: 0;
min-width: fit-content;
}
<table>
<tr>
<td class="stretch">this should stretch</td>
<td class="stretch">this should stretch</td>
<td class="fit">this should be the content width</td>
</tr>
</table>

Simple :
<div style='overflow-x:scroll;overflow-y:scroll;width:100%;height:100%'>

Related

How to override default css of table

This question is already on stackoverflow. But the solutions are not working for me. Actually I'm working on an Angular project. I want to align Mode of comparison and the corresponding Dropdown in the middle with respect to each other. Here is the widget that I'm creating. I've clearly marked that part in the image:
Here is my HTML:
Note: pt-label, dls-combobox and dls-option are my custom made angular components.
<table>
<tbody>
<tr class="my-row">
<td class="first-col1">
<div class="comparing-switch1">
<pt-label>Mode of comparison </pt-label>
</div>
</td>
<td class="second-col1">
<div class="comparing-label1">
<dls-combobox placeholder="Time average">
<dls-option>
<pt-label>Time average</pt-label>
</dls-option>
</dls-combobox>
</div>
</td>
</tr>
</tbody>
</table>
and here is my CSS:
.my-row {
background: cornflowerblue;
}
.first-col1 {
background: magenta;
width: 50% !important;
}
.second-col1 {
width: 100%;
background: blueviolet;
padding-bottom: 10px;
}
table.stats tbody tr:nth-child(even) {
vertical-align: middle !important;
}
table.stats tbody tr {
vertical-align: middle !important
}
Even If I try to set it through margin and padding then both of them gets shifted even when the class names are different. One more thing I noticed. When I inspect the element table. When I remove vertical-align: baseline from these two places (as marked in the picture below) the my problem is solved:
What is wrong with my code. Please correct me.
Here vertical-align: baseline property is applied to the table. vertical-align: middle !important is applied for tr element.
since table has that property tr itself aligned in baseline. try adding vertical-align: middle for the table

Hide thead but keep its cells width in tbody

I always use Bootstrap grid classes in thead th tags so I'll no longer need repeating classes on tbody cells. for example:
<table>
<thead>
<tr>
<th class="col-xs-2">#</th>
<th class="col-xs-10">Title</th>
</tr>
</thead>
<tbody>
<tr><td>150</td><td>Long text in here</td></tr>
<tr><td>150</td><td>Long text in here</td></tr>
<tr><td>150</td><td>Long text in here</td></tr>
<tr><td>150</td><td>Long text in here</td></tr>
<tr><td>150</td><td>Long text in here</td></tr>
</tbody>
</table>
Now, I'm implementing a scenario that I should not use table headers. I tried display: none and visibility: hidden on thead but none of them works.
I guess I have following solutions (which are all bad INMHO!):
Add grid classes to each tbody cell (which in my large dynamic table is a bad thing)
Use css to target cells by the index eg: nth-child() which is also bad, because of duplicated CSS rules, and will be a pain in the ass becase table may dynamically change and I'll always need a SCSS compile!
Give thead a 1px height, with no inner text or anything.
Is there a better solution?
Something like this should work:
thead p {
margin: 0;
opacity: 0;
height: 0;
}
Of course the p is just an example, you can do this with any other tag.
Updated Fiddle: https://jsfiddle.net/8brbuy6v/1
Thanks to #Johann Kratzik suggestion, I managed to solve my own problem by hiding thead contents and using height: 0 on thead itself.
thead { opacity: 0; border: 0 none; height: 0; }
thead * { margin: 0; padding: 0; border: 0 none; height: 0px; }

how to set word break in table th or td, when column and table-layout auto using CSS

I'm hoping this is fairly simple.
I want to keep table-layout:auto for the table, as this allows the "name" column to size gracefully, while the url column uses up the remaining space.
The problem is when the url column gets large, the table automatically sizes beyond the width.
Ideally I'd like to hide the overflow on the "url" column once it expands out beyond the size of the containing div.
In the Jsfiddle example you can see the first table sizing nicely, with the "name" column taking up the available space.
In the second table, it overruns its containing div, because of the text in the "url" column. I cant workout how to hide this overflow.
http://jsfiddle.net/RDG4T/
<!DOCTYPE html>
<html>
<head>
<title>Table Test</title>
<style>
table {
table-layout:auto;
}
table, th, td
{
text-align:left;
white-space:nowrap;
text-overflow:ellipsis;
}
</style>
</head>
<div style="width:400px; border: 1px solid red; background-color:lightgrey;">
<table>
<thead>
<tr><th>Status</th><th style="width:100%">Name</th><th style="width:100%">Url</th></tr>
</thead>
<tbody>
<tr><td>On</td><td>Fred</td><td>http://www.google.com</td></tr>
<tr><td>On</td><td>Fred long long long name</td><td>http://www.google.com</td></tr>
<tr><td>On</td><td>Fred</td><td>http://www.google.com</td></tr>
<tr><td>On</td><td>Fred</td><td>http://www.google.com</td></tr>
<tr><td>On</td><td>Fred</td><td>http://www.google.com</td></tr>
<tr><td>On</td><td>Fred</td><td>http://www.google.com</td></tr>
<tr><td>On</td><td>Fred</td><td>http://www.google.com/xxxxxx </td></tr>
</tbody>
</table>
</div>
</div>
<p/>
<div style="width:400px; border: 1px solid red; background-color:lightgrey;">
<table>
<thead>
<tr><th>Status</th><th style="width:100%">Name</th><th style="width:100%">Url</th></tr>
</thead>
<tbody>
<tr><td>On</td><td>Fred</td><td>http://www.google.com</td></tr>
<tr><td>On</td><td>Fred long long long name</td><td>http://www.google.com</td></tr>
<tr><td>On</td><td>Fred</td><td>http://www.google.com</td></tr>
<tr><td>On</td><td>Fred</td><td>http://www.google.com</td></tr>
<tr><td>On</td><td>Fred</td><td>http://www.google.com</td></tr>
<tr><td>On</td><td>Fred</td><td>http://www.google.com</td></tr>
<tr><td>On</td><td>Fred</td><td>http://www.google.com/xxxxxxxxxxxxxxxxxxxxxxx</td></tr>
</tbody>
</table>
</div>
</body>
</html>
I used, It's only work set table-layout: fixed is this key to making it work.
word-wrap: break-word;
word-break: break-all;
table-layout: fixed;
check this jsFiddle help to you
Edit Updated
check this JsFiddle
Remove your inline style and now you css is
table {
table-layout:auto;
}
table, th, td
{
text-align:left;
word-break:break-all;
}
Your div wrapper is displaying the overflow. Add overflow hidden to it. FIDDLE
div{
overflow: hidden;
}
If you want to have an option to show the full url on hover you could try it this way:
Have a fiddle - Fiddle link!
HTML
<td>
<span>http://reallylongstring.com</span>
</td>
CSS
span {
width: 200px;
overflow: hidden;
display: block;
}
span:hover {
overflow: initial;
}
Since you're giving your div a fixed width, just add on overflow:hidden; to it's style and the overflow from the table won't show.
JSFiddle: http://jsfiddle.net/ginovva320/CFbKR/

HTML table ignoring element-style width

HTML table ignoring element-style width
I have an HTML table where certain cells have very long text contents.
I want to specify a width (in pixels) for these cells using jQuery, but the rendered table just ignores the given width.
Is there any way to force the table to respect this width?
Thanks!
JSFiddle: http://jsfiddle.net/sangil/6hejy/35/
(If you inspect the cell you can see the the computed width is different than the element-style width)
HTML:
<div id="tblcont" class="tblcont">
<table id="pivot_table">
<tbody>
<tr>
<th id="h0" >product</th>
<th id="h1" >price</th>
<th id="h2" >change</th>
</tr>
<tr>
<!-- this is the cell causing trouble -->
<td id="c00" >Acer 2400 aaaaaaaaaaaaaaaaaaaaaaaaaa</td>
<td id="c01" >3212</td>
<td id="c02" >219</td>
</tr>
<tr>
<td id="c10" >Acer</td>
<td id="c11" >3821</td>
<td id="c12" >206</td>
</tr>
</tbody>
</table>
</div>
CSS:
.tblcont {
overflow: hidden;
width: 500px;
}
table {
table-layout: fixed;
border-collapse: collapse;
overflow-x: scroll;
border-spacing:0;
width: 100%;
}
th, td {
overflow: hidden;
text-overflow: ellipsis;
word-wrap: break-word;
}
th {
height: 50px;
}
​Javascript:
$(document).ready(function() {
// THIS LINE HAS NO EFFECT!
$('#c00').width(30);
});​
I can see from your fiddle that you already have a good grasp on how to get the word truncation and such in-place. I think you may find it useful to do something like the following:
<table>
<colgroup>
<col style="width: 30px;" /> <!-- this style affects the whole 1st column -->
<col />
<col />
</colgroup>
<!-- the rest of your table here -->
</table>
This method works with the HTML specification in a way that is compliant - and will resize the whole column. If you instead change the display of the cell to inline-block, as mentioned above, what will happen is that you take the cell out of the table's flow - and other stylistic changes may cease working.
By styling the entire col using the code above, you use the table element's table-layout: fixed styling to your advantage instead.
Additionally - I noticed that you have the cells set up to use text-overflow: ellipsis; Check out this article on quirksmode to understand why it's not working. The fix you need is to make the following edit:
th, td {
border: solid #4682B4 1px;
overflow: hidden;
text-overflow: ellipsis;
word-wrap: break-word;
text-align: center;
white-space: nowrap; /* Add this line */
}
Table cells by default fit to their content and ignore your width.
Other possibility to the already provided answers:
Surround the text with some other container:
<td id="c00" ><div>Acer 2400 aaaaaaaaaaaaaaaaaaaaaaaaaa</div></td>
And change its width:
$('#c00 div').width(30);
You have a few issues:
table-layout: fixed tells the columns to be equal.
Then, even if you take that out, your text is wider than 30 pixels, with no spaces, so it's not going to go narrower than that "aaaaaaaaaa" etc. You'll need to make the text smaller, or add spaces.
Finally, width should be "30px" (in quotes).
Hope that helps.
Try this:
$('#c00').css("width","30px");
or this:
<td id="c00" style='width:30px'>
If you are using IE, you may need to have Compatability Mode on. Also, make sure you are importing the proper jQuery plugin.

Table column width as narrow as contained data?

I have three columns. The last two I want to make as narrow as the their contained data and the first column can take the rest of the width (table has 100% width).
How can you do this using CSS? Right now the columns on the right look silly with extra space. Ideas?
Just give the first column a width of 100% and if necessary give the cells in all other columns a white-space: nowrap to avoid their content being wrapped (again, only if necessary).
E.g.
<table>
<tr><td class="first">first</td><td>second</td><td>third</td></tr>
<tr><td class="first">first</td><td>second</td><td>third</td></tr>
<tr><td class="first">first</td><td>second</td><td>third</td></tr>
</table>
with
table { width: 100%; }
table td.first { width: 100%; }
Or the modern way if you don't bother about IE6 users:
table { width: 100%; }
table td:first-child { width: 100%; }
(so that you can remove class="first")
I just answered this with a little different approach with this more detailsed answer in a similar question, basically:
Add the class shrink to columns you want to have as narrow as possible
<table>
<tr><td>first</td><td class="shrink">second</td><td class="shrink">third</td></tr>
<tr><td>first</td><td class="shrink">second</td><td class="shrink">third</td></tr>
<tr><td>first</td><td class="shrink">second</td><td class="shrink">third</td></tr>
</table>
With this css:
td.shrink {
white-space: nowrap;
width: 1px;
}
With this you can define multiple columns to have minimum width on one line but the other's width stays dynamic (including possible line breaks).
Example Snippet
table {
width: 100%;
}
td {
padding: 10px;
}
td.shrink {
white-space: nowrap;
width: 1px;
}
<table>
<tr><td>first</td><td class="shrink">second</td><td class="shrink">third</td></tr>
<tr><td>first</td><td class="shrink">second</td><td class="shrink">third</td></tr>
<tr><td>first</td><td class="shrink">second</td><td class="shrink">third</td></tr>
</table>