I'm trying to create a grid layout based on flexbox:
.container {
width: 360px; /* Try to change this. Possible values: 240px, 360px, 480px.*/
background: #eee;
display: flex;
flex-flow: row wrap;
margin: 0 -10px;
}
.cell {
box-sizing: border-box;
padding: 10px;
flex: 0 0 120px;
max-width: 120px;
}
.cell.wide {
flex: 1 0 120px;
max-width: 240px;
}
.inner {
background: red;
height: 100px;
color: #fff;
padding: 10px;
box-sizing: border-box;
}
.wide .inner {
background: blue;
}
<div class="container">
<div class="cell">
<div class="inner">1</div>
</div>
<div class="cell wide">
<div class="inner">2</div>
</div>
<div class="cell">
<div class="inner">3</div>
</div>
<div class="cell">
<div class="inner">4</div>
</div>
<div class="cell wide">
<div class="inner">5</div>
</div>
<div class="cell">
<div class="inner">6</div>
</div>
<div class="cell wide">
<div class="inner">7</div>
</div>
<div class="cell">
<div class="inner">8</div>
</div>
<div class="cell">
<div class="inner">9</div>
</div>
<div class="cell">
<div class="inner">10</div>
</div>
<div class="cell">
<div class="inner">11</div>
</div>
<div class="cell wide">
<div class="inner">12</div>
</div>
<div class="cell">
<div class="inner">13</div>
</div>
</div>
This JSFiddle helps to illustrate my problem.
A container element .container can contain any number of cells.cell. There are two types of cells: a regular one with a fixed width (the red ones in the jsfiddle) and a wide one .cell.wide (the blue ones) which are twice as wide but could shrink to the width of the regular cell if there is not enough space in the current row. Each row must be filled completely.
So in the example (see fiddle):
Cell #2 should be wide and push #3 to the next row.
In the second row, which then contains #3, #4 and #5, cell #5 should stay small, because there's no space for a larger cell and rows should be filled completely.
etc
By the way: The grid container is of variable width and rows can therefore contain between two and four cells. You can try this out in the fiddle by changing to width to the specified possible values.
After trying around in the fiddle for the whole morning and trying numerous combinations of the flex, width, min-width and max-width properties I definitely need you help! Thanks in advance!
I already have a Javascript workaround (counting columns and adding classes) but would much prefer a CSS-only solution.
I believe the answer is that what you're looking for is not possible with Flexbox. The reason is that the sizing algorithm (in simplified terms) uses a couple of steps to determine the actual size of the element:
Determine the preferred minimum size (the value of flex-basis if set to a length/percentage, the value of main axis size if declared to be auto, and min-content size if not). In your case, both .cell and .cell.wide prefer 120px.
Place items as if they had the preferred size.
Evaluate each resulting line (in a wrapping flex flow) and determine any remaining space.
Distribute remaining space (per line) according to flex-grow.
In your case, this means that each item (regardless if .wide or not) will evaluate to a preferred size of 120px, and thus fits 3 items on each row. At this point, the flex-grow factor does nothing, as there isn't any space left to grow, so the fact that .wide items have a flex-grow of 1 is irrelevant. I think your example would require a form of "sometimes min-width, sometimes not" behavior that flexbox just doesn't do — there would be too many layout passes for the browser to do (e.g. reflowing into lines several times etc).
The only CSS-based solution I can think of is to hardcode all the possible scenarios in something akin to "Quantity Queries", but that would get unwieldy fast...
Closest I can get with flexbox is something like https://jsfiddle.net/qde5xq09/1/.
Related
I'm using Bulma for column management, and it has a is-multiline class that can be used to allow columns to wrap. However, I'm not using this class, but my columns are still wrapping.
Expected Behavior:
Two columns are always side-by-side, on the same row
Actual behavior:
At certain viewport widths, the second column goes below the first column instead of beside.
Question
If you're familiar with Bulma, would you mind taking a look at this simple example and letting me know if I'm doing something obviously wrong? Thanks so much!
HTML
<div class="body">
<div class="columns">
<div class="column row-name is-narrow">
Row 1
</div>
<div class="column row-cells">
Some data
</div>
</div>
</div>
CSS
.body {
width: 600px;
background-color: #000;
margin: 0 auto 0;
}
.row-name {
background-color: #ffff0088;
width: 50px;
}
.row-cells {
background-color: #ff000088;
}
A JSFiddle: https://jsfiddle.net/8ggyagxp/10/
It turns out if Bulma detects that your viewport is mobile sized, it will stack columns unless the is-mobile class exists on the columns. See here for more information.
I want to make my Bootstrap 3 columns to be:
of the same height (edit: equal to the highest column, which could change)
have visible gutters separating them
have a background color that matches their equal height
So far I was able to either make them of equal height (with no visible gutter) or give them a gutter and a background. I've been fiddling with this for the past 2 hours to no avail. Naturally, I've read through everything I could find but couldn't solve this riddle. Would highly appreciate your help!
Here is code and codepen with my problem.
HTML
<div class="container">
<div class="flex-row row">
<div class="col-sm-5">
<div class="inner">
<p>Some text and probably an image over here. Not as much as on the other side, but still..</p>
</div>
</div>
<div class="col-sm-7">
<div class="inner">
<p>More content on this side. How can I make the two columns have the same height and have a gutter in between?</p>
<img src="...">
</div>
</div>
</div>
</div>
CSS
div[class^='col-sm-'],
div[class*=' col-sm-'] {
background-color: green;
}
#media only screen and (min-width : 768px) {
.flex-row.row {
display: flex;
flex-wrap: wrap;
}
.flex-row.row > [class*='col-'] {
display: flex;
flex-direction: column;
}
.flex-row.row:after,
.flex-row.row:before {
display: flex;
}
}
http://codepen.io/anon/pen/QEozAj
I don't want columns to be of fixed height because contents will change.
And ideally I would like to have as little extra divs as possible. :)
Edit: Column heights now look okay, thanks to a helpful reply. Still need the visible gutter.
I am working on a grid layout using css flex styling and want a total css solution, if possible, I have the means to fix it with javascript.
When a row exceeds the viewport width, it displays the scrollbar,
but when you scroll, the styling of the row element remains the size of the viewport,
it does not seem to "wrap" all of its children.
see : fiddle
Try scrolling, you will see the yellow row (.sk_row) class does not appear around all its children.
A solution would be fine, but I would like to know why the parent does not visually contain all children. I think I may be missing some key concept about flexboxes...
Duplicate of fiddle code...
<body>
<div id='pg_wrap'>
<div id='frm0'>
<div class='sk_scrl'>
<div class='sk_row'>
<div class='itm_val'>row 1</div>
<div class='itm_val'>1</div>
<div class='itm_val'>2</div>
<div class='itm_val'>3</div>
<div class='itm_val'>4</div>
<div class='itm_val'>5</div>
<div class='itm_val'>6</div>
<div class='itm_val'>7</div>
<div class='itm_val'>8</div>
</div>
<div class='sk_row'>
<div class='itm_val'>row 2</div>
<div class='itm_val'>1</div>
<div class='itm_val'>2</div>
<div class='itm_val'>3</div>
<div class='itm_val'>4</div>
<div class='itm_val'>5</div>
<div class='itm_val'>6</div>
<div class='itm_val'>7</div>
<div class='itm_val'>8</div>
</div>
</div>
</div>
</div>
#frm0{ width:420px;height:200px}
.sk_scrl{ overflow:auto;display:flex;flex-flow:column;align-content:stretch}
.sk_row{
display:flex;
justify-content:flex-start;
align-items:center;
background:#ff0;border:2px #f00 solid;
height:50px}
.itm_val{
display:flex;
border:1px #000 solid;background:#666;
flex:0 0 100px; height:30px; margin:0 5px;
align-items:center;justify-content:center}
Note : this is not the same as question
That op wants to change child behaviour, I want the parent to change.
It's not working the way you want because .sk_row inherits the width, in this case from #frm0:
#frm0 { width: 420px; }
With the class .sk_scrl you can't see it very well, because it's set to:
.sk_scrl { overflow: auto; }
If you use your browsers developer tools (assuming you have any), you'll see that the elements wrapped around your .itm_val divs are all 420 pixel wide. The reason the .itm_val divs are all visible outside of their container, is because they are "overflowing" out of their containing div.
Here's an example for how the width-inheriting-thing works:
<div class="container">
<div class="element"></div>
</div>
If you set the the width of .container to 50%, it will use up half of the available width within the window. If, however, you want .element to take up the full width of the window, you will have to adjust the width like this:
.element {
width: 200%;
}
If it were set to 100%, it would only be as wide as .container.
Here's a fiddle: http://jsfiddle.net/Niffler/n8hmpv13/
Given the following markup:
<div class="box">
<div class="A">A</div>
<div class="B">B</div>
<div class="C">C</div>
</div>
How do I achieve the following layout:
With the following behavior:
A has fixed width of 150px
Height of C is based on the height of the content inside of it (which changes), but it always remains fixed to the bottom.
The flex container (.box) width takes up the full width of the browser.
B and C always take up the remaining width of the container (.box) after A's 150px of width is taken into account.
What about A's and B's height? Is it fixed or it varies depending on
the content or something else?
The height of the content inside of A will not change, but the height of the content inside of B will change. .box height should equal max(height A, height B + C)
Here's a pen where everything is stubbed out
Your result is conceptually simple, but you need to use more than just 3 consecutive elements to accomplish what you want. Flex box is the bee's knees but it can't magic your layout. You need a separate sub-layout.
HTML
<div class="box flex">
<div class="a">A</div>
<div class="b-c flex column">
<div class="b">B</div>
<div class="c"></div>
</div>
<div>
CSS
.box {
display: flex;
align-items: stretch;
width: 100vw;
}
.a {
flex: 0 0 150px;
}
.b-c {
flex-direction: column;
display: flex;
flex-grow: 1;
}
I have some divs that should take the entire height of a page. I managed to get this working as i needed. (Some fixed rows and some flexible rows) like in a html table.
I took the solution from one of my other questions here:
Layout divs in css like table cells in HTML Tables
Today i had to add a div inside the flexible row which should take 100% of the height of the flexible row. Which works great in all major browsers. Muahaha that was a good joke wasn't it? Of course this doesn't work as expected in IE see my js fiddle:
<div class="tableContainer">
<div class="row rowA">
<div class="cell">Test</div>
</div>
<div class="row rowB">
<div class="cell">Test</div>
</div>
<div class="row rowC">
<div class="cell">Test</div>
</div>
<div class="row rowD">
<div class="cell testcell">
<div class="testcontent">Test</div>
</div>
</div>
<div class="row rowE">
<div class="cell">Test</div>
</div>
</div>
http://jsfiddle.net/7ewEJ/3/
the ie seems to take the "100%" from the page and not from the enclosing flexible table row. So the blue div should take the whole space of the purble table row.
Am i doing anything wrong?
Could this be a bug in ie's height calculation?
http://jsfiddle.net/7ewEJ/5/
div.testcell{
height: 100%;
width: 100%;
min-width: 1px;
min-height: 1px;
/*background: #fff;*/
align: center;
display: block;
}