Using calc() with tables - css

I'm trying to get a table with fixed-width tds and variable-width tds.
Im using the CSS calc() function, but somehow it seems like I can't use % in tables.
So that is what I have so far:
<table border="0" style="width:100%;border-collapse:collapse;">
<tr style="width:100%">
<td style="width:30px;">1</td> <!--Fixed width-->
<td style="width: calc( (100% - 230px) / 100 * 40);">Title</td> <!--Width should be 40% of the remaining space-->
<td style="width: calc( (100% - 230px) / 100 * 40);">Interpret</td> <!--Width should be 40% of the remaining space-->
<td style="width: calc( (100% - 230px) / 100 * 20);">Album</td> <!--Width should be 20% of the remaining space-->
<td style="width:80px;">Year</td><!--Fixed width-->
<td style="width:180px;">YouTube</td><!--Fixed width-->
</tr>
</table>
How I see it, it should work, but it isn't.
Does anybody know how to solve this? Or maybe has an other suggestion how I could reach my goal?

Tables have difficult rules about distributing the space of the columns because they distribute space dependent on the content of the cells by default. Calc (atm) just wont work with that.
What you can do however is to set the table-layout attribute for the table to force the child td elements to get the exact width you declared. For this to work you also need a width (100% works) on the table.
table{
table-layout:fixed; /* this keeps your columns with at the defined width */
width: 100%; /* a width must be specified */
display: table; /* required for table-layout to be used
(since this is the default value it is normally not necessary;
just included for completeness) */
}
and then use plain percentages on the remaining columns.
td.title, td.interpret{
width:40%;
}
td.album{
width:20%;
}
After using up the space for the fixed width columns, the remaining space is distributed between the columns with relative width.
For this to work you need the default display type display: table (as opposed to say, display: block). This however means you can no longer have a height (including min-height and max-height) for the table.
See your modified Example.

Calc is the general function.
-webkit-calc is for webkit.
Add those in according to the browser you're using.
Regardless, your -calc- function will be ignored. having 3 td's that will be 40% of the remaining width? Thats 120% in total. This is a table. The parent's width will always take precedence.
However, if you have the TD's in in 5%, it the total width will be smaller than that of the table, hence it will also be ignored.
Bottom line: don't use calc with table.

Related

Table with some columns in percent, the rest fluid

I have a table, where two columns will receive 30% of the space each:
<td style="width: 30%;">
The remaining columns should just equally share the remaining space. How do I accomplish this? Do I just give the remaining columns no widthat all?
Yes, declaring no width would work (see snippet below).
<td> automatically adjusts width evenly unless otherwise declared (e.g. <td style="width: 30%;"></td>)
EDIT
When you put data in the fluid cells, they will adapt to the size of the data inside them. To keep them the same width as each other and wrap the text, you will need to declare a width percentage for the fluid cells.
Since we're already using 60% with the first two cells, we have 40% left. We will need to divide 40 by the number of extra cells to get the percentage value for their width.
Thanks to #Chiller for pointing this out!
table {
height: 500px;
width: 100%;
}
td {
background: red;
/* Edit - divide number of fluid cells by 40
(because we're using 60% with the first two)
in this example the number is just over 13) */
width: 13%; /* the number we calculated */
}
<table>
<tr>
<td style="width: 30%;"></td>
<td style="width: 30%;"></td>
<td></td>
<td></td>
<td></td>
</tr>
</table>

What happens when CSS children percentage of width is more than 100%

