I am trying to recreate the following layout with flexbox:
I am almost there layout wise, but I am getting some weird flex-wrap behaviour like this:
My css is as follows:
.parent {
display: flex;
justify-content: space-between;
.square-container {
width: calc(33% - 1.333px);
display: flex;
flex-wrap: wrap;
justify-content: space-between;
&:before {
content:'';
float:left;
padding-top:100%;
}
.small-square {
width: calc(50% - 2px);
height: calc(50% - 2px);
background: red;
flex-shrink: 0;
}
}
}
The html is as follows:
<div class="parent">
<div class="square-container">
<div class="small-square"></div>
<div class="small-square"></div>
<div class="small-square"></div>
<div class="small-square"></div>
</div>
<div class="square-container">
<div class="small-square"></div>
<div class="small-square"></div>
<div class="small-square"></div>
<div class="small-square"></div>
</div>
<div class="large-square"></div>
</div>
I feel that I am missing some important flexbox property here. Thank you for your help!
You can do it quite easily:
.flex {
display: flex;
flex-direction: column;
flex-wrap: wrap;
height: 210px;
justify-content: space-between;
width: 650px;
}
.small {
width: 100px;
height: 100px;
background: red;
}
.large {
width: 210px;
height: 210px;
background: red;
}
<div class="flex">
<div class="small"></div>
<div class="small"></div>
<div class="small"></div>
<div class="small"></div>
<div class="large"></div>
<div class="small"></div>
<div class="small"></div>
<div class="small"></div>
<div class="small"></div>
</div>
Update
Fully responsive with current html:
.parent {
width: 100%;
display: flex;
flex-direction: row;
justify-content: space-between;
}
.parent:after {
content: '';
display: block;
width: 0;
background: blue;
padding-top: 33.3333%;
}
.square-container {
width: calc(33.33333% - 5px);
flex-grow: 1;
display: flex;
flex-wrap: wrap;
flex-direction: row;
justify-content: space-between;
}
.small-square {
width: calc(50% - 5px);
height: calc(50% - 10px);
background: red;
}
.large-square {
margin: 0 10px 10px 10px;
flex-grow: 1;
width: 33.33333%;
background: red;
order: 2;
}
.square-container:first-child {
order: 1;
}
.square-container:nth-child(2n) {
order: 3;
}
<div class="parent">
<div class="square-container">
<div class="small-square"></div>
<div class="small-square"></div>
<div class="small-square"></div>
<div class="small-square"></div>
</div>
<div class="square-container">
<div class="small-square"></div>
<div class="small-square"></div>
<div class="small-square"></div>
<div class="small-square"></div>
</div>
<div class="large-square"></div>
</div>
No changes to the HTML:
.parent {
display: flex;
}
.square-container {
flex: 1;
display: flex;
justify-content: space-around;
align-content: space-between;
flex-wrap: wrap;
}
.small-square {
flex: 0 0 45%;
height: 100px;
background-color: red;
}
.large-square {
flex: 1;
height: 210px;
margin: 0 5px;
background-color: red;
}
.square-container:nth-child(2) {
order: 1;
}
<div class="parent">
<div class="square-container">
<div class="small-square"></div>
<div class="small-square"></div>
<div class="small-square"></div>
<div class="small-square"></div>
</div>
<div class="square-container">
<div class="small-square"></div>
<div class="small-square"></div>
<div class="small-square"></div>
<div class="small-square"></div>
</div>
<div class="large-square"></div>
</div>
jsFiddle
Related
I wonder if there is a flex-way to create fluid like behaviour of the parent container: by moving red boxes n1 and n2 to the left of the blue box n3 and as a result moving the red box n3 to the left side of the container
.parent {
display: flex;
width: 525px;
flex-wrap: wrap;
background-color: green;
}
.child {
flex-wrap: wrap;
display: flex;
}
.box {
width: 100px;
height: 100px;
margin: 5px;
}
.blue .box {
background-color: blue;
}
.red .box {
background-color: red;
}
<div class='parent'>
<div class='child blue'>
<div class='box'>1</div>
<div class='box'>2</div>
<div class='box'>3</div>
</div>
<div class='child red'>
<div class='box'>1</div>
<div class='box'>2</div>
<div class='box'>3</div>
</div>
</div>
You can use display:contents (https://caniuse.com/#feat=css-display-contents) on .child elements making the boxes behaving as they was child of the .parent element.
.parent {
display: flex;
width: 555px;
flex-wrap: wrap;
background-color: green;
}
.child {
flex-wrap: wrap;
display: flex;
display:contents
}
.box {
width: 100px;
height: 100px;
margin: 5px;
}
.blue .box {
background-color: blue;
}
.red .box {
background-color: red;
}
<div class='parent'>
<div class='child blue'>
<div class='box'>1</div>
<div class='box'>2</div>
<div class='box'>3</div>
</div>
<div class='child red'>
<div class='box'>1</div>
<div class='box'>2</div>
<div class='box'>3</div>
</div>
</div>
I want to achieve the following scenario with flexbox
the green element is a text element and the width is flexible. The blue elements should have 100% of the remaining width beside the green element.
My current solution looks like this:
<div class="container">
<span class="title">title</span>
<div class="fullwidth"></div>
<div class="fullwidth"></div>
<div class="fullwidth"></div>
</div>
and the css:
.container {
display: flex;
align-items: center;
flex-wrap: wrap;
background-color: #EAEBEF;
.title {
padding: 20px;
background-color: #48CFAE;
}
.fullwidth {
background-color: #87BDFF;
flex: 0 0 100%;
height: 60px;
margin: 10px 0;
}
}
But it looks currently like this
here is a codepen example
Without changing the HTML this can be managed with CSS-Grid as an alternative to flexbox.
.container {
display: grid;
grid-template-columns: max-content 1fr;
grid-gap: 1em;
background-color: #EAEBEF;
margin-bottom: 1em;
}
.title {
padding: 10px;
grid-row: 2;
background-color: #48CFAE;
}
.fullwidth {
grid-column: 2;
background-color: #87BDFF;
height: 40px;
}
<div class="container">
<div class="title">title</div>
<div class="fullwidth"></div>
<div class="fullwidth"></div>
<div class="fullwidth"></div>
</div>
<div class="container">
<div class="title">Longer title</div>
<div class="fullwidth"></div>
<div class="fullwidth"></div>
<div class="fullwidth"></div>
</div>
Try this HTML and CSS markup. Basically You need to keep the left side in one div and the right side elements in another div.
.container {
display: flex;
align-items: center;
flex-wrap: nowrap;
background-color: #eaebef;
}
.container .title {
padding: 20px;
background-color: #48cfae;
}
.container .div1 {
width: 20%;
}
.container .div2 {
width: 80%;
}
.container .fullwidth {
background-color: #87bdff;
height: 60px;
margin: 10px 0;
}
<div class="container">
<div class="div1">
<span class="title">title</span>
</div>
<div class="div2">
<div class="fullwidth"></div>
<div class="fullwidth"></div>
<div class="fullwidth"></div>
</div>
</div>
See code below:
You have to warp fullwidth in div and set width to this div
also set width and margin to title
.container {
display: flex;
align-items: center;
flex-wrap: wrap;
background-color: #EAEBEF;
}
.title {
width: 20%;
padding: 20px;
background-color: #48CFAE;
margin-left: 15px;
}
.fullwidth {
background-color: #87BDFF;
flex: 0 0 100%;
height: 60px;
margin: 10px 0;
}
.a{
margin: 50px;
width: 50%;
}
<div class="container">
<span class="title">title</span>
<div class="a">
<div class="fullwidth"></div>
<div class="fullwidth"></div>
<div class="fullwidth"></div>
</div>
</div>
If you want to achive this without change your html but only your less, try this:
.container {
display: flex;
flex-direction: row;
align-items: center;
flex-wrap: wrap;
background-color: #EAEBEF;
justify-content: flex-end;
.title {
padding: 20px;
background-color: #48CFAE;
margin-right: 20px;
flex-grow: 1
}
.fullwidth {
background-color: #87BDFF;
height: 60px;
margin: 10px 0;
width: 80%;
}
}
your codepen edited
I have such code:
https://plnkr.co/edit/ZAEzfAOCO0ZcSq2OR4Lp?p=preview
but this isn't working in ie, until I add height:0 (it's a very bad idea on parent element)
<body>
<div class="container">
<div class="container-item container-item-1"></div>
<div class="container-item container-item-2"></div>
<div class="container-item container-item-3"></div>
</div>
</body>
body, html {
min-height: 100%;
height: 100%;
}
.container {
width: 100%;
min-height: calc(100% - 80px);
margin: 30px;
padding: 20px;
border: 1px solid gray;
border-radius: 16px;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
-webkit-box-flex: 1;
-ms-flex: 1;
flex: 1;
}
.container-item {
-webkit-box-flex: 1;
-ms-flex: 1;
flex: 1;
content: "someText";
border-bottom: 1px solid #cecece;
}
.container-item-1 {
background-color: red;
}
.container-item-2 {
background-color: orange;
}
.container-item-3 {
background-color: green;
}
everything works fine in chrome and ff
(my parents should expand to fit parent)
Important!
I need a flexible solution, my code can have a lot of nested div's (not a constant value) between body and content divs.
for example:
<body>
<div>
<div>
<div class="container">
<div class="container-item container-item-1"></div>
<div class="container-item container-item-2"></div>
<div class="container-item container-item-3"></div>
</div>
</div>
</div>
</body>
or
<body>
<div>
<h3>text</h3>
<div class="container">
<div class="container-item container-item-1"></div>
<div class="container-item container-item-2"></div>
<div class="container-item container-item-3"></div>
</div>
</div>
</body>
If you have an unknown or nested markup before the container, you could add an extra wrapper within it (here inner), to overcome IE's min-height bug.
Fiddle sample 1 -- Fiddle sample 2
Stack snippet sample 1
html, body {
margin: 0;
}
.container {
display: flex;
}
.container .inner {
width: 100%;
min-height: calc(100vh - 100px);
margin: 30px;
padding: 20px;
border: 1px solid gray;
border-radius: 16px;
display: flex;
flex-direction: column;
}
.container-item {
flex-grow: 1;
border: 1px solid #cecece;
}
.container-item-1 {
background-color: red;
}
.container-item-2 {
background-color: orange;
}
.container-item-3 {
background-color: green;
}
<div>
<h3>text</h3>
<div class="container">
<div class="inner">
<div class="container-item container-item-1">
</div>
<div class="container-item container-item-2">
</div>
<div class="container-item container-item-3">
</div>
</div>
</div>
</div>
Stack snippet sample 2
html, body {
margin: 0;
}
.container {
display: flex;
}
.container .inner {
width: 100%;
min-height: calc(100vh - 100px);
margin: 30px;
padding: 20px;
border: 1px solid gray;
border-radius: 16px;
display: flex;
flex-direction: column;
}
.container-item {
flex-grow: 1;
border: 1px solid #cecece;
}
.container-item-1 {
background-color: red;
}
.container-item-2 {
background-color: orange;
}
.container-item-3 {
background-color: green;
}
<div>
<div>
<div class="container">
<div class="inner">
<div class="container-item container-item-1">
</div>
<div class="container-item container-item-2">
</div>
<div class="container-item container-item-3">
</div>
</div>
</div>
</div>
</div>
I have container with div elemenents
.container {
display: flex;
justify-content: space-between;
}
How to make one element positioned at the center on this block, and others to be space-between.
.container {
display: flex;
justify-content: space-between;
}
.container div {
height: 50px;
}
.one,
.four,
.seven {
background-color: red;
width: 200px;
}
.two,
.six {
background-color: green;
width: 100px;
}
.three,
.five {
background-color: yellow;
width: 150px;
}
.center {
width: 300px;
background-color: black;
}
<div class="container">
<div class="one"></div>
<div class="two"></div>
<div class="three"></div>
<div class="center"></div>
<div class="four"></div>
<div class="five"></div>
<div class="six"></div>
<div class="seven"></div>
</div>
jsFiddle
Based on how dynamic you want this to be, here is a suggestion where the items on the left and on the right side of the center element are wrapped.
The left and right get 50% each minus the width of the center (150px for each side), which will put the center in the middle.
Updated fiddle
Stack snippet
.container {
display: flex;
justify-content: space-between;
}
.container div {
height: 50px;
}
.left, .right {
display: flex;
justify-content: space-between;
flex-basis: calc(50% - 150px);
}
.one,
.four,
.seven {
background-color: red;
flex-basis: 200px;
}
.two,
.six {
background-color: green;
flex-basis: 100px;
}
.three,
.five {
background-color: yellow;
flex-basis: 150px;
}
.center {
flex-basis: 300px;
background-color: black;
}
<div class="container">
<div class="left">
<div class="one">
</div>
<div class="two">
</div>
<div class="three">
</div>
</div>
<div class="center">
</div>
<div class="right">
<div class="four">
</div>
<div class="five">
</div>
<div class="six">
</div>
<div class="seven">
</div>
</div>
</div>
By adding a pseudo to each side wrapper, we can also make it behave similar to how space-between work without the wrappers (though still with center centered).
In this fiddle demo (and below Stack snippet) I changed the width's so one easier can see how it behaves in full screen.
.container {
display: flex;
justify-content: space-between;
}
.container div {
height: 50px;
}
.left, .right {
display: flex;
justify-content: space-between;
flex-basis: calc(50% - 100px);
}
.left::after,
.right::before {
content: '';
}
.one,
.four,
.seven {
background-color: red;
flex-basis: 125px;
}
.two,
.six {
background-color: green;
flex-basis: 25px;
}
.three,
.five {
background-color: yellow;
flex-basis: 75px;
}
.center {
flex-basis: 200px;
background-color: black;
}
<div class="container">
<div class="left">
<div class="one">
</div>
<div class="two">
</div>
<div class="three">
</div>
</div>
<div class="center">
</div>
<div class="right">
<div class="four">
</div>
<div class="five">
</div>
<div class="six">
</div>
<div class="seven">
</div>
</div>
</div>
I'm trying to create this: http://imgur.com/G2TpjDR
What I have: https://jsfiddle.net/tzayffsv/
I use flexbox with params: flex-direction: column, flex-wrap: wrap. The Problem is that items going outside the screen when wrapping... Any ideas how to do this using flexbox (or mbe other ideas)? I don't look for solutions with javascript and positioning items as absolute..
<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 class="item">6</div>
</div>
This works. flex-flow: column wrap-reverse;
.box {
height:200px;
width:300px;
background:grey;
display: flex;
flex-flow: column wrap-reverse;
justify-content: center;
align-content: flex-start;
align-items: flex-end;
}
.item {
flex: 0 1 auto;
align-self: auto;
min-width: 0;
min-height: 40%;
border:1px solid black;
}
<div class="box">
<div class="item">A</div>
<div class="item">B</div>
<div class="item">C</div>
</div>
This is not directly related to flexbox, you only need to set the direction of the text to be right-to-left. This can be easily achieved with
.container {
direction: rtl;
}
.container {
direction: rtl;
display: flex;
flex-direction: column;
flex-wrap: wrap;
position: absolute;
top: 0;
right: 50px;
height: 600px;
}
.item {
width: 200px;
height: 140px;
line-height: 60px;
background-color: #618ae4;
margin-top: 10px;
margin-left: 10px;
text-align: center;
font-weight: bold;
font-size: 30px;
color: #fff;
}
<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 class="item">6</div>
</div>