CSS Flexbox: grow first flex items instead of last ones - html

I have a flex-boxes layout that grows the boxes in the final "row", like here:
Screenshot
The CSS:
.container {
display: flex;
flex-flow: row wrap;
align-items: stretch;
}
.item {
flex-grow: 1;
flex-shrink: 0;
display: inline-block;
position: relative; width: 14em; height: 14em; min-width: 14em;
}
The question: can one indicate in such a row flow to preferably grow the "first" flex-items rather than the "last" ones (via CSS not JS)?

You can add flex-wrap: wrap-reverse; in the container class, and in your html add the elements in reverse order
.container {
display: flex;
flex-flow: row wrap;
align-items: stretch;
flex-wrap: wrap-reverse;
}
<div class="container">
<div class="item">5</div>
<div class="item">4</div>
<div class="item">3</div>
<div class="item">2</div>
<div class="item">1</div>
</div>

Related

Flexbox: each element 1/3 width, fall under each other if not enough space [duplicate]

This question already has answers here:
How can I show three columns per row?
(4 answers)
Closed 1 year ago.
I am looking for a way (with Flexbox, not Grid) to create a layout, when I have a container with x cards inside, and each card inside should take 1/3 of the container width. So cards number 1,2,3 will be in the first row, cards number 4,5... in the second row etc.
I feel like it is impossible with flexbox, I don't wanna do some checks for number of items, I used map to map cards in containers of max 3 cards but I didn't like the solution. Before I move to using grid, I would love to get some insight if it is possible to acomplish with Flexbox.
The code is:
<div class="container">
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
</div>
you should set box-sizing: border-box; on the cards so padding and borders are calculated in their width. and set their max-width: 33.33%.
body {
padding: 30px;
margin: 0;
}
.container {
display: flex;
flex-direction: row;
width: 100%;
flex-wrap: wrap;
background: orange;
}
.card {
box-sizing: border-box;
width: 100%;
text-align: center;
max-width: 33.33%;
padding: 50px 0;
background-color: aqua;
border: 1px solid #000;
}
<div class="container">
<div class="card">1</div>
<div class="card">2</div>
<div class="card">3</div>
<div class="card">4</div>
<div class="card">5</div>
</div>
The difference will be for the second row. There are two options for the last two element width.
Option 1 Last two nodes take 33% width only and leave the right side blank.
You have to use display: flex; flex-wrap: wrap; for .container and display: flex; flex: 0 1 33%; for the child element, which is .card.. Here flex-shrink is to be set for child
.container {
display: flex;
flex-wrap: wrap;
}
.card {
height: 100px;
display: flex;
flex: 0 1 33%;
justify-content: center;
align-items: center;
font-size: 50px;
}
<div class="container">
<div class="card">1</div>
<div class="card">2</div>
<div class="card">3</div>
<div class="card">4</div>
<div class="card">5</div>
</div>
Option 2 Last two element use 50% width each.
You have to use display: flex; flex-wrap: wrap; for container and display: flex; flex: 1 0 33%; to the child element, which is .card. Here flex-grow is to be set for child
.container {
display: flex;
flex-wrap: wrap;
}
.card {
height: 100px;
display: flex;
flex: 1 0 33%;
justify-content: center;
align-items: center;
font-size: 50px;
}
<div class="container">
<div class="card">1</div>
<div class="card">2</div>
<div class="card">3</div>
<div class="card">4</div>
<div class="card">5</div>
</div>
Flex-wrap can help you with that
.container{
display: flex;
flex-wrap: wrap;
}
.card{
min-width: 33.3333%;
}
Example here: https://codepen.io/jriches/pen/WNjVaav
Use 33.33333333% width in your card class.

Adjust flex items in same column

I have a horizontal slider(scrollable) on my page, which contains list of sub-cards. The below code snippet works perfectly fine.
JSFiddle-1: https://jsfiddle.net/28rnwpqk/
I now want to display different sized cards, which are dynamic. I made following change to my container css, so as to stack multiple cards in same column if space exists.
.container {
...
flex-direction: column;
flex-wrap: wrap;
...
}
JSFiddle-2: https://jsfiddle.net/k60zLg74/
This results in the parent container width being set only to width of first slider item, bcz of flex-direction: column property. As such the background color, slider scroll has stopped working. What is the correct way to achieve this without impacting width of container. My main requirement is to have flex items stacked vertically if space exists and size of cards is not know upfront.
CSS grid can do this better:
.viewport {
width: 600px;
height: 200px;
overflow-x: hidden;
}
.container {
display: inline-grid;
background-color: DodgerBlue;
grid-auto-flow:column;
grid-template-rows:1fr 1fr;
grid-auto-columns:130px;
gap: 10px;
height: 100%;
min-width:100%;
}
.item {
box-sizing: border-box;
background-color: #f1f1f1;
padding: 20px;
margin: 10px;
font-size: 30px;
grid-row:span 2;
}
.item.small {
grid-row:span 1;
}
<div class="viewport">
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item small">3</div>
<div class="item small">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
</div>
</div>
Your width: max_content; setting is restricting the width of your container. Remove that property, and your full container will have a blue background as expected:
.container {
display: flex;
background-color: DodgerBlue;
flex-direction: column;
flex-wrap: wrap;
gap: 10px;
height: 200px;
}

How to make flex children have equal widths and at the same time not larger than its contents?