I have a table that fills dynamically with columns based on the dataset it receives. Each column gets a width of 15%. Sometimes there are 10 columns which is technically over 100%. What is the expected outcome?
Background: I am trying to add excel like column resizing and when I resize one column the other columns shrink and seem like they are trying to compensate. I don't want them to, I also don't want them static. So, I'm just curious if having % widths is causing the bugs.
Note: please do not recommend any plugin's. Just curious about the CSS.
Depends on the user agent. The spec states that user agents may choose to reflow the layout but does not define exactly how it must be done. Some of them will just automatically divide 100% by the number of cols and reflow them. Some browsers will arbitrarily narrow one or more of the colums to fit. Some will just keep them at the defined width and push excess to the next row. Basically, there is no guarantee of the behavior, so I would not even set width implicitly if you dont know the number of columns/items in advance.
You could just populate them all, then use a bit of JS to divide 100% by the number of cols and use that value to update the CSS on the fly to reflow.
If the columns are displayed as block elements, they wrap onto a new line (in firefox):
.container {
width: 100%;
}
.item {
background: red;
width: 75%;
}
<div class="container">
<div class="item">abc</div>
<div class="item">abc</div>
</div>
However, if you're using actual tables (or display: table), they behave differently:
.container {
width: 100%;
}
.item {
background: red;
width: 75%;
}
<table class="container">
<tr>
<td class="item">abc</td>
<td class="item">abc</td>
</tr>
</table>
I'm not an expert on table behavior, feel free to edit this answer or create a new answer based on this one.

td element is wider than its max-width property [duplicate]

<table>
<tr>
<td>Test</td>
<td>A long string blah blah blah</td>
</tr>
</table>
<style>
td{max-width:67%;}
</style>
The above does not work. How can I set the max-width of a table cell using percentages?
Old question I know, but this is now possible using the css property table-layout: fixed on the table tag. Answer below from this question CSS percentage width and text-overflow in a table cell
This is easily done by using table-layout: fixed, but a little tricky because not many people know about this CSS property.
table {
width: 100%;
table-layout: fixed;
}
See it in action at the updated fiddle here: http://jsfiddle.net/Fm5bM/4/
According to the definition of max-width in the CSS 2.1 spec, “the effect of 'min-width' and 'max-width' on tables, inline tables, table cells, table columns, and column groups is undefined.” So you cannot directly set max-width on a td element.
If you just want the second column to take up at most 67%, then you can set the width (which is in effect minimum width, for table cells) to 33%, e.g. in the example case
td:first-child { width: 33% ;}
Setting that for both columns won’t work that well, since it tends to make browsers give the columns equal width.
I know this is literally a year later, but I figured I'd share. I was trying to do the same thing and came across this solution that worked for me. We set a max width for the entire table, then worked with the cell sizes for the desired effect.
Put the table in its own div, then set the width, min-width, and/or max-width of the div as desired for the entire table. Then, you can work and set width and min-widths for other cells, and max width for the div effectively working around and backwards to achieve the max width we wanted.
#tablediv {
width:90%;
min-width:800px
max-width:1500px;
}
.tdleft {
width:20%;
min-width:200px;
}
<div id="tablediv">
<table width="100%" border="1">
<tr>
<td class="tdleft">Test</td>
<td>A long string blah blah blah</td>
</tr>
</table>
</div>
Admittedly, this does not give you a "max" width of a cell per se, but it does allow some control that might work in-lieu of such an option. Not sure if it will work for your needs. I know it worked for our situation where we want the navigation side in the page to scale up and down to a point but for all the wide screens these days.
the percent should be relative to an absolute size,
try this :
table {
width:200px;
}
td {
width:65%;
border:1px solid black;
}
<table>
<tr>
<td>Testasdas 3123 1 dasd as da</td>
<td>A long string blah blah blah</td>
</tr>
</table>

Complex table, different cells' widths requirements

