Flex-wrap property not responsive when parent has a set width - html

In the example below, when I set a width for a wrapper, the parent flex container can no longer use the flex-wrap property. The top two boxes won't wrap, but the bottom ones will.
<div class="wrapper">
<div class="parent">
<div class="child"></div>
<div class="child"></div>
</div>
</div>
<div class="parent">
<div class="child"></div>
<div class="child"></div>
</div>
.wrapper {
width: 700px;
margin: 0 auto;
border: solid cadetblue 5px;
}
.parent {
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.child {
height: 250px;
min-width: 250px;
max-width: 300px;
flex: 1;
background: mistyrose;
border: solid goldenrod 2px;
margin: 30px;
}

The 'issue' you raise is by design; you're specifying a width for the parent that is wide enough for your children to be wholly contained within (a 700px container for two 300px children). flex-wrap only causes elements to overflow when there's not enough space for the container to hold them. In your example, there is.
To force an overflow responsively, you could either specify a narrow width on the parent(which will cause an overflow for all viewports):
.wrapper {
width: 400px;
margin: 0 auto;
border: solid cadetblue 5px;
}
.parent {
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.child {
height: 250px;
min-width: 250px;
max-width: 300px;
flex: 1;
background: mistyrose;
border: solid goldenrod 2px;
margin: 30px;
}
<div class="wrapper">
<div class="parent">
<div class="child"></div>
<div class="child"></div>
</div>
</div>
<div class="parent">
<div class="child"></div>
<div class="child"></div>
</div>
Or use max-width instead(which will only overflow on narrow viewports):
.wrapper {
max-width: 700px;
margin: 0 auto;
border: solid cadetblue 5px;
}
.parent {
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.child {
height: 250px;
min-width: 250px;
max-width: 300px;
flex: 1;
background: mistyrose;
border: solid goldenrod 2px;
margin: 30px;
}
<div class="wrapper">
<div class="parent">
<div class="child"></div>
<div class="child"></div>
</div>
</div>
<div class="parent">
<div class="child"></div>
<div class="child"></div>
</div>

Related

How to prevent DIV wrapping on the second row? [duplicate]

This question already has answers here:
Is it possible to prevent wrapping of child elements in HTML?
(3 answers)
Stop flex children wrapping
(2 answers)
Prevent wrapping in flex items
(1 answer)
Closed 11 months ago.
I'm trying to make a very simple list of cards, there should be 3 cards in each row with a 20 pixels gap between them. Thus, each card should occupy 1/3 of the parent container. But for some reason, when I decrease the size of the browser window, the 3rd card moves to the second row. How can I prevent this?
.parent{
border: solid green 1px;
display: flex;
flex-wrap: wrap;
width: 1000px;
height: 100px;
gap: 20px;
}
.child{
width: 32.2%;
border: solid blue 1px;
background-color: blue;
}
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
flex-wrap: nowrap; should do the trick for you. You can set the width for the children by doing calc(100% / 3);. For this to work, remove the fixed width of 1000px on the parent.
.parent{
border: solid green 1px;
display: flex;
flex-wrap: nowrap;
height: 100px;
gap: 10px;
}
.child{
width: calc(100% / 3);
border: solid blue 1px;
background-color: blue;
}
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
Using ul:
.parent {
border: solid green 1px;
display: flex;
flex-wrap: wrap;
width: 1000px;
height: 100px;
gap: 10px;
list-style-type: none;
padding-inline-start: 0;
}
.child {
border: solid blue 1px;
background-color: blue;
flex-basis: 31%;
}
<ul class="parent">
<li class="child"></li>
<li class="child"></li>
<li class="child"></li>
<li class="child"></li>
<li class="child"></li>
<li class="child"></li>
</ul>
You can change in your parent container flex-wrap: nowrap; And the item width you can change to 100%;
.parent{
border: solid green 1px;
display: flex;
flex-wrap: nowrap;
width: 1000px;
height: 100px;
gap: 20px;
box-sizing: border-box;
}
.child{
width: 100%;
border: solid blue 1px;
background-color: blue;
}
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
UPDATE
With flex-basis
.parent{
border: solid green 1px;
display: flex;
flex-wrap: wrap;
width: 1000px;
height: 100px;
gap: 20px;
box-sizing: border-box;
justify-content: space-between;
}
.child{
flex-basis: 30%;
border: solid blue 1px;
background-color: blue;
}
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>

How to fix div child of parent center when "float:left"?

I tried to center child divs inside a parent div. Quantity of child div is dynamic and I make "float: left". But group of child divs can't center inside a parent div.
Parent div static width: 800px;
Child divs static width: 360px; height: 320px.
Here my code:
* {
box-sizing: border-box;
}
.parent {
width: 800px;
display: flex;
justify-content: center;
background-color: #f8f9fb;
}
.child {
width: 360px;
margin: 7px;
min-width: 360px;
height: 320px;
float: left;
background-color: #FFFF;
border: 1px solid;
}
<div class="parent">
<div class="content">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
</div>
Some way I references but not in my case:
- http://jsfiddle.net/h9H8w/12/
- https://dev.to/stel/a-little-trick-to-left-align-items-in-last-row-with-flexbox-230l
- https://codepen.io/anon/pen/JbpPKa
My results like that:
- https://imgur.com/TX9I4vq
- https://imgur.com/NiRaHgj
Thanks for reading and sorry my bad english.
========================================================
From the help of #kukkuz. I changed my code:
* {
box-sizing: border-box;
}
.parent {
max-width: 800px;
display: grid;
justify-content: center;
background-color: #f8f9fb;
grid-template-columns: repeat( auto-fit, 360px);
grid-gap: 7px;
}
.child {
width: 360px;
/*margin: 7px;*/
min-width: 360px;
height: 320px;
/* float: left;*/
background-color: #FFFF;
border: 1px solid;
}
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
Is this what u want,
Basically I removed the float:left and the content div
justify-content: center; will handle the centering of the boxes,
Uncomment flex-wrap:wrap; to wrap the children on to the next line
Know that, making a div display:flex, will make its children flex-items, which was not happening in your case
* {
box-sizing: border-box;
}
.parent {
width: 800px;
display: flex;
justify-content: center;
background-color: #f8f9fb;
/*flex-wrap:wrap;*/
}
.child {
width: 36px;
margin: 7px;
min-width: 36px;
height: 32px;
background-color: #FFFF;
border: 1px solid;
}
<div class="parent">
<div class="child">1</div>
<div class="child">2</div>
<div class="child">3</div>
</div>

CSS Flex items vertically and then horizontally

If container has fixed width and height, is it possible to move child elements to next line until there is enough space vertically and then, when there it no more vertical space, make last line child element take width space.
It is hard to verbally expain what I want to achieve, so here is JsFiddle of what I currently have: JsFiddle
.parent {
width: 400px;
height: 300px;
background: white;
border: 1px solid black;
display: flex;
flex-wrap: wrap;
overflow: hidden;
}
.child {
width: 160px;
height: 80px;
margin: 4px;
background: red;
}
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
Image of what I would like to achieve:
You can have something similar if you use a column direction. In this case, the overflow will occur on the right and not on the bottom:
.parent {
width: 400px;
height: 300px;
background: white;
border: 1px solid black;
display: flex;
flex-direction:column;
justify-content:flex-end;
flex-wrap: wrap;
overflow: hidden;
}
.child {
width: 160px;
height: 80px;
margin: 4px;
background: red;
}
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>

How to make CSS grid that stretches children and respects min-height: 0 on them?

I have simple css grid. I'd like it to stretch children to fill available content but also respect it if any of the children has height: 0. Right now it also "reserves" space for the child with height: 0.
Here's the fiddle showing my problem:
https://jsfiddle.net/f3r0b5e9/7/
.wrapper {
height: 300px;
width: 200px;
border: 1px solid red;
display: grid;
align-content: stretch;
grid-template-rows: auto;
}
.child {
width: 100%;
border: 1px solid blue;
background: #cad5e8;
}
.child.one {
height: 0;
min-height: 0;
max-height: 0;
}
<div class="wrapper">
<div class="child one">
</div>
<div class="child two">
</div>
<div class="child three">
</div>
</div>
Here's what I'm trying to accomplish:
http://prntscr.com/kqcry4
Note: I know how to do this with flexbox:)
Thanks!
Instead of auto, use min-content or max-content for the grid-template-rows's value:
.wrapper {
height: 300px;
width: 200px;
border: 1px solid red;
display: grid;
align-content: stretch;
grid-template-rows: min-content;
}
.child {
width: 100%;
border: 1px solid blue;
background: #cad5e8;
}
.child.one {
height: 0;
min-height: 0;
max-height: 0;
}
<div class="wrapper">
<div class="child one">
</div>
<div class="child two">
</div>
<div class="child three">
</div>
</div>

Flexbox: 4 items per row

I'm using a flex box to display 8 items that will dynamically resize with my page. How do I force it to split the items into two rows? (4 per row)?
Here is a relevant snip:
(Or if you prefer jsfiddle - http://jsfiddle.net/vivmaha/oq6prk1p/2/)
.parent-wrapper {
height: 100%;
width: 100%;
border: 1px solid black;
}
.parent {
display: flex;
font-size: 0;
flex-wrap: wrap;
margin: -10px 0 0 -10px;
}
.child {
display: inline-block;
background: blue;
margin: 10px 0 0 10px;
flex-grow: 1;
height: 100px;
}
<body>
<div class="parent-wrapper">
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
</div>
</body>
You've got flex-wrap: wrap on the container. That's good, because it overrides the default value, which is nowrap (source). This is the reason items don't wrap to form a grid in some cases.
In this case, the main problem is flex-grow: 1 on the flex items.
The flex-grow property doesn't actually size flex items. Its task is to distribute free space in the container (source). So no matter how small the screen size, each item will receive a proportional part of the free space on the line.
More specifically, there are eight flex items in your container. With flex-grow: 1, each one receives 1/8 of the free space on the line. Since there's no content in your items, they can shrink to zero width and will never wrap.
The solution is to define a width on the items. Try this:
.parent {
display: flex;
flex-wrap: wrap;
}
.child {
flex: 1 0 21%; /* explanation below */
margin: 5px;
height: 100px;
background-color: blue;
}
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
With flex-grow: 1 defined in the flex shorthand, there's no need for flex-basis to be 25%, which would actually result in three items per row due to the margins.
Since flex-grow will consume free space on the row, flex-basis only needs to be large enough to enforce a wrap. In this case, with flex-basis: 21%, there's plenty of space for the margins, but never enough space for a fifth item.
Add a width to the .child elements. I personally would use percentages on the margin-left if you want to have it always 4 per row.
DEMO
.child {
display: inline-block;
background: blue;
margin: 10px 0 0 2%;
flex-grow: 1;
height: 100px;
width: calc(100% * (1/4) - 10px - 1px);
}
Here is another apporach.
You can accomplish it in this way too:
.parent{
display: flex;
flex-wrap: wrap;
}
.child{
width: 25%;
box-sizing: border-box;
}
Sample:
https://codepen.io/capynet/pen/WOPBBm
And a more complete sample:
https://codepen.io/capynet/pen/JyYaba
I would do it like this using negative margins and calc for the gutters:
.parent {
display: flex;
flex-wrap: wrap;
margin-top: -10px;
margin-left: -10px;
}
.child {
width: calc(25% - 10px);
margin-left: 10px;
margin-top: 10px;
}
Demo: https://jsfiddle.net/9j2rvom4/
Alternative CSS Grid Method:
.parent {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-column-gap: 10px;
grid-row-gap: 10px;
}
Demo: https://jsfiddle.net/jc2utfs3/
For more detail you can follow this Link
.parent{
display: flex;
flex-wrap: wrap;
}
.parent .child{
flex: 1 1 25%;
/*Start Run Code Snippet output CSS*/
padding: 5px;
box-sizing: border-box;
text-align: center;
border: 1px solid #000;
/*End Run Code Snippet output CSS*/
}
<div class="parent">
<div class="child">1</div>
<div class="child">2</div>
<div class="child">3</div>
<div class="child">4</div>
<div class="child">5</div>
<div class="child">6</div>
<div class="child">7</div>
<div class="child">8</div>
</div>
I believe this example is more barebones and easier to understand then #dowomenfart.
.child {
display: inline-block;
margin: 0 1em;
flex-grow: 1;
width: calc(25% - 2em);
}
This accomplishes the same width calculations while cutting straight to the meat. The math is way easier and em is the new standard due to its scalability and mobile-friendliness.
.parent-wrapper {
height: 100%;
width: 100%;
border: 1px solid black;
}
.parent {
display: flex;
font-size: 0;
flex-wrap: wrap;
margin-right: -10px;
margin-bottom: -10px;
}
.child {
background: blue;
height: 100px;
flex-grow: 1;
flex-shrink: 0;
flex-basis: calc(25% - 10px);
}
.child:nth-child(even) {
margin: 0 10px 10px 10px;
background-color: lime;
}
.child:nth-child(odd) {
background-color: orange;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
</style>
</head>
<body>
<div class="parent-wrapper">
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
</div>
</body>
</html>
;)
Flex wrap + negative margin
Why flex vs. display: inline-block?
Flex gives more flexibility with elements sizing
Built-in white spacing collapsing (see 3 inline-block divs with exactly 33% width not fitting in parent)
Why negative margin?
Either you use SCSS or CSS-in-JS for the edge cases (i.e. first element in column), or you set a default margin and get rid of the outer margin later.
Implementation
https://codepen.io/zurfyx/pen/BaBWpja
<div class="outerContainer">
<div class="container">
<div class="elementContainer">
<div class="element">
</div>
</div>
...
</div>
</div>
:root {
--columns: 2;
--betweenColumns: 20px; /* This value is doubled when no margin collapsing */
}
.outerContainer {
overflow: hidden; /* Hide the negative margin */
}
.container {
background-color: grey;
display: flex;
flex-wrap: wrap;
margin: calc(-1 * var(--betweenColumns));
}
.elementContainer {
display: flex; /* To prevent margin collapsing */
width: calc(1/var(--columns) * 100% - 2 * var(--betweenColumns));
margin: var(--betweenColumns);
}
.element {
display: flex;
border: 1px solid red;
background-color: yellow;
width: 100%;
height: 42px;
}
you can try this
.parent-wrapper {
height:100%;
width:100%;
border: 1px solid black;
}
.parent {
display: grid;
font-size: 0;
grid-template-columns: 25% 25% 25% 25%;
}
.child {
background:blue;
flex-grow: 1;
height:100px;
margin: 10px;
margin-bottom: 0;
}
.child:last-child {
margin-bottom: 10px;
}
<body>
<div class="parent-wrapper">
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
</div>
</body>
https://jsfiddle.net/samet19/gdntwLhb/
Here's another way without using calc().
// 4 PER ROW
// 100 divided by 4 is 25. Let's use 21% for width, and the remainder 4% for left & right margins...
.child {
margin: 0 2% 0 2%;
width: 21%;
}
// 3 PER ROW
// 100 divided by 3 is 33.3333... Let's use 30% for width, and remaining 3.3333% for sides (hint: 3.3333 / 2 = 1.66666)
.child {
margin: 0 1.66666% 0 1.66666%;
width: 30%;
}
// and so on!
That's all there is to it. You can get fancy with the dimensions to get a more aesthetic sizes but this is the idea.