Flexbox justify wrapped content with same sized elements - html

I was using CSS-Grid to make a list of elements that had a min-width of 35px and the size would adapt if you resized the window, so that always as many elements as possible could fit into one row, and the gap on the right of the row would always be the same as it was on the left using this CSS:
article{
display: grid;
grid-template-columns: repeat(auto-fill, minmax(35px, 1fr));
grid-gap: 5px;
}
div{
height: 35px;
background-color: lightblue;
}
You can try it here, by rescaling the window.
https://jsfiddle.net/k36jy0ou/39/
But due to compability problems I now want to make the same behaviour using flexbox. I don't know flexbox really well, but I got kind of close using this CSS:
article{
display: flex;
flex-wrap: wrap;
}
div {
flex-grow: 1;
min-width: 35px;
max-width: 40px;
background-color: lightblue;
height: 35px;
margin: 5px;
}
https://jsfiddle.net/k1tmfu7o/3/
Except, that not all elements have the same size, if you do it like this.
Here is an image to explain my problem
Is there any way to do it using flexbox?
Thank you for your help.

Already has an answer here
Working example from the answer above
SASS code
=flex-wrap-fix($flex-basis, $max-viewport-width: 2000px)
flex-grow: 1
flex-basis: $flex-basis
max-width: 100%
$multiplier: 1
$current-width: 0px
#while $current-width < $max-viewport-width
$current-width: $current-width + $flex-basis
$multiplier: $multiplier + 1
#media (min-width: $flex-basis * $multiplier)
max-width: percentage(1 / $multiplier)
ul
display: flex
flex-wrap: wrap
li
// I want the width to be between the following two sizes
min-width: 40px
//max-width: 100px
// this keeps all the elements the same size
// **as long as they are on the same row**
// but I want them to all the same width everywhere
//flex: 1 0 0
+flex-wrap-fix(100px)
// demo styles
ul, li
margin: 0
padding: 0
list-style: none
ul
background-color: tomato
li
.content
margin: .5em
background-color: darkgreen
// the image may have variable width, I want it to take the entire space calculated by flexbox
img
width: 100%
opacity: .5
figure, img
margin: 0
padding: 0

Remove
flex-grow:1;
and they will be the same size!

I don't know it is what you want or not, just add the attribute on the class article:
justify-content: space-around;
or
justify-content: space-between;
The gap will disappear.

Related

How can I make three containers grow at the same size