It's not easy explaining the need here, but here is the playground for the problem.
Playground
Requirements:
First cell has FIXED width
Middle cell width takes the rest of the space
Last cell's width depends on it's children's width
The Question:
How can the middle cell take the rest of the row's space, without being "taken over" by it's child's greater width?
this is a simplified version of my problem, using real tables instead of CSS tables)
Without specific markup, it's hard to propose an exact solution, but here are some things to consider.
The left-most fixed-width cell is easily handled by setting its width. e.g. width: 100px. (This cell isn't really relevant to the problem; in a sense it can be ignored.)
If I'm interpreting correctly, you want to prevent the right-most cell from wrapping. That's easy or hard, depending on the content. For pure text, it can be achieved with white-space: nowrap. If the content isn't strictly text, perhaps you can coerce it into acting like text, e.g. display: inline.
For the middle cell, you don't specify what you want to happen to the excess content. Hide it? Add a horizontal scroll bar? You also don't indicate what this content is. But most likely you'll want to set the overflow-x property to some suitable value.
Solution playground
HTML
<table>
<tr>
<td></td>
<td>
<div>
<div></div>
</div>
</td>
<td>
<b></b>
<b></b>
<b></b>
</td>
</tr>
</table>
CSS
table{ width:100%; }
/*
This is the trick. There is a wrapping DIV with a position:relative which
holds the actual content DIV which is positioned Absolute, so it's width won't
affect it's own cell width's
*/
td > div{ position:relative; width:100%; height:20px; }
div div{
position:absolute;
background:green; height:100%; width:800px;
}
/* First TD has FIXED width */
td:nth-child(1){ width:100px; background:#EEE; }
/* Middle TD width takes the rest of the space */
td:nth-child(2){ overflow:hidden; }
/* Last TD has width depends on it's children's width */
td:nth-child(3){ white-space:nowrap; width:1%; }

How to create a table with 100% width, with dynamic width for the 1st column, and wrapped text in the 2nd column?

I'm trying to format the debug log of an app as an HTML table. I have two columns: one for time stamps, and one for the text of log entries. The text can easily contain long character sequences. Example:
<table>
<tr>
<td class="ts">12:50:01.683</td>
<td class="txt">[1]: NDIS-WDM_Driver_for_HighSpeed_USB-Ethernet_Adapter_(Microsoft's_Packet_Scheduler)_:\Device\NPF_{7D9F4819-8B81-49FA-B321-5F1ACBD6740D}</td>
</tr>
<tr>
<td class="ts">12:50:01.683</td>
<td class="txt">[2]: Realtek_10/100/1000_Ethernet_NIC_________________________________(Microsoft's_Packet_Scheduler)_:\Device\NPF_{90EF96D0-AC16-41E5-AFFD-1B25D439A0D9}</td>
</tr>
<tr>
<td class="ts">12:50:01.683</td>
<td class="txt">[3]: Realtek_10/100/1000_Ethernet_NIC_________________________________(Microsoft's_Packet_Scheduler)_:\Device\NPF_{D3FA28DC-C59B-4027-AC43-6480B775ACD9}</td>
</tr>
</table>
I would like the table to always use 100% browser width. The width of the time stamp column should adapt to its content, and the text of the second column should wrap automatically. The CSS I tried:
table {
width: 100%;
border-collapse: collapse;
table-layout: fixed;
}
td {
border: solid 1px #000;
}
.ts {
width: 100px;
}
.txt {
word-wrap: break-word;
}
In Chrome 26, without table-layout: fixed;, the table is wider than the browser, and a horizontal scroll bar appears. Since this setting makes the width of my columns equal, I had to set the width of the time stamp column to a predefined value: width: 100px;.
The problem is, if the user changes the zoom factor by Ctrl + Mouse Wheel, timestamps can easily become wider than their column, which looks ugly. Is it possible to make the width of the timestamp column follow the width of its content? (I could make it unbreakable with white-space: pre;.) Or, is there another approach which is not based on table-layout: fixed;?
Since 1em is equal to the current font size, it's better to set the width of the time stamp column in em units instead of px. This way the width of the column will be proportional to its content, which solves the zooming problem.
This solution is sub-optimal because the actual width value will depend on the font-family. For example for Times New Roman, the width of the time stamp column can be set to 6em, but a wider font like Courier New requires 8em.

Resources