i'm working with flexbox with justify-content: space-between & flex-wrap: wrap,
so each item separates as far as possible.
But i want to if the container space is not sufficient, the item(s) are wrapped to the next row
but keep the items placement symmetrical (centered).
See the illustration below:
Update: the alone box is might in somewhere row:
It works for space-around & space-evenly but not for space-between.
Any idea for making this behavior? Maybe using display: grid can archive similar result.
html:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="styles.css">
</head>
<body>
<p>symmetrical => works:<p/>
<div class="container long">
<div></div>
<div></div>
<div></div>
</div>
<hr />
<p>non symmetrical => fail:<p/>
<div class="container short">
<div></div>
<div></div>
<div></div>
</div>
<hr />
<p>symmetrical => works:<p/>
<div class="container med">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<hr />
<p>non symmetrical => fail:<p/>
<div class="container med">
<div></div>
<div></div>
<div></div>
<div class="weird"></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
</body>
</html>
css:
.container>*{
inline-size: 100px;
block-size: 50px;
background: blue;
}
.container {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
row-gap: 10px;
background: orange;
margin: 20px;
}
.long {
inline-size: 400px;
}
.short {
inline-size: 250px;
}
.med {
inline-size: 350px;
}
.weird {
inline-size: 300px;
}
See the sandbox here
You can achieve this by putting an extra css rule on the last child of .short container, but this is a hack. space-between is expected to work like this.
.short div:last-child {margin:0 auto;}
Related
Is it possible to shift all 2nd/even grid colums as a whole like in the image using CSS grid?
My current css code situation is very simple, it looks like this:
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 24px;
I am trying to achive something that looks like the following image:
You can use the :nth-child() pseudo class to achieve this. This is how I approached it:
<div class="container">
<div class="cards">
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
<div class="card"></div>
</div>
</div>
.container{
max-width: 900px;
margin: 0 auto;
height: auto;
}
.cards{
display: grid;
place-items: center;
grid-template-columns: repeat(4,1fr);
gap: 5px;
}
.card{
width: 200px;
height: 250px;
border: 3px solid black;
}
.card:nth-child(2n-2){
position: relative;
top: 100px;
}
/* or use margin */
/*
.card:nth-child(2n-2){
margin-top: 100px;
}
*/
Here is the codepen link: https://codepen.io/glenhug/pen/QWrWXJY
Also this is post had a nice explanation: How to target a specific column or row in CSS Grid Layout?
This might do the trick.
.grid-container {
width: min-content;
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-gap: 10px;
}
.grid-container > div {
width: 50px;
height: 50px;
border: 1px solid black;
}
.grid-container div:nth-child(2n) {
position: relative;
top: 15px;
}
<div class='grid-container'>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
Not with CSS grid but combining inline-block, float and shape-outside you can do it and it will be responsive and works with any element.
Find all the details in my article: https://css-tricks.com/hexagons-and-beyond-flexible-responsive-grid-patterns-sans-media-queries/
Here is a demo:
.main {
display:flex;
--s: 100px; /* size */
--r: 1; /* ratio */
--mv: 4px; /* margin */
--vc: calc(var(--s) * var(--r) * .5);
--mh: calc(var(--mv) + var(--s)/2);
--f: calc(2*var(--s)*var(--r) + 4*var(--mv) - 2*var(--vc) - 2px);
}
.container {
font-size: 0; /*disable white space between inline block element */
}
.container div {
width: var(--s);
margin: var(--mv) var(--mh);
height: calc(var(--s)*var(--r));
display: inline-block;
font-size: initial;
background: red;
margin-bottom: calc(var(--mv) - var(--vc));
}
.container div:nth-child(odd) {
background: green;
}
.container::before {
content: "";
width: calc(var(--s)/2 + var(--mh));
float: left;
height: 135%;
shape-outside: repeating-linear-gradient(
#0000 0 calc(var(--f) - 2px),
#000 0 var(--f));
}
<div class="main">
<div class="container">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
</div>
I have a 2 col 2 row grid with 3 of the items/cells occupied.
I would like it to appear like:
A
B
C
I know I can use grid-column: 2; on the 3rd item but that doesn't really help me if I have a dynamic number of rows and items.
I'm also aware of direction: rtl; on the wrapping element, but this obviously reverses the order which is not idea, eg:
B
A
C
I've tried justify-content: right/end/flex-end but no luck there either.
I am aware I can achieve the above with flex-box but was just curious if there was a way with CSS grid?
Since you only have two columns you can write a specific selector and target the last item
.box {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 5px;
border: 1px solid;
margin: 10px;
}
.box div {
height: 50px;
background: red;
}
/* place the last item at last column */
.box div:last-child {
grid-column-end: -1;
}
<div class="box">
<div></div>
<div></div>
</div>
<div class="box">
<div></div>
<div></div>
<div></div>
</div>
<div class="box">
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<div class="box">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
I have a 3x3 grid with flex-box concept, inside of each cell it has another 3x3 grid.
I was trying to put an Overlay over the Inner grid in one cell, but I didn't find how to do it.
I found some examples like this one
Overlay / hover a div in flexbox container div
but it don't work in nested flex-box, or I don't know how to set them up.
here is the html, the grid has just two cell to take up less space, it actually is done with JQuery but for the example lets use only 2.
.Region{
position: absolute;
top: 10px;
left: 10px;
width: 500px;
height: 500px;
border: 5px double black;
display: flex;
}
.FlexContainer{
display: flex;
flex-direction: column;
flex-grow: 1;
}
.FlexContainer > div{
flex-grow: 1;
flex-basis: 0;
border: 3px solid blue;
display: flex;
flex-direction: row;
margin: 5px;
}
.FlexContainer > div > div{
flex-grow: 1;
flex-basis: 0;
border: 1px solid red;
margin: 3px;
display:flex;
flex-direction: row;
}
.Overlay{
position: absolute;
width: 100%;
height: 100%;
background-color: rgba(013, 130, 230, 0.5);
cursor: not-allowed;
}
<div class="Region">
<div class="FlexContainer">
<div>
<div>
<div class="FlexContainer">
<div>
<div></div>
<div></div>
<div></div>
</div>
<div>
<div></div>
<div></div>
<div></div>
</div>
<div>
<div></div>
<div></div>
<div></div>
</div>
</div>
</div>
<div></div>
<div></div>
</div>
<div>
<div></div>
<div></div>
<div></div>
</div>
<div>
<div>
<div class="FlexContainer">
<div class="Overlay"></div>
<div>
<div>
</div>
<div></div>
<div></div>
</div>
<div>
<div></div>
<div></div>
<div></div>
</div>
<div>
<div></div>
<div></div>
<div></div>
</div>
</div>
</div>
<div></div>
<div></div>
</div>
</div>
</div>
I have tried with the Overlay inside and outside the Inner FlexContainer, but didn't work.
Finally got it to work, indeed the parent container must have relative position for it to work, so there is two change, one in the FlexContainer and other in the Overlay
.FlexContainer{
position:relative; <-- ADD THIS
display: flex;
flex-direction: column;
flex-grow: 1;
}
.FlexContainer .Overlay {
position: absolute;
top: 0px;
left: 0px;
margin: 0px;
border: 0px;
width: 100%;
height: 100%;
background-color: rgba(013, 130, 230, 0.5);
cursor: not-allowed;
}
Code Pen solution https://codepen.io/anon/pen/dKaXqg
Credits to user Pogany from the css-tricks web site
CSS-TRICKS thread: https://css-tricks.com/forums/topic/add-and-overlay-div-in-nested-flex-box-container/#post-273437
I have been busting my butt, just to lineup my pics in css boxes
here is the code(and the screen shop of result) its in the blade(laravel5) :
Here is my code:
#foreach($users as $user)
<div style="width: 200px;height: 200px;background-color: gray;text-align: center; float: right; margin-bottom: 22px;
margin-right: 17px;
">
<img src="{{$user->getavatar()}}" alt="{!!$user->username!!}" >
<strong>{!!$user->username!!}</strong>
</div>
<br>
#endforeach
Let's try another method using display instead of using float, and remove the <br>. How does this look?
<div style="width: 200px; height: 200px; text-align: center; display: inline-block; vertical-align: top; margin: 0 10px 22px;">
<img src="{{$user->getavatar()}}" alt="{!!$user->username!!}" >
<strong>{!!$user->username!!}</strong>
</div>
Remove the <br> tag at the end of the foreach loop.
You can put all your foreach loop divs inside a div container and use display:flex. It is better not to use css inline with yout html code(It looks heavy), also <br> is not needed there.
Please review this one:
#container {
display: flex;
flex-wrap: wrap;
padding: 50px;
}
#container div {
height: 200px;
width: 200px; /*or using calc(100% / 6);*/
background-color: gray;
text-align: center;
flex-grow: 0;
margin-bottom: 22px;
margin-right: 17px;
}
<div id="container">
<!--sample result of your foreach loop-->
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<!--end foreach-->
</div>
This keeps coming up on certain projects and I wanted to see if anyone may have a better solution.
Essentially, I'm trying to have a group of div elements of which all have an equal amount of spacing between them but not around. The snippet below is an example of what I'm looking for, my hope is someone may have a cleaner solution.
My question here is if anyone has a better solution that may use less css or less HTML elements. The important things to maintain:
Localization compliant - Since we aren't using margin left or right there aren't any weird localization issues in rtl
Alignment - It shouldn't size to the whole window if it doesn't need to but it should wrap if needed. (see example)
Spacing - Should be a fixed amount of space between the elements
If you have any ideas I'd love to hear them!
body {
background-color: black;
padding: 30px;
}
.inner {
overflow: hidden;
margin: 20px 0px;
}
.innerMargin {
background-color: white;
display: flex;
flex-direction: row;
flex-wrap: wrap;
margin: -10px;
}
.innerMargin > div {
flex: 0 0 20px;
background-color: red;
margin: 10px;
height: 20px;
width: 20px;
}
.fixedWidth {
width: 180px;
}
<div class="inner">
<div class="innerMargin">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
</div>
<div class="inner fixedWidth">
<div class="innerMargin">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
</div>
I think it should be noted this is trivial with CSS Grid.
body {
background-color: #000;
}
.container {
display: grid;
grid-template: 20px/repeat(auto-fit, 20px);
grid-gap: 20px;
background-color: #FFF;
margin: 20px;
}
.container div {
background-color: red;
}
.fixed-width {
width: 180px;
}
.container > div {
background-color: red;
}
<div class="container">
<div>
</div>
<div>
</div>
<div>
</div>
<div>
</div>
<div>
</div>
<div>
</div>
<div>
</div>
<div>
</div>
<div>
</div>
<div>
</div>
</div>
<div class="container fixed-width">
<div>
</div>
<div>
</div>
<div>
</div>
<div>
</div>
<div>
</div>
<div>
</div>
<div>
</div>
<div>
</div>
<div>
</div>
<div>
</div>
<div>
</div>
<div>
</div>
<div>
</div>
<div>
</div>
<div>
</div>
</div>
CodePen here
Necromancing, but I'd like to add that a pretty quick way to accomplish this if you're just dealing with a row/column is to use a last-child pseudoselector to override margin to 0. Like so:
.column-item {
width: 5px;
height: 5px;
background-color: red;
margin-bottom: 20px;
}
.column-item:last-child {
margin: 0;
}
beginning
<div id="column">
<div class="column-item"></div>
<div class="column-item"></div>
<div class="column-item"></div>
<div class="column-item"></div>
<div class="column-item"></div>
<div class="column-item"></div>
<div class="column-item"></div>
</div>
end
If you know you will always have 5 boxes in the fixedwidth box, you could do something like:
HTML (Slim)
.container
- 5.times do
.box
.container.container--thinner
- 15.times do
.box
CSS (SCSS)
$width : 36;
body {background-color: #000;}
.container {
display:flex;
flex-wrap: wrap;
background-color: white;
margin-bottom: 2em;
width: $width + em;
.box {
width: 2em;
height: 2em;
margin-right: 2em;
background-color: red;
}
&--thinner {
justify-content: space-between;
width: $width/2 + em;
.box {
margin-bottom: 2em;
&:nth-of-type(5n) {
margin-right: 0;
}
}
}
}
Here's a Codepen