I feel like I'm missing something. I have a <table> set to width: 100%; and I add CSS to prevent a column from becoming narrower than 50px. It is a simple scenario.
My problem is that the column which has min-width applied gets wider even when if it is already wider than the min-width value.
Example of problem: I apply min-width: 50px; to a td element which has a width of 123px, the td increases to a width of 167px. I expected applying min-width: 50px; to an element with a rendered width of 123px to not change the elements width.
My problem can be reproduced by running the below code and following these steps:
Check the width of the first column of the table
Verify that the column has a width greater than 50px
If the first column has a width less than 50px, increase the width of your browser window.
When the first column has a display width greater than 50px, click the button below the table.
The width of the first column should increase, despite not being smaller than the min-width value.
NOTE: Clicking the button will toggle a class applied to the table cells (th and td elements) which form the first column of the table. The class applies min-width: 50px;.
This problem will be considered solved by any solution that does not affect the calculated width of a table cell (th or td) with a calculated width greater than 50px and style property width: auto; when setting min-width: 50px.
I am using Google Chrome Version 46.0.2490.80 m.
Any help/insight would be greatly appreciated. Thank you.
$("button").click(function() {
$("table tr > *:nth-child(1)").toggleClass("min-width-test")
});
table {
width: 100%;
}
table,
table * {
border: 1px solid black;
}
.min-width-test {
min-width: 50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<th>First</th>
<th>Second</th>
<th>Third</th>
<th>Fourth</th>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>A</td>
<td>B</td>
<td>C</td>
<td>D</td>
</tr>
</table>
<button>Toggle min-width on first column</button>
CSS has no specification for how min-width and max-width are handled by tables, inline tables, table cells, etc. The behavior you are seeing is how Chrome somewhat arbitrarily handles it.
In CSS 2.1, the effect of 'min-width' and 'max-width' on tables, inline tables, table cells, table columns, and column groups is undefined.
CSS 2.1
This hasn't been changed in any later specs.
As Matt mentioned in the comments, adding min-width is going to increase the size of the column. Tables auto-adjust their size based on their content, and adding a min-width of 50 will thus increase it by 50.
I've copied over your code and made it so you can visualize what's happening. Adding a min-width of 50px is like adding an invisible element of width 50 in there (which I've conveniently made un-invisible and colored red). If you want to counteract that, try removing some margins or padding (although this may break your design--can't tell without seeing exactly what you're doing). Press the "Toggle fix on first column" button to see what I mean.
$("button").click(function() {
$("table tr > *:nth-child(1)").toggleClass("min-width-test")
});
$("#b2").click(function() {
$("table tr > *:nth-child(1)").toggleClass("min-width-test-fixed")
});
table {
width: 100%;
}
table,
table * {
border: 1px solid black;
}
.min-width-test:after {
content: '';
width: 50px;
height: 1px;
background: red;
display: block;
}
.min-width-test-fixed:after {
content: '';
width: 50px;
margin-right: -50px;
height: 1px;
background: green;
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<th>First</th>
<th>Second</th>
<th>Third</th>
<th>Fourth</th>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>A</td>
<td>B</td>
<td>C</td>
<td>D</td>
</tr>
</table>
<button>Toggle min-width on first column</button>
<button id="b2">Toggle fix on first column</button>
Related
When I increase the table height, all the rows get resized and the additional height is distributed equally. among them.
Question
Is it possible to make a row (in my example the one with headers) always stay at it's minimum height? As an analogy I see it as specifying flex-grow: 0 on a Flex item.
No fixed height
I don't want to make that row fixed height (e.g. set on it height: <fixed value in px>), just make it's height the natural minimum to render all the contents.
Code
FIDDLE with the example code to work on. Screenshot below.
I want to make the first row in the right table (.Table-Row--NotResizable) to be the same height as the first row in the left table.
HTML
<div class="TableDisplay">
<table class="Table Table--Natural">
<tr>
<th>Artist</th>
<th>Song</th>
</tr>
<tr>
<td>Prince</td>
<td>Kiss</td>
</tr>
<tr>
<td>Bob Dylan</td>
<td>Idiot Wind</td>
</tr>
</table>
<table class="Table Table--Full">
<tr class="Table-Row--NotResizable">
<th>Artist</th>
<th>Song</th>
</tr>
<tr>
<td>Prince</td>
<td>Kiss</td>
</tr>
<tr>
<td>Bob Dylan</td>
<td>Idiot Wind</td>
</tr>
</table>
</div>
CSS
html,
body {
height: 100%;
min-height: 100%;
}
.TableDisplay {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
height: 100%;
}
.Table {
height: 100%;
border-collapse: collapse;
}
.Table td,
.Table th {
border: 1px solid black;
}
.Table--Full {
height: 100%;
}
.Table--Natural {
height: auto;
}
/* Make this row do not participate in height changes */
.Table-Row--NotResizable {
/* ??? */
}
In fact fixed value in px is exactly what you should use:
.Table-Row--NotResizable {
height: 1px;
}
If you set it to 1px then the browser will resize it to exactly the size needed to fit the content. Table content has to fit into table cell, so the height will not be smaller, and as any (non-empty) content will be higher than 1px it will also not be greater than minimum needed.
I've been scratching my head at this for ages but I finally found a solution that works for me which slightly differs from the current answer.
In order to prevent each <Tr> from resizing to match the <Table> height, I set the height of each of my <Tr> to 1px, however, to stop these rows from resizing, I had to add an empty final <Tr> that does not contain any data to the end of my <Table>. It seems this behaviour is because the <Table> element by default needs the <Tr> elements to sum up to the total height of the table, and the empty <Tr> element stretches to fill this height whilst the rows containing data can be sized to their content.
I have a table with a fixed number of columns. I would like 3 of the columns to have the same width, but I don't know what it is, as I don't know the width of the other 2. I want the browser to render it as best it can with the one constraint that my three designated columns all have the same width,
Here's an example. I would like columns 2,3,4 all to have the same width, I don't mind what it is, just that they are the same.
<table>
<tr>
<td>Could be short or maybe it could be long</td>
<td class="samewidth">Col2 Long Text</td>
<td class="samewidth">Col3 Some More Long Text</td>
<td class="samewidth">Col4 Some More Long Text and a bit more on top</td>
<td>Could be short or long</td>
<tr>
</table>
I can only do something like I want by having a fixed percentage
td.samewidth {
width: 25%;
overflow: hidden;
}
Here's a fiddle with the best I could do which ties the three columns to have a width of 25%.
https://jsfiddle.net/GrimRob/zugnyzb4/
What I ideally want to do is get rid of width: 25% and put something in its place, but what?
Do it like this:
td.samewidth {
width: 33%;
overflow: hidden;
}
<table>
<tr>
<td>Could be short or maybe it could be long</td>
<td>
<table>
<tr>
<td class="samewidth">Col2 Long Text</td>
<td class="samewidth">Col3 Some More Long Text</td>
<td class="samewidth">Col4 Some More Long Text and a bit more on top</td>
</tr>
</table>
</td>
<td>Could be short or long</td>
</tr>
</table>
Since your "samewidh" columns will be 33% fixed, you won't have trouble with other rows misaligning. At most you'll have to add !important.
Hard to arrive at a set answer for your question, since I am not exactly sure how you want the columns to resize based on content. Flexbox could be an alternative for you. Here is the CSS and a Codepen illustrating, to as best I understood, what you are trying to accomplish.
table {
width: 100%;
border: 1px solid black;
}
tr {
display: flex;
}
td {
border: 1px solid black;
}
td.samewidth {
/* width: 25%; */
overflow: hidden;
flex-grow: 1;
display: inline-block;
flex-basis: 0;
}
td:not(.samewidth) {
flex-basis: content;
}
http://codepen.io/anon/pen/bpobGq
In this example, columns 1 and 5 (not samewidth) determine width based off of the content provided. Columns with the .samewidth class, will grow evenly to fill up the remaining space available in the parent container (in this case the tr).
You really have a lot of options here with how you'd want the columns to resize. You could set a fixed width for columns 1 and 5, size off of content (as in example), or have those grow to fill up space as well. Hopefully this gets you on the right path.
Here's a quick guide on Flexbox. https://css-tricks.com/snippets/css/a-guide-to-flexbox/
The page consists of two tables (golf scores). The first, which is always wider than the second, includes two columns of names and therefore its total width will vary from league to league. The second table only contains numbers and its width will be constant.
I want to align the left edge of the two tables while keeping the first table centered.
If I knew the width of the first table then the issue would be simple, use css to set the html width to that of the table and set the two table left margins to 0. But with the width being fluid the tables move with different content.
How do I solve this dilemma?
Here is a fairly easy and robust way of solving this problem.
First, create a wrapper elements to contain the two tables, .wrap in my example.
On .wrap, set display: table and margin: 0 auto. This will force .wrap to take a shrink-to-fit width, and then the margin trick will center the block.
Your two child tables will then be aligned to the left by default.
.wrap {
display: table;
border: 1px dashed blue;
margin: 0 auto;
}
table {
border: 1px dotted blue;
margin: 20px;
}
table td {
border: 1px solid gray;
}
<div class="wrap">
<table>
<tr>
<td>First Wide Column With Long Names</td>
<td>Second Wide Column with Very Long Names</td>
</tr>
</table>
<table>
<tr>
<td>First Short Column</td>
<td>Second Short Column</td>
</tr>
</table>
</div>
You can also see jsfiddle at: http://jsfiddle.net/audetwebdesign/qt5ffzuo/
One way to do this is to add a wrapper around the tables that has display: inline-block. This will make the wrapper shrink to fit around the largest table. It will also allow you to center it horizontally by setting the parent (for example the body) to text-align: center.
To make sure the text in the tables is not also centered, you'll have to set text-align: left to the wrapper contents.
body {
text-align: center;
}
.wrapper {
display: inline-block;
border: 1px solid red;
text-align: left;
}
table, tr, td {
border: 1px solid blue;
}
<div class="wrapper">
<table>
<tr><th>Name</th><th>Score</th></tr>
<tr>
<td>Johnny</td>
<td>12</td>
</tr>
<tr>
<td>Jimmy</td>
<td>12.412.002</td>
</tr>
</table>
<table>
<tr>
<td>6</td>
<td>3</td>
</tr>
<tr>
<td>5</td>
<td>4</td>
</tr>
</table>
</div>
Given a <table> with one or many <td>'s with text that is wider than the parent <div>, is there a way to make the table scroll without making the parent <div> use overflow:auto, and still have the table retain 100% width?
I'm hoping for a CSS solution I can apply to ONLY the <table> element (or its children).
Example: See JSFiddle Demo.
CSS:
<style>
#wrapper {
width: 250px;
/* looking for solution that doesn't use overflow auto here */
}
table {
border-collapse: collapse;
}
td {
border:1px solid #ccc;
padding: 3px;
}
</style>
HTML:
<div id="wrapper">
<p>Table should scroll, but not this text.</p>
<table>
<thead>
<tr>
<td>A</td>
<td>B</td>
<td>C</td>
</tr>
</thead>
<tbody>
<tr>
<td>..</td>
<td>..</td>
<td>....................................................................................</td>
</tr>
<tr>
<td>..</td>
<td>..</td>
<td>..</td>
</tr>
</tbody>
</table>
</div>
Not modifying the parent div is important in my project because <table>'s are in a <div> with a bunch of other content that I do not want to scroll with it. While I could add a wrapper <div> to all tables in my project, I would also have to rewrite a JavaScript plugin (has to do with paging), which I am trying to avoid.
You can use overflow: scroll on the table itself if you make it display as block:
table {
display: block;
overflow: scroll;
}
Edit:
As the comments below suggest, use td { width: 1%; } as a somewhat-messy way to get the table to still be 100% width if the content is narrower than the wrapper.
Fiddle: http://jsfiddle.net/94g53edb/12/
I am just a newbie in css and html, but if I can give my opinion, so there will be two ways in achieving that:
You can set the <p> to the fixed position,
or
You can create another wrapper for the table.
:)
[I'm adding a second answer because the comments on my first answer are going in a different direction than my new answer, and I don't want to derail that train]
Set the table to display: block and overflow: scroll, and give each of the cells a min-width (in pixels) to make up 100% of the container's width.
Here's what it looks like with table content less than the container width: http://jsfiddle.net/94g53edb/8/
Because the cells have only a min-width and not a fixed width, they can expand as needed, pushing the table to greater than the width of the container, and the table will scroll: http://jsfiddle.net/94g53edb/9/
I am looking for a way to specify a table's width by specifying widths of its TDs.
In the following scenario (try it live on jsfiddle) you can see that I have specified width of each TD as 100px and I expected to get a 300px table (and a horizontal scrollbar for div) but in practice browsers give them a width of 63px (that's table's width divided by 3)
Is there any way to make TDs determine the width of table and not other way round? So far I have tried different values of table-layout, display, overflow for TD and TABLE without any success.
The html:
<div>
200px
<table>
<tr>
<td>100px</td>
<td>100px</td>
<td>100px</td>
</tr>
</table>
</div>
and a minimal CSS:
div {
width: 200px;
height: 300px;
border: solid 1px red;
overflow-x: scroll;
}
td {
width:100px;
border: solid 1px #000;
}
table {
border-collapse: collapse;
}
A simple solution is make the td's content be 100px wide.
<div>
200px
<table>
<tr>
<td><div class="content">100px</div></td>
<td><div class="content">100px</div></td>
<td><div class="content">100px</div></td>
</tr>
</table>
</div>
.content {
width: 100px;
}
Simplest solution appears to be setting min-width instead of width for TDs.
If you're dynamically generating the table, you could just dynamically set the width of the table while you're at it. Just calculate the desired width, and add style="width:300px;" (or whatever) to the <table> tag.
Not that the other options people have posted here aren't also perfectly valid, of course.