I am trying to get a horizontal line to stretch between the first and last columns in a table but I need the first and last columns to wrap if the text is long. The only way I have found to get the desired effect is to use width:100%; on the middle column, and white-space:nowrap; on the first and last, but I need to find another way as I need the text to wrap when there isn't enough space. Is there a way to achieve this effect in plain CSS?
https://jsfiddle.net/macu/8axk5qv5/4/
table {
width: 100%;
}
td {
vertical-align: middle;
white-space: nowrap;
}
td:nth-child(2) {
width: 100%;
}
.line {
border-top: thin solid blue;
}
<table>
<tr>
<td>Title cell with a long title that should wrap</td>
<td><div class="line"></div></td>
<td>Another cell, should wrap</td>
</tr>
</table>
If the text is long enough there should be no line, and the text should wrap normally:
You can put a span or div in each cell, and make them to use white background, then set the line on the table row to create such layout visually.
Check out the fiddle demos below, so you can easily resize and see the wrapping text.
jsFiddle
.table {
width: 100%;
border-collapse: collapse;
}
.table tr {
background: linear-gradient(blue, blue) center/99.99% 1px no-repeat;
}
.table div {
background: white;
display: inline-block;
}
.middle div {
min-width: 100px; /*remove or adjust value as need*/
}
.last {
text-align: right;
}
<table class="table">
<tr>
<td class="first">
<div>Title cell with a long title that should wrap</div>
</td>
<td class="middle">
<div><!-- This td can be removed if no min-width needed --></div>
</td>
<td class="last">
<div>Another cell, should wrap</div>
</td>
</tr>
</table>
But using flexbox can make it much easier, if you don't have to use table.
jsFiddle
.container {
display: flex;
}
.line {
background: linear-gradient(blue, blue) center/1px 1px repeat-x;
flex: 1;
min-width: 100px; /*remove or adjust value as need*/
}
<div class="container">
<div>Title cell with a long title that should wrap</div>
<div class="line"></div>
<div>Another cell, should wrap</div>
</div>
try by removing the white-space: nowrap; on the TD tag, then target the first and the third TD with
td {
vertical-align: middle;
//white-space: nowrap;
}
td:nth-child(1),td:nth-child(3) {
//add whatever min-width AND max-width so it could be something like this
min-width:150px;
max-width:300px;
}
see if that helps.
Related
What's the default css of a td which makes it so that stuff are automatically centered vertically?
I know how to get things to center horizontally given that a div is smaller than its parent with margin: 0 auto but what's allowing a td to center vertically automatically?
#outer {
width: 200px;
height: 200px;
background-color: yellow;
}
#inner {
width: 60%;
margin: auto;
background-color: red;
}
<div id="outer">
<div id="inner">
centered only horizontally
</div>
</div>
<table height=200 border=1>
<tr>
<td>
I center automatically
</td>
</tr>
</table>
The default css of td elements is display: table-cell. This property, will also accept vertical-align.
So, you might need to set the css:
td {
vertical-align: middle;
}
.outer {
display: table-cell;
vertical-align: middle;
width: 400px;
height: 200px;
border: 1px solid black;
}
.inner {
width: 60%;
margin: 0 auto;
background-color: yellow;
text-align: center;
}
<table height="200" border="1">
<tr>
<td>I am vertically centered</td>
</tr>
</table>
<div class="outer">
<div class="inner">
This is vertically centered
</div>
</div>
vertical-align: inherited;
for TD & TR in user agent stylesheet i.e default browser stylesheet. So TD is referring vertical-align of TBODY which is as below and thats causing it to align vertically in middle.
vertical-align: middle;
To override, default stylesheet you can do something like
td{
vertical-align: top !important ;
}
#outer{display:table-cell;}
#inner{vertical-align:middle;}
Demo: http://jsfiddle.net/zvmcyp4w/
.wide {
width: 400px;
background: lightblue;
}
.narrow {
width: 200px;
background: lightpink;
}
.table-responsive {
max-width: 100%;
overflow-x: auto;
}
table {
border: 1px solid black;
border-collapse: collapse;
}
td {
border: 1px solid black;
padding: 5px;
}
<div class="wide">
<div class="table-responsive">
<table>
<tr>
<td>Many words</>
<td>word</td>
<td>oneword</td>
<td>onemoreword</td>
</tr>
</table>
</div>
</div>
<div class="narrow">
<div class="table-responsive">
<table>
<tr>
<td>Many words</>
<td>word</td>
<td>oneword</td>
<td>onemoreword</td>
</tr>
</table>
</div>
</div>
I'm simulating a responsive layout with "wide" and "narrow" containing the same table.
In "narrow" you can scroll left and right.
If the content of a cell is made out of multiple words, like the first cell, it automatically breaks into lines.
What I'm looking for is to avoid breaking the line and have the cell expand horizontally to accommodate its content, given that the content is dynamic therefore no fixed widths or min-widths allowed.
Ideally a clean CSS only solution would be great, I already know how to solve it with JavaScript.
So you want multiple words not to expand on multiple rows? You can use white-space property
.narrow table td{
white-space:nowrap
}
jsfiddle
Add white-space: pre to the table cells:
td {
border: 1px solid black;
padding: 5px;
white-space: pre;
}
Updated Fiddle.
You could adjust the td styles to include white-space: nowrap;
td {
border: 1px solid black;
padding: 5px;
white-space: nowrap;
}
Also, a couple of your td elements had malformed closing tags.
http://jsfiddle.net/zvmcyp4w/2/
How can I align vertical text, that is generated by two spans, inside a div inside a table cell. I've tried many combinations of text-align,display but nothing worked. I have this html segment
<table>
<tr>
<td>
<div class="container">
<span>This is span-sentence-1</span>
<span>This is span-sentence-2</span>
</div>
</td>
</tr>
</table>
and the output is
This is span-sentence-1 This is span-sentence-2
while I want to be rendered like this
This is span-sentence-1
This is span-sentence-2
fiddle:http://jsfiddle.net/hjuxdd1b/1/
You can use following:
.container {
width: 100%;
line-height: 50px;
border: 1px solid black;
/*height: 50px; Remove height*/
}
.container span{
display: block;/*Set display to block*/
}
fiddle
Give display: block to .container span
.container span {display: block;}
Remove the height and line-height in the .container
Fiddle: http://jsfiddle.net/praveenscience/hjuxdd1b/7/
Add br tag after the first span or replace span with div.
You may not need that div:
Set those spans to display: block so they are each given their own line.
Give vertical-align: middle to the td so that its content will stay vertically centred.
Have a fiddle
By default a span is display: inline so they will line up next to each other. You could read more about the span element over on the MDN.
CSS
td {
vertical-align: middle;
height: 100px;
border: 1px solid black;
}
td span {
display: block;
}
HTML
<table>
<tr>
<td>
<span>This is span-sentence-1</span>
<span>This is span-sentence-2</span>
</td>
</tr>
</table>
I have tried now several things (and looked around here) and nothing worked so far. So I am going to ask.
What I want:
I have the following simple HTML:
<table>
<tr>
<td class="small">First column with text</td>
<td class="extend">This column should fill the remaining space but should be truncated if the text is too long</td>
<td class="small">Small column</td>
</tr>
</table>
The table itself should be 100% width of the parent container.
I wish the first and last column (.small) to be as large as they need to be, so the content can fit into it without a line break (so pretty much what white-space: nowrap does). The middle column (.extend) should take the rest of the space (so the table will stay within 100% width of its parent container) and the text within .extend should be ellipsised before it needs to break to a seconds line.
I've prepared a fiddle for this at http://jsfiddle.net/3bumk/
With these background colors I would expect a result like:
Is there any solution for this?
What I get:
My problem is, if I can make the text to stay in one row (having no line breaks), the table will always overflow its parent container width (and cause it to be scrollable), before having the idea to ellipsis the text in the middle column.
What is no solution (I often found):
It's no solution to set the first and third column to a 'fixed' with (percentage or pixel), because the content will have different length from time to time. It is possible to add as many div or span as needed (or get rid of the table all together - what I tried first, with display and table but I didn't find a working solution that way either).
PS: It would be very nice if you could edit the fiddle to a working example, if you know one :-)
EDIT I am free to use divs instead of a table too!
Here is an answer using divs instead of a table: DEMO
HTML
<div class="container">
<div class="fnl first">First Baby</div>
<div class="fnl last">Last Guy</div>
<div class="adjust">I will adjust between both of you guys</div>
</div>
CSS
.container{
width: 300px;
}
.first{
float:left;
background: red;
}
.last{
float:right;
background: orange;
}
.adjust{
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
Something like this? http://jsfiddle.net/NhGsf/
By using: display: table; width: 100%; table-layout: fixed; position: absolute; top: 0;
And setting first and last child to fixed width the middle section will have the rest off the space
min-width in combination with width:100% seems to work in firefox and chrome:
tr {
td:first-of-type {
width: 100%;
}
td:last-of-type {
min-width: 200px;
}
}
I was facing the same challenge and I found the following solution using tables.
The HTML needs to use a DIV in the long column.
The CSS defines your small and extend classes. The hard part being the definition of the extend class.
This gives you the behavior you describe.
HTML
<table>
<tr>
<td class="small">First column with text</td>
<td class="extend">
<div class="small">This column should fill the remaining space but should be truncated if the text is too long.</div>
</td>
<td class="small">Small column</td>
</tr>
</table>
CSS
table {
margin-top: 50px;
}
table td {
white-space: nowrap;
}
table td:nth-child(1) {
background-color: red;
}
table td:nth-child(2) {
background-color: green;
}
table td:nth-child(3) {
background-color: orange;
}
.extend {
display: table;
table-layout: fixed;
width: 100%
}
.small {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
You can re-arrange the columns by moving the longest one at the end then use nested tables.
CSS
.extend
{
white-space:nowrap;
overflow:hidden;
text-overflow:ellipsis;
-o-text-overflow:ellipsis;
}
td
{
white-space:nowrap;
}
.box
{
width:1000px;
border:blue solid thick;
overflow:hidden;
}
HTML
<div class="box">
<table width="100%" border="1">
<tr>
<td class="small">First column with text</td>
<td class="small">Small column</td>
<td>
<table>
<tr>
<td class="extend" >This column should fill the remaining space but should be truncated if the text is too long. This column should fill the remaining space but should be truncated if the text is too long. This column should fill the remaining space but should be truncated if the text is too long. This column should fill the remaining space but should be truncated if the text is too long. This column should fill the remaining space but should be truncated if the text is too long.</td>
</tr>
</table>
</td>
</tr>
</table>
</div>
Except for the ellipsis it is working well. See result
See this fiddle (or, alternatively), you need to set the max-width for each table cell:
body{
width:100%;
padding:0;
margin:0;
}
table {
margin-top: 50px;
width:100%;
max-width:100%;
}
table td {
white-space: nowrap;
}
table td:nth-child(1) {
background-color:red;
max-width:100px;
}
table td:nth-child(2) {
background-color: green;
overflow:hidden;
max-width:100px;
text-overflow: ellipsis;
white-space: nowrap;
}
table td:nth-child(3) {
background-color: orange;
max-width:100px;
}
I have a fixed-width table of 400px with 3 columns.
<table>
<tbody>
<tr>
<td class="wide">This is really really long and as much as possible should show but should eventually be cut off.</td><td class="narrow">Small1</td><td class="narrow">Small2</td></tr>
</tbody>
</table>
Here is the CSS.
table
{
table-layout: fixed;
width: 400px;
}
td
{
border: 1px solid #000;
white-space: nowrap;
}
td.wide
{
overflow: hidden;
text-overflow: ellipsis;
}
td.narrow
{
}
Here is the JSFiddle.
Currently, each of the 3 columns takes up 1/3 of the space. What I want is for the 2nd and 3rd columns to be as small as possible (without anything hidden or text-wrapped) and have the 1st column take up the remainder of the space (with any text that doesn't fit being hidden).
Depending on the data displayed, the 2nd and 3rd columns may need to be wider or narrower to fit their content, so I don't want to define a fixed size for any column.
Is this possible?
Here is the only solution i found. It's pretty ugly but it does the trick :
http://jsfiddle.net/XA9kY/
The thing is to wrap the string to be overflowing into a .... table
Notice the table into the td.wide
<div style="width:400px; border: 1px solid red;">
<table>
<tbody>
<tr>
<td class="wide">
<table>
<tr>
<td>This is really really long and as much as possible should show but should eventually be cut off.
</td>
</tr>
</table>
</td>
<td class="narrow">Small1</td>
<td class="narrow">Small2</td>
</tr>
</tbody>
</table>
</div>
And here is the magic
td.wide table
{
width: 100%;
table-layout: fixed;
}
td.wide table td
{
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
Just wrapping the string into a table with table-layout: fixed; property does the trick.
Here's my try at this: (Example)
<table>
<tbody>
<tr>
<td class="wide">This is really really long and as much as possible should show but should eventually be cut off.</td>
<td class="rest">Small1</td>
<td class="rest">Small2</td>
</tr>
</tbody>
</table>
CSS
table {
width: 400px;
}
table td {
border: 1px solid #000;
}
td.rest {
width:1px;
}
The only thing is that it doesn't like:
overflow: hidden;
text-overflow: ellipsis;
If that isn't an issue then this should work.
EDIT
A possible solution to hide the text in the wider cell by just setting the height.
Added also the line-height for all the cells so you can change both based on the settings you're after.
Here the (Example)
table {
width: 400px;
}
table td {
border: 1px solid #000;
line-height:26px;
}
td.rest {
width:1px;
white-space: nowrap;
}
td.wide {
overflow:hidden;
height:26px;
display:block;
}