I have the following code:
.parent {
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
}
.firstChild {
flex: 1;
text-align: left;
}
.lastChild {
flex: 1;
text-align: right;
}
<div class="parent">
A very loooooooooooooooooong link
<span>Work</span>
<span class="lastChild">Other</span>
</div>
Complete fiddle here
The Problem is: The first flex child (long link) element is larger than its content (because of flex-grow). So when the user click next to its text, it also activates the link.
We used flex-grow here in order to make 1. and 3. childs equally wide, so the 2. element can stand -almost- in the middle (since the flex childrens' width vary a lot). How can i achieve this without using flex-grow? Or in other words, how can i guarantee that, the link's width is equal to its text's width?
simply use this.
<div class="parent">
<div class="firstChild">
A very looooooooooooooooooooong link
</div>
<div>
<span>Work</span>
</div>
<div class="lastChild">
<span>Other</span>
</div>
</div>
Wrap it with an additional span.firstChild:
.parent {
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
}
.firstChild {
flex:1;
text-align:left;
}
.lastChild {
flex:1;
text-align:right;
}
/* for overview */
a {
border: 1px solid red;
}
<div class="parent">
<span class="firstChild">
A very loooooooooooooooooong link
</span>
<span>Work</span>
<span class="lastChild">Other</span>
</div>
Try this one:
.parent {
display: grid;
align-items: center;
justify-items: start;
grid-auto-flow: column;
justify-content: space-between;
grid-template-columns: repeat(3, 1fr);
justify-items: center;
}
<div class="parent">
A very looooooooooooooooooooong link
<div>
<span>Work</span>
</div>
<div class="lastChild">
<span>Other</span>
</div>
</div>

How to shrink flex items height to fit container heights

I am trying to display a layout below in flex .
I have divs of equal width and height. I want to achieve the layout out below. By placing one item on the left and the remaining four fit on the right container and maintaining the same container height in the process . Thats the one on the left increase to fill the left height and width and the other right size of the container is shared among the four items.
.trades {
display: flex;
flex: 1;
}
.trade-panel {
flex: 1;
}
.layout-5-2 {
-ms-flex-direction: row;
flex-direction: row;
justify-content: space-between;
display: flex;
}
.layout-container-5-2-1 {
-ms-flex-direction: column;
flex-direction: column;
height: 100%;
justify-content: space-between;
flex: 0 0 48%;
display: flex;
}
.layout-container-5-2-2 {
flex: 0 0 48%;
display: flex;
flex-direction: column;
}
<div class="trades">
<div class="layout-5-2">
<div class="layout-container-5-2-1">
<div class="trade-panel">item 1</div>
<div class=" trade-panel">item 2</div>
<div class="trade-panel">item 3</div>
<div class=" trade-panel">item 4</div>
</div>
<div class="layout-container-5-2-1">
<div class="trade-panel">vertical item.</div>
</div>
</div>
</div>
My layout displays close to what i was expecting.with four to in the container to the right and one item to the left. However, The trades container scroll vertically to accommodate the four trades height. The trades does not shrink to fit into the right container thats .layout-container 5-2-2. Please how do i shrink the four to fix in the container heights ? Any help would be appreciated.
Try this
body,
html {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
display: flex;
min-height: 100vh;
background: #2A3052;
}
.left {
flex: 1;
background: #9497A8;
margin: 10px;
}
.right {
flex: 1;
display: flex;
flex-direction: column;
}
.box {
flex: 1;
background: #9497A8;
margin: 10px;
}
<div class="container">
<div class="left"></div>
<div class="right">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
</div>

Flex- change position of child's child?

I wish to get A to sit at the top, B to sit in the middle and C to sit at the bottom.
JSFiddle
<div class="container">
<div class="a">A</div>
<div class="sub-container">
<div class="b">B</div>
<div class="c">C</div>
</div>
</div>
CSS:
.container{
display: flex;
flex-direction: column;
justify-content: space-between;
height: 100%;
position: fixed;
}
i need to keep the same markup - how can I change the position of a div that is not the immediate child of the flex container?
EDIT:
It should look like this
A
B
C
The CSS Display Module Level 3 introduces display: contents:
The element itself does not generate any boxes, but its children and
pseudo-elements still generate boxes as normal. For the purposes of
box generation and layout, the element must be treated as if it had
been replaced with its children and pseudo-elements in the document
tree.
You can use it to "ignore" the subcontainer, and display all the inner items as if they belonged to the same container.
body { margin: 0 }
.container {
display: flex;
flex-direction: column;
justify-content: space-between;
height: 100%;
position: fixed;
}
.sub-container {
display: contents;
}
<div class="container">
<div class="a">A</div>
<div class="sub-container">
<div class="b">B</div>
<div class="c">C</div>
</div>
</div>
It's not widely supported yet, though.
With this HTML code where .b and .c aren't siblings of .a, you can achieve desired result with a flex inception: .sub-container is both a flex item of parent .container and a flex container for .b and .c
flex: 2 0 auto; is related to height ratio of 1/3 + (1/3 + 1/3)
Fiddle
.container{
display: flex;
flex-direction: column;
justify-content: space-between;
width: 100%;
height: 100%;
position: fixed;
}
.sub-container {
flex: 2 0 auto;
/* flex inception */
display: flex;
flex-direction: column;
background-color: lightgreen;
}
.a, .b, .c {
flex: 1 0 auto; /* .a and .b, .c are not flex items of the same parent though we still want the same value */
padding: 1rem 0;
text-align: center;
}
<div class="container" style="background-color: blue;">
<div class="a" style="background-color: red;">A</div>
<div class="sub-container" style="background-color: green;">
<div class="b">B</div>
<div class="c">C</div>
</div>
</div>