flex-shrink: 0 and white-space: wrap - html

I have a flexbox container with 2 columns. I want the columns to stack when there isn't room to display them both. I use the following html/css
<div class="container">
<div class="column">
<div>Short content</div>
<div>This is some longer content to show problem</div>
<div>Short contetn</div>
</div>
<div class="column">
<div>Short content</div>
<div>This is some longer content to show problem</div>
<div>Short contetn</div>
</div>
</div>
and
.container {
display: flex;
flex-wrap: wrap;
}
.column {
flex: 1 0 auto;
/* grow, don't shrink */
}
JS fiddle here: http://jsfiddle.net/AsdNS/
It seems that there is implicitally white-space: nowrap on the inner divs, but I don't want this. If I did want it surely I would specify it in my css. Is there a way to not wrap whitespace and then only wrap the columns if a single block of text with no whitespace is too big?
In practice I want to force it to wrap on some whitespace, but not others (I will use <span>s)
EDIT Here is a more real-world jsfiddle: http://jsfiddle.net/W7g3U/1/
What I want is for the long div to wrap, but the short divs not to.
EDIT 2 Here is what I want to achieve (works in chrome) http://plnkr.co/edit/Ppoe8xJrrbC16Y1vyWCD

Related

How does inline-flex container decide when text is wrapped? [duplicate]

This question already has an answer here:
Understanding how width of scrollbar is computed in nested flex container
(1 answer)
Closed last year.
I have an issue with text clipping where flex items are clipped too early even though their flex-basis is set to 0 so I would expect the flex container to stretch all items to be at least as big as the biggest item in the container. Anyway here's a fiddle:
https://jsfiddle.net/nxbwufLk/
How is it choosing to wrap the text? Why is it not stretching the first item.
.button {
flex: 1 1 0;
border: 1px solid red;
}
.container {
display: inline-flex;
}
<div class="container">
<div class="button">
Some text
</div>
<div class="button">
Some text that is very long indeed
</div>
</div>
I can see that the second text is wrapped but how is that decided? There are no widths set anywhere
I can see that the second text is wrapped but how is that decided? There are no widths set anywhere
There is a width set it's just not trivial to notice, You're using inline-flex which on it's own should tell you what's going on.
The width of the container will equal it's content, in this case the width of the text of both elements.
Demo
.button {
border: 1px solid red;
}
.container {
display: inline-flex;
}
.test>.button {
flex: 1 1 0;
}
No flex properties set
<br/>
<div class="container">
<div class="button">
Some text
</div>
<div class="button">
Some text that is very long indeed
</div>
</div>
<br/>
<br/>
<br/> flex properties set
<br/>
<div class="container test">
<div class="button">
Some text
</div>
<div class="button">
Some text that is very long indeed
</div>
</div>
As you can see the width of the containers is the same.
Now regardless of what we do, the width of the container is set and won't change, so when you apply flex: 1 1 0; you're simply dividing that width (evenly flex-basis:0;) between the two elements and then you get the wrapping.

Flexbox issue with wrapping and flex-grow: auto

I'm struggling with a puzzle I ran myself into. I want to have tabs, which can be multiline, to fill the entire width optimally. For which flex: auto works great. However for some unrelated and unchangable circumstances I also have the container with flex-wrap: wrap and a single item covering the whole width above the tabs.
With flex: auto and flex-wrap: wrap the flex items no longer try to fit into the width by wrapping their content text — they all have it in one line and wrap if they do not fit in.
I've made a fiddle to illustrate it:
https://jsfiddle.net/d67mgqvm/
<div class="flexbox">
<div class="flexitem full">
This is a desired behavior but it has to use a wrapper to prevent wrapping
</div>
<div class="wrapper">
<div class="flexitem">
Content can be different so I have to use flex: auto so it has more space for longer texts
</div>
<div class="flexitem">
Like I said, it can be short like this one
</div>
</div>
</div>
<div class="flexbox">
<div class="flexitem full">
This doesn't work, even though it can fit in all the content if it wraps text inside items
</div>
<div class="flexitem">
Content can be different so I have to use flex: auto so it has more space for longer texts
</div>
<div class="flexitem">
Like I said, it can be short like this one
</div>
</div>
I've been thinking on if it's even possible to do this without a wrapper for a while now. Looks like flex-basis: min-content should be something like that but it only works in FF...
Well, it looks like flex-basis: min-content is what I am looking for, unfortunately it is not yet implemented anywhere other than Firefox.

Placing two divs next to each other, which should fill up the space, when both divs are of unknown width

Consider the following HTML markup:
<div class='wrapper'>
<div class='left'> Text text text </div>
<div class='right'>
<button></button>
</div>
</div>
Let's say that the button is of variable width (because of the text that appears on it). Is it possible in plain css, to place the .left and .right div next to each other, and the .left div should take up the space remaining after the width of the button element was calculated?
You can use flexbox.
flex: <positive-number>
Makes the flex item flexible and sets the flex basis to zero,
resulting in an item that receives the specified proportion of the
free space in the flex container. If all items in the flex container
use this pattern, their sizes will be proportional to the specified
flex factor.Equivalent to flex: 1 0.
Source
.wrapper {
display: flex;
}
.left {
flex: 1 1;
}
<div class='wrapper'>
<div class='left'> Text text text </div>
<div class='right'>
<button>button</button>
</div>
</div>
Change the position:relative; of #right to position:absolute;top:0;right:0; .
Alternatively you can put the right div before left div.
<div class='wrapper'>
<div id='right'> Text text text </div>
<div id='left'>
<button></button>
</div>
</div>
The elements are drawn in order. The right is drawn before and the left is drawn around the right element which will position the elements accordingly.
flexbox is another good option indeed!

How to use bootstrap to create responsive two-column layout with left column really narrow

I have been using bootstrap responsive 12 column grid layout for my website.
I have the layout like follows (stripped down version for example purpose)
<div class='container-fluid'>
<div class='row'>
<div class='col-md-1'>
Left side contents go here
</div>
<div class='col-md-11'>
Right side contents go here
</div>
</div>
</div>
What I need now, is that the left side column is wider than what I want. How can I make it fixed-length narrow and still use Bootstrap layout?
Any help is appreciated!
A clean solution would be customizing bootstrap to have more columns, like this answer:
How to use bootstrap with 16 or 24 columns
Other alternative is using nested rows, but that could end up with problems like unused space, so my suggestion is customizing bootstrap.
you can make a nested row within a column
For eg-
<div class="row">
<div class="col-md-1">
<div class="row">
<div class="col-md-offset-9 col-md-3"><!-- offset-9 leave space in left and start in last three of column --></div>
</div>
</div>
<div class="col-md-11"></div>
</div>
The issue you're having is an issue with how grid systems work. What they're designed to do is describe a fixed set of column widths: the content of those columns should expand to fill them. What you want is the inverse of this: you want the content to define the width.
You've effectively got three good options, and in order from least -> best in terms of getting what you want with the simplest markup:
Live with it (or have more columns as suggested, say 24).
Put the two columns of content in a block[1], apply display:table; width: 100%;. Make the two child items display:table-cell, use white-space:nowrap on the left-hand one and make the right-hand one width: 99%.
Put the two columns of content in a block[1], apply display:flex, and apply flex:1 to the right-hand child item.
Flex is the best solution, but needs IE10+ if that's an issue.
.container {
max-width: 400px;
margin: 0 auto;
}
[class^="row-"] {
margin: 10px 0;
}
.row-1 {
display: table;
width: 100%;
}
[class^="col-1-"] {
display: table-cell;
}
.col-1-left {
white-space: nowrap;
}
.col-1-right {
width: 99%;
}
.row-2 {
display: flex;
}
.col-2-right {
flex: 1;
}
<div class='container'>
<div class='row-1'>
<div class='col-1-left'>Some content</div>
<div class='col-1-right'>Some content</div>
</div>
<div class='row-2'>
<div class='col-2-left'>Some content</div>
<div class='col-2-right'>Some content</div>
</div>
</div>

Achieve table cell effect with floated divs

If I try to apply min-width, max-width to a floating div so that it expands to max-width when the right content is hidden does not work.
But, if I use table and 2 tds in it, the left td will expand to 100% if the right td is hidden.
Can I achieve this table effect with floated divs?
I don't think you can do what you are asking, but you can make it look like what you are asking.
Make it into two tds and put a max-width on a div inside the td. Would that work?
This isn't going to work with floats. Luckily we now have more tools at our disposal.
Here are two very simple methods to expand a div to 100% of the available width if a sibling horizontally to it is hidden or removed.
#1 – Using display: flex
Compatibility: Edge and all modern browsers. IE 10 and 11 support the non-standard -ms-flexbox.
The Basic Markup
<div class="container">
<div>
First Column
</div>
<div>
This second column can be hidden or not exist and the first column will take up its space
</div>
</div>
The CSS
The container div is given display: flex.
The containers children are give flex: 1 and they will be assigned equal width, can grow and can shrink.
.container {
width: 500px;
display: flex;
}
.container>div {
flex: 1;
background: #FF6961;
height: 200px;
margin-bottom: 20px;
}
.container>div:nth-child(even) {
background: #006961;
}
<div class="container">
<div>
Content
</div>
<div>
Content
</div>
</div>
<div class="container">
<div>
Content takes up the whole width when other divs are hidden.
</div>
<div style="display: none">
Content
</div>
</div>
<div class="container">
<div>
Content takes up the whole width when there is no other div.
</div>
</div>
Read this guide to flexbox
Read more about flexbox on the MDN
#2 – Using display: table
Compatibility: IE8+ and all modern browsers
The Basic Markup
<div class="container">
<div>
First Column
</div>
<div>
This second column can be hidden or not exist and the first column will take up its space
</div>
</div>
The CSS
The container is given display: table
The containers children are given display: table-cell and will act the same as cells in an HTML table. If a cell is hidden or is removed the other cell will take its space.
.container{
display: table;
width: 600px;
margin: 20px;
}
.container>div {
display: table-cell;
height: 200px;
background: #FF6961;
}
.container>div:nth-child(even) {
background: #006961;
}
<div class="container">
<div>
Content
</div>
<div>
Content
</div>
</div>
<div class="container">
<div>
Content takes up the whole width when other divs are hidden.
</div>
<div style="display: none">
Content
</div>
</div>
<div class="container">
<div>
Content takes up the whole width when there is no other div.
</div>
</div>
<div class="container">
<div>
Content takes up the remaining width if a cell has a fixed width.
</div>
<div style="width: 200px">
Content
</div>
</div>
Read more about CSS tables on the MDN