Reputation: 104999
I'm trying to implement a flex box of the following scenario outlined by this positioning
+----+----------+----+
| 1|2> | <3|
+----+----------+----+
| 4|5 |
| v|v |
+----+ |
| |
+----+------+--------+
|7> | <6|
+-----------+--------+
<>v
show dimension flexibility of an item depending on the amount of content it has;
>
content will stretch to the right<
content will stretch to the leftv
content will stretch downThe main problem is that all of the items are within the same flex container. Therefore I have problems wrapping them (breaking the line) at the right point i.e. items should wrap after item 3, while items 2 and 3 have to stretch over the whole line, so item 3 can display content completely to the right of itself.
Here a working JSFiddle with inital HTML and CSS that you can work on.
Maybe just for idea that crossed my mind. One could use two additional items in flexbox container by using :before
and :after
and giving them proper order. This way one could simulate some additional content to get required results.
If there were flex groups it would be much easier because one could change flex-direction
to column
and group several items together:1&2&3, 4&5 and 6&7 and position them in row
within flex group with proper widths.
Upvotes: 1
Views: 4251
Reputation: 104999
This solution I've now come up with using some ideas of @Jan's answer and realising that all browsers that support flexbox also support calc
CSS function. And based on this I was able to make flexbox container flexible and keep items within break at points I require.
Jan's answer solved my layout assuming that all item widths are relative to container, yet items #1 and #3 have fixed widths. All of the others are flexible according to layout.
I'm just adding the most important CSS that defines flex item widths on a flexible container. I'll refer to .itemX
as a selector of flex item X where X is element number. So these selectors are just pseudo code for easier understanding. Adjust accordingly:
.itemAll {
flex-grow: 1;
}
.item1,
.item4 {
flex-grow: 0;
flex-basis: @FixedWidth; /* i.e. 25px */
}
.item2,
.item3 {
flex-basis: calc((100% - @FixedWidth)/2);
}
.item5 {
flex-basis: calc(100% - @FixedWidth);
}
.item6,
.item7 {
flex-basis: 50%;
}
As we can see from my modified JSFiddle example this actually works. Try resizing results panel width and you'll see that all flex items except #1 and #4 adjust their width according to container and always keep their layout as defined.
Upvotes: 0
Reputation: 287950
Effectively, you can use pseudo-elements to achieve this:
main::before, main::after {
content: ''; /* Enable pseudo-elements */
margin-right: 100%; /* Force line break */
}
main::before {
order: 4; /* Place it before .i4 */
}
main::after {
order: 5; /* Place it after .i5 */
}
main {
width: 200px;
display: flex;
flex-flow: row wrap;
border: 1px solid #ccc;
resize: horizontal;
overflow: auto;
}
main::before, main::after {
content: '';
margin-right: 100%;
}
main::before {
order: 4;
}
main::after {
order: 5;
}
.i2, .i3, .i5, .i6, .i7 {
flex-grow: 1;
}
.i5 {
width: 0;
}
section {
border: 1px solid #eee;
}
.i1, .i4 {
width: 50px;
text-align: right;
}
.i7 {
text-align: right;
order: 6;
}
.i1 { order: 1; }
.i2 { order: 2; }
.i3 { order: 3; }
.i4 { order: 4; }
.i5 { order: 5; }
.i6 { order: 7; }
.i7 { order: 6; }
<main>
<section class="i1">1</section>
<section class="i2">2</section>
<section class="i3">3</section>
<section class="i4">4</section>
<section class="i5">This one has much more content than the rest.</section>
<section class="i6">6</section>
<section class="i7">7</section>
</main>
Upvotes: 1
Reputation: 1414
I managed to achieve the desired result by using flex-basis
. When the items 1, 2, 3 and 4 all have a basis of 26%, the 4th item does not fit in the first row anymore. The same thing can be applied to the second row.
Then flex-grow
can be applied to items 2, 3, 5, 6 and 7 to fill the remaining space in each row.
Finally align-self
the 4th item, so it does not use the same height as item 5.
Updated JSFiddle: http://jsfiddle.net/ojmghu3t/2/
Update: Of course you can also specify px
with flex-basis
. But then it is harder to produce a break at the correct position.
Here is the JSFiddle with fixed values for item 1 and 4: http://jsfiddle.net/ojmghu3t/4/
Upvotes: 1