I've got a table with the contents of the cells completely filling them. I gave the content a fixed width and a height of 100% so that elements that get bigger are still able to grow the cells. The cells also have a minimum height via the simple height attribute so the 100% height of the content has an effect. In Chrome and Edge everything works fine, but in Firefox the cells don't grow:
Chrome:
Firefox:
If you want to try yourself:
table {
border-spacing: 8px;
font-size: 14px;
}
td {
height: 50px;
}
td div {
height: 100%;
width: 200px;
background-color: green;
}
<table>
<tr>
<td>
<div>
This div is normal sized.
</div>
</td>
<td>
<div>
This div is normal sized.
</div>
</td>
</tr>
<tr>
<td>
<div>
This div is also normal sized but should size accordingly.
</div>
</td>
<td>
<div>
This div is very very big so it gets higher and should affect other divs in the same row. But not in Firefox apparently.
</div>
</td>
</tr>
</table>
Not sure if this a bug in Firefox or a feature in Chrome, but the way I understood table sizing is that table elements cannot have a fixed size. Instead their width and height attributes are used as a min-width / min-height and they grow according to their content. Is there a quick workaround or should I rebuild the table in flexbox layout?
Update
By the way, when I instead set a fixed height on the row / tr and height: 100%; on the td, it works in Firefox. But then it's broken in Chrome...
I managed to find a workaround. I added the lines
#-moz-document url-prefix() {
tr {
height: 50px; // Your min height
}
td {
height: auto;
}
}
to my css and now it seems to display correctly in firefox and chrome. Not very clean but it works.
Apparently Chrome was to adopt Firefox behaviour with tables in Version 50 but reverted because it broke too many layouts. The trick applying height: 100%; to the tds worked because all percent sizes are automatically translated to auto. Makes much more sense then.
Related
I have recreated a CSS compatibility issue I have come across between Chrome and Firefox.
An "inner" DIV with 100% height inside a Table cell which is inside a "container" DIV of fixed height. I want the inner DIV to fill the cell and dynamically add text to it such that a scrollbar appears when it begins to overflow.
In the JSFiddle you can see the code in both Chrome and Firefox. In Chrome it behaves as expected but in Firefox the scrollbar doesn't display and the inner DIV just keeps expending beyond the height of the container DIV.
JSFiddle code to try in both Chrome and Firefox
HTML as follows:
<style>
#container {
height:80px;
width:100%;
border:1px solid;
overflow:hidden;
resize:vertical;
}
#inner {
height:100%;
width:300px;
border:2px solid red;
overflow-y:auto;
}
table{
height:100%;
}
</style>
<div id="container">
<table>
<tr>
<td>
<div id="inner">
Test<br/>Test<br/>Test<br/>Test<br/>Test<br/>
</div>
</td>
<td>
<img src="https://doc-snapshots.qt.io/qt-mobility/images/used-in-examples/video/qmlvideo/images/close.png" />
</td>
</tr>
</table>
</div>
EDIT, further requirement: I forgot to mention that I have this setup inside a resizable DIV i.e. the Container DIV is able to resize it's height so that the table and Inner DIV resize accordingly.
Thats a common mistake. Whenever an element is set to height: 100% or any other percentage, it relates to the height of its parent. So when using this, its important to define a height for the parent of your element:
To demonstrate the problem: Adding a class to the parent <td class="fix"> and add some css fixes the problem:
.fix {
height: 80px;
display: block;
}
WORKING JSFIDDLE DEMO
Keep in mind that setting the display attribute of a table cell from table-cell to block is something you should avoid, as you are changing the elements roots. Consider a solution without using a <table> markup if you have got the possibilities.
#inner {
border: 2px solid red;
height: 75px;
overflow: auto;
width: 300px;
}
You can use this CSS. I think it may work fine.
I am trying to build a table that contains a td which has a width set in percentage and when overflown a horizontal scrollbar.
Unfortunately I don't manage to make this happen.
http://jsfiddle.net/ne45s2wf/1/
HTML
<div class="container">
<table>
<tbody>
<tr>
<td>cell 1
</td>
<td>cell 2
</td>
<td class="too-long">cell 3 loooooooooooooooooooooooooooooooooooooooooooong
</td>
</tr>
</tbody>
</table>
</div>
CSS
.container {
position: relative;
max-width: 500px;
background-color: red;
}
table {
width: 100%;
}
td.too-long {
background-color: darkgreen;
display: inline-block;
width: 20%;
overflow-x: scroll;
}
First thing I wonder is what is the td-width in percentage relative to? And is it possible to set it to be relative to the table?
I would set a maximum width in percentage for the td with overflow hidden. While this works for the td, the parent containers do not align their width to the td child when its width is set with percentage. The parents width is as if the child did not have any width set. Furthermore the table now is not "responsive" any more.
I would take a look at bootstrap. I am not sure exactly what you mean but it seems like you are having trouble with your tables overflowing. Bootstrap has responsive tables which will scroll in the way you specify at small sizes. Take a look at this:
http://getbootstrap.com/css/#tables-responsive
I'm trying to fill the center cell of a table with a div element. For the purposes of illustrating the problem, the div is styled with a red background. It seems to work in Chrome, but not IE. In the fiddle below, IE is setting the height of the div to the minimum height necessary to contain its content. In tinkering around with this problem with different CSS settings, I managed to get IE to interpret "height: 100%"; as "the height of the browser window". However, as the question states, I want IE to interpret it as the height of the td cell. Any ideas?
http://jsfiddle.net/UBk79/
CSS:
*{
padding: 0px;
margin: 0px;
}
html, body{
height: 100%;
}
#container{
height:100%;
width: 100%;
border-collapse:collapse;
}
#centerCell{
border: 1px solid black;
}
#main{
height: 100%;
background-color: red;
}
HTML:
<table id="container">
<tr id="topRow" height="1px">
<td id="headerCell" colspan="3">
TOP
</td>
</tr>
<tr id="middleRow">
<td id="leftCell" width="1px">
LEFT
</td>
<td id="centerCell">
<div id="main">CENTER</div>
</td>
<td id="rightCell" width="1px">
RIGHT
</td>
</tr>
<tr id="bottomRow" height="1px">
<td id="footerCell" colspan="3">
BOTTOM
</td>
</tr>
</table>
I did some more research on this and collected some info that might come in handy to others trying to solve similar problems. The CSS spec says the following three things that I think are important:
First, re: specifying the height (of a div) as a percentage:
The percentage is calculated with respect to the height of the generated box's containing block. If the height of the containing block is not specified explicitly (i.e., it depends on content height), and this element is not absolutely positioned, the value computes to 'auto'.
http://www.w3.org/TR/CSS21/visudet.html#the-height-property
... a height of 'auto' won't fill the cell unless the content is taller than the cell's minimum height. But if we try to explicitly set the height of the containing cell or row, then we run into the following problem:
CSS 2.1 does not define how the height of table cells and table rows is calculated when their height is specified using percentage values.
http://www.w3.org/TR/CSS21/tables.html#height-layout
Since the spec doesn't define it, I guess it's not too surprising that Chrome and IE choose to calculate it differently.
Alternatively, (as xec indirectly pointed out) trying to use relative positioning has the following spec problem:
The effect of 'position:relative' on table-row-group, table-header-group, table-footer-group, table-row, table-column-group, table-column, table-cell, and table-caption elements is undefined.
www.w3.org/TR/CSS21/visuren.html#propdef-position
So I've concluded there's probably not a pure CSS way to solve the problem that one can reasonably expect to work on most browsers.
At first, I thought, "Wow, the CSS spec is pretty shoddy and incomplete for leaving all this stuff undefined." As I thought about it more, though, I realized that defining the spec for these issues would a lot more complicated than it appears at first. After all, row/cell heights are calculated as a function of the heights of their content, and I want to make the height of my content a function of the row/cell height. Even though I have a well-defined, terminating algorithm for how I want it to work in my specific case, it's not clear that the algorithm would easily generalize to all the other cases that the spec would need to cover without getting into infinite loops.
Just set the table cell to: position:relative and the div to:
position:absolute;
top:0;
left:0;
width:100%;
height:100%;
Edit 2017:
DEMO BELOW:
Note how you cannot see the red td because the yellow div covers it entirely...
#expandingDiv {
position: absolute;
height: 100%;
width: 100%;
top: 0;
left: 0;
background: yellow;
}
<table style="width: 120px">
<tr>
<td style="background: blue">blue td</td>
<td style="background: green">green td</td>
</tr>
<tr>
<td style="background: red; position: relative">
<div id='expandingDiv'> yellow div </div>
</td>
<td style="background: orange">
Some longer text which makes the bottom two tds expand dynamically.
</td>
</tr>
</table>
Although I liked Craig's answer and will not use the approach in this answer myself, I did get quite far with this jsFiddle.
It relies on a hack, however: Setting height: 1px on the table. It works in Chrome, FF, IE11 and Edge (all that I tested), but Chrome starts misbehaving in edge cases. See the fiddle. Here are the interesting bits:
table {
width: 100%;
/* Whý does this make it work? */
height: 1px;
}
td {
border: 10px solid blue;
height: 100%;
}
#container {
width: calc(100% - 20px);
height: calc(100% - 20px);
border: 10px solid black;
}
Too much of a hack-smell to me.
have you tried changing css to:
#centerCell{
border: 1px solid black;
height:100%;
}
seems to work for me on edge, firefox and chrome
Simply set the line height of the div; as long as its display is still a block level element. There is no need for relative or absolute positioning or hard coding of the height at the div level or any of its parents. Works in IE 8+, Firefox, and Chrome.
Example:
line-height: 50px;
// or
line-height: 2em;
Here's a jsfiddle: https://jsfiddle.net/55cc077/pvu5cmta/
CSS height: 100% only works if the element's parent has an explicitly defined height. This jQuery sets the table cell height in the first column.
<script type="text/javascript">
$(function(){
$('.myTable2 tr').each(function(){
var H1 = $(this).height(); // Get the row height
$(this).find('td:first').css({'height': H1 + 'px', 'line-height': H1 + 'px'}); //Set td height to row height
});
});
</script>
I have an indeterminate number of table-cell elements inside a table container.
<div style="display:table;">
<div style="display:table-cell;"></div>
<div style="display:table-cell;"></div>
</div>
Is there a pure CSS way to get the table-cells to be equal width even if they have differently sized content within them?
Having a max-width would entail knowing how many cells you have I think?
Here is a working fiddle with indeterminate number of cells: http://jsfiddle.net/r9yrM/1/
You can fix a width to each parent div (the table), otherwise it'll be 100% as usual.
The trick is to use table-layout: fixed; and some width on each cell to trigger it, here 2%. That will trigger the other table algorightm, the one where browsers try very hard to respect the dimensions indicated.
Please test with Chrome (and IE8- if needed). It's OK with a recent Safari but I can't remember the compatibility of this trick with them.
CSS (relevant instructions):
div {
display: table;
width: 250px;
table-layout: fixed;
}
div > div {
display: table-cell;
width: 2%; /* or 100% according to OP comment. See edit about Safari 6 below */
}
EDIT (2013): Beware of Safari 6 on OS X, it has table-layout: fixed; wrong (or maybe just different, very different from other browsers. I didn't proof-read CSS2.1 REC table layout ;) ). Be prepared to different results.
HTML
<div class="table">
<div class="table_cell">Cell-1</div>
<div class="table_cell">Cell-2 Cell-2 Cell-2 Cell-2Cell-2 Cell-2</div>
<div class="table_cell">Cell-3Cell-3 Cell-3Cell-3 Cell-3Cell-3</div>
<div class="table_cell">Cell-4Cell-4Cell-4 Cell-4Cell-4Cell-4 Cell-4Cell-4Cell-4Cell-4</div>
</div>
CSS
.table{
display:table;
width:100%;
table-layout:fixed;
}
.table_cell{
display:table-cell;
width:100px;
border:solid black 1px;
}
DEMO.
Just using max-width: 0 in the display: table-cell element worked for me:
.table {
display: table;
width: 100%;
}
.table-cell {
display: table-cell;
max-width: 0px;
border: 1px solid gray;
}
<div class="table">
<div class="table-cell">short</div>
<div class="table-cell">loooooong</div>
<div class="table-cell">Veeeeeeery loooooong</div>
</div>
Replace
<div style="display:table;">
<div style="display:table-cell;"></div>
<div style="display:table-cell;"></div>
</div>
with
<table>
<tr><td>content cell1</td></tr>
<tr><td>content cell1</td></tr>
</table>
Look at all the issues surrounding trying to make divs perform like tables. They had to add table-xxx to mimic table layouts
Tables are supported and work very well in all browsers. Why ditch them? the fact that they had to mimic them is proof they did their job and well.
In my opinion use the best tool for the job and if you want tabulated data or something that resembles tabulated data tables just work.
Very Late reply I know but worth voicing.
this will work for everyone
<table border="your val" cellspacing="your val" cellpadding="your val" role="grid" style="width=100%; table-layout=fixed">
<!-- set the table td element roll attr to gridcell -->
<tr>
<td roll="gridcell"></td>
</tr>
</table>
This will also work for table data created by iteration
This can be done by setting table-cell style to width: auto, and content empty. The columns are now equal-wide, but holding no content.
To insert content to the cell, add an div with css:
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
You also need to add position: relative to the cells.
Now you can put the actual content into the div talked above.
https://jsfiddle.net/vensdvvb/
Here you go:
http://jsfiddle.net/damsarabi/gwAdA/
You cannot use width: 100px, because the display is table-cell. You can however use Max-width: 100px. then your box will never get bigger than 100px. but you need to add overflow:hidden to make sure the contect don't bleed to other cells. you can also add white-space: nowrap if you wish to keep the height from increasing.
I am trying to get the following code to work without the 670px hardcoded into the app:
<tr>
<td height="100%">
<div id="navigation" class="navigation">
<jsp:include page="menu.jsp" flush="true"/>
</div>
</td>
<td>
<div style="height:670px; overflow: auto; width:100%;">
<jsp:include page='dynamicContent.jsp' flush="true"/>
</div>
<div>
<center><jsp:include page="footer.jsp" flush="true" /></center>
</div>
</td>
</tr>
It renders fine in IE7 before a window resize - the content pane scrolls with the footer at a fixed height above the page bottom.
However, this stops working (for obvious reasons) when I make the window smaller as I have the HTML of the page set to use overflow:hidden.
Unfortunately, using "height:75%" doesn't seem to be compatible with overflow in IE7.
Does anyone have any idea how I might fake this for IE7 (it needs to be compatible with IE7 cause of project requirements)? Unfortunately this code is pretty embedded so using CSS positioning instead of a table is also probably more work than we will be able to handle before our next release.
Get rid of the overlow: auto, the overlow: hidden, and the fixed height. Instead give your footer a fixed position and add a bottom margin to the body the height of the footer.
body
{
margin-bottom: 100px;
}
.footer
{
position: fixed;
bottom: 0;
height: 90px;
padding-top: 10px;
background-color: #fff;
}
Make sure to set a background for the footer, or else the page content can show through.
Here's a working live example: http://jsfiddle.net/ADpMs/