So I am building a 3 column preview card using HTML, CSS and FLEXBOX. I built it using the mobile-first approach. It starts off as a column but when it is being expanded and it reaches a certain dimension, it transforms into a row. The problem I am having is that as the containers transform to a row, they grow in different sizes. The heights grow differently as some become columns become taller than others. How can I make sure they all grow at the same rate? How do I make sure that one column does not become larger than the other as they are being expanded? I tried setting flex-grow to 1 and flex-shrink to 1 but it is not working. Please find relevant parts of my code below.
Here is a link to the live version of my site
body {
box-sizing: border-box;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
--The panel is the container as a whole--
.panel {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
border: 1px solid white;
border-radius: 10px;
width: 100%;
max-width: 960px;
height: 100%
}
--I am styling each column below--
.panel section {
display: flex;
padding: 2.5rem;
flex-direction: column;
text-align: left;
border-bottom: none;
height: 100%;
#media only screen and (min-width: 560px) {
.panel {
display: flex;
flex-direction: row;
border-radius: 10px ;
width: 80%;
height: 100%;
}
.panel section {
height: 100%;
}
}
Remove the height: 100% from the child elements and just simply change the align-items to stretch on desktop, that will create equal height columns.
Well there can be different ways to solve this.
Problem : Due to which this error occur . It the difference between the amount of content in three containers as middle has more content that is you have told more about SUVS . This is the cause
Solution : Either you can make the content almost equal or can make the height of container bigger so that content can easily fit
Content equal and Content fixed height - Less compatible as content can vary on need
Increase height of container - Using hard code(400px; 30em) you can increase the height of the container according to need of content . And you can position Learn more btn at bottom using absolute position . So that it positioned at equal height
#media only screen and (min-width: 560px)
.panel section {
height: 30em;
position: relative;
}
.general-button {
background-color: var(--major-color);
border-radius: 5rem;
padding: 0.89rem;
margin: 1.1em 0;
border: none;
width: 8rem;
position: absolute;
bottom: 0;
}

How do I center these items properly?

I have the code here but basically the problem is I have these product cards and I am trying to get them in the center but also align them with the other cards if that makes sense.
https://codepen.io/manfreebie/pen/NWNvyGz
Here is a visual of what I want to accomplish vs. what is actually happening. It looks fine at first till you try to resize it.
I have tried to make the cocktail-container have the value flex-start instead of center for the justify-content attribute like this
#cocktails-container {
max-width: 70%;
display: flex;
flex-flow: row wrap;
justify-content: flex-start;
}
but that leaves a lot of whitespace on the right side when I resize it. I have tried playing around a little bit with inline-block and using text-align instead but that didn't work either.
Add this code.
#cocktails-container::after {
content: "";
flex: auto;
}
I am only sharing parts that I changed, the rest is the same.
#cocktails-container {
width: 70%; // You can adjust this for your needs
display: flex;
flex-flow: row wrap;
justify-content: start;
}
// Removed margin from .cocktail but added padding to the a tag
.cocktail {
width: 100%;
height: auto;
padding-top: 10px;
text-align: center;
}
a {
width: 33%; // You should adjust this for different screen widths, mobile 100% large 25% etc.
padding: 15px;
box-sizing: border-box; // This is necessary to include padding in '33% width'
}
Please try this code,To How do I center these items properly?
.box {
display: flex;
align-items: flex-start;
height: 200px;
}
.box .selected {
align-self: center;
}
<div class="box">
<div class="selected">Three</div>
</div>
I hope this code will be useful for you.
Thank you.
The issue that I identified while checking the code is that you are using a margin margin: 50px 0px; for the .cocktail class. Change it to the below one.
#media (max-width: 800px) {
.cocktail {
width: 60%;
margin: 50px auto;
}
}
Giving margin value 50px 0px; will make the left and right margin to zero in the samller resolution. Update that to 50px auto that will give left and right margins auto value.

Negative margin not working with flexbox

I'm trying to create a grid layout with the help of the flexbox.
What I'm doing is that I'm giving parent negative margin on left and right and then giving its child the same amount of padding on left and right for the gutter space.
I'm trying to make 5 column grid and when I use flex: 1 1 20% all the columns are not coming in the same row. The last get wrapped in the next row. This should not be the case as flex-basis is set to 20% and parent should accommodate all five columns in one row.
But when I'm trying to do this, the 4th grid item is getting wrapped on the next line.
Here is the working codepen for this issue.
Updated the codepen:
https://codepen.io/vikrantnegi007/pen/BZwGJQ
Thanks.
If I add bootstrap to to your codepen it works, which means you have some other issue we can't see in your original code.
Note though, based on your image's settings, your elements still might wrap
Still, instead of doing negative margin tricks, create a gutter, use justify-content: space-around and flex-basis.
Updated codepen
//testing css
.buisness-blocks {min-height: 250px;}
//main css
.buisness-blocks {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
.block {
flex-basis: calc(20% - 10px);
outline: 1px solid;
}
}
Is box-sizing the CSS property you are looking for?
Giving the block's a box-sizing of border-box, they all come next to each other:
.block {
flex: 0 1 20%;
padding-right: 10px;
padding-left: 10px;
outline: 1px solid;
box-sizing: border-box;
}
https://codepen.io/anon/pen/vZeQjO
Just Try This hope its work
.buisness-blocks {min-height: 250px;}
.buisness-blocks {
display: flex;
display: -webkit-flex;
flex-wrap: wrap;
margin-right: 0px;
margin-left: 0px;
.block {
flex: 0 1 20%;
-webkit-flex: 10; /* Safari 6.1+ */
-ms-flex: 10; /* IE 10 */
flex: 2;
padding-right: 10px;
padding-left: 10px;
outline: 1px solid;
}
}
CLICK HERE for DEMO
If the negative margins isn't working with display flex, but you can try to use transform:
At the CSS style properties of the inner element add the translate that you wanna.
Example:
transform: translateY(15px);
P.S.: transform isn't portable to all browsers.

How can I set a minimum amount of space between flexbox items?

Given this CSS:
div.container {
display: flex;
flex-flow: row wrap;
justify-content: space-between;
border: 1px solid blue;
}
div.container div {
width: 200px;
border: 1px solid gray;
display: inline-block;
text-align: center;
}
This layout has the first item in each row aligned to the left, and the last item aligned to the right, as required.
As the browser window is made narrower, the distributed div elements will move closer together until they touch, at which point they are re-arranged over an additional row. Again, the first div on each row is aligned left, and the last aligned right with space between.
Is there any way of setting a minimum spacing so that the inner div elements always have a gap between them.
padding and margin will probably not work, as the alignment
<-- 1st left in row and last right in row --> will not hold.
Bit late the the party but I ran into the same issue. The way I solved it probably wont work for everyone but here it is for those who can use it.
The basic idea is that you have a min gap of x. You set the left and right margins of each item to x/2 so that the distance between the items will be x (margin + margin). Then you wrap all of the items in a container with a left and right margin of -x/2. This will hide the margin on the items at the edges of each row.
Here is a working example:
.box {
border: 1px solid black;
overflow-x: hidden;
}
.container {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
margin: 0 -1em;
}
.item {
display: flex;
border: 1px solid grey;
padding: 1em;
width: 20%;
margin: 0 1em;
}
<div class="box">
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
</div>
</div>
The overflow-x: hidden; on .box is to prevent the horizontal scrollbar that shows up in some browsers because of the margin overflowing.
If you want the gap to always be consistent and for rows with only one item to have that item span the whole row then you can add flex-grow: 1 to .item.
You can add another div with flex style for holding the needed gap between inner divs. and for the minimum width for that gap use this property (as mentioned in W3Schools.com):
flex: flex-grow flex-shrink flex-basis|auto|initial|inherit;
which flex-shrink is :
flex-shrink: A number specifying how much the item will shrink relative to the rest of the flexible items
so, for example you set this css code for the gap div :
flex: 1 0 10px;
that tells gap div will have 10px width, and will grow relative to the rest of the flexible items, but WON'T SHRINK. so the minimum width will be 10px at the narrowest width of the screen.
In 2022 you can just use gap CSS property:
div.container {
display: flex;
flex-flow: row wrap;
justify-content: space-between;
border: 1px solid blue;
gap: 20px;
}
To support older browsers you may use margin hack.
div.container > * {
margin: 12px 0 0 12px;
}
div.container {
display: inline-flex;
flex-wrap: wrap;
margin: -12px 0 0 -12px;
width: calc(100% + 12px);
}
Since April 2021 support for flexbox-gap has arrived in all major browsers (IE considered dead). Combining it w/ space-between solves your problem.
div.container {
display: flex;
gap: 10px; /* minimum gap between flex-items */
justify-content: space-between;
}
It's a couple of days passed since this question was asked, but I thought I should add my solution if anybody comes past and has the same issue.
I suggest using calc, width, and media to solve this issue. Yes, it's a little work but it's a visual clean solution in my opinion.
.main{
display: flex;
justify-content: space-between;
flex-wrap: wrap;
}
.main > div{
width: 100%;
height: 125px;
border: 1px solid red;
}
#media (min-width: 576px) {
.main > div{
width: calc(100% / 2 - 5px);
margin-bottom: 5px;
}
}
#media (min-width: 992px) {
.main > div{
width: calc(100% / 3 - 5px);
}
}
#media (min-width: 1140px) {
.main > div{
width: calc(100% / 6 - 5px);
margin-bottom: 0;
}
}
<div class="main">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
</div>
For the needed breakpoints I calculate the width I want the divs to use and subtract the space I want them to have.
I hope this helps someone and that I explained it understandable.
Regards.
Setting a flex-basis with percentage also will do the trick. Then the min space between will be also in percentage.
For instance, with 3 elements, flex: 0 0 30% will allow a fixed 10% space reparted between elements.
with 6 elements, flex: 0 0 15% and so on.

How to use css3 flexbox to create multi-column layout without expanding vertically?

I'm playing with css3's flexbox in Chrome (no need to worry about cross-browser for this). I'm having a hard time convincing it to lay out my content the way I'd like. Here's a sketch of my goal:
Here's a jsFiddle of my attempt: http://jsfiddle.net/Yht4V/2/ This seems to work great except each .group will expand its height rather than create multiple columns.
I'm using flexbox pervasively here. The body lays out vertically, with the #content div taking the remaining height of the page. Each .group is laid out horizontally. Finally, each .item is laid out within a .group vertically with wrapping.
Unfortunately, each .group ends up as a single column by expanding the #content height, which causes a vertical scrollbar (unwanted). If I set the height of each .group to a fixed pixel size, the items break out into multiple columns, but this defeats the fluidity of the flexbox. Here's what it looks like with fixed heights: http://jsfiddle.net/Yht4V/3/
So, how can I get my #content div to not expand vertically since everything is managed with flexboxes without setting a fixed height? I was expecting the flexbox to trigger more columns instead of expanding the height of its parent and causing a scrollbar.
From what I've seen with the Chrome and Opera implementations for Flexbox, a flex-direction of column requires restricting the height of the element, otherwise it will continue expanding vertically. It doesn't have to be a fixed value, it can be a percentage.
That said, the layout you want for your .group elements can also be achieved by using the CSS Columns module. The flow of the elements will be similar to that of the flexbox column orientation, but it will create columns as long as there's enough width for them, regardless of how long the document is.
http://jsfiddle.net/Yht4V/8/ (you'll have to excuse the lack of prefixes)
html {
height: 100%;
}
body {
height: 100%;
display: flex;
flex-flow: column nowrap;
}
h1 {
padding: 1em;
}
#content {
padding: 10px;
background-color: #eee;
display: flex;
flex-grow: 1;
}
#content > .group {
margin: 10px;
padding: 10px;
border: 1px solid #cfcfcf;
background-color: #ddd;
flex: 1 1 auto;
}
#content > .group:first-child {
columns: 10em;
flex-grow: 2;
}
#content > .group .item {
margin: 10px;
padding: 10px;
background-color: #aaa;
break-inside: avoid;
}
#content > .group .item:first-child {
margin-top: 0;
}
Leaving it as a bunch of nested flexboxes, this was about as close as I could get it:
http://jsfiddle.net/Yht4V/9/ (again, no prefixes)
html {
height: 100%;
}
body {
height: 100%;
display: flex;
flex-flow: column nowrap;
}
h1 {
padding: 1em;
}
#content {
padding: 10px;
background-color: #eee;
display: flex;
flex: 1 1 auto;
height: 100%;
width: 100%;
}
#content > .group {
margin: 10px;
padding: 10px;
border: 1px solid #cfcfcf;
background-color: #ddd;
display: flex;
flex-flow: column wrap;
flex: 1 1 30%;
max-height: 100%;
}
#content > .group .item {
margin: 10px;
padding: 10px;
background-color: #aaa;
}
Replace the following in your css -
display: -webkit-flex;
to the following -
display: -webkit-box;
This worked very well for me :-)