Can I accomplish this grid layout with flexbox? To have the first element take up 2 rows height and then continue after it?
Check image.
You can achive it by dividing this layout in 2 columns while the 2nd column will have a nested flexbox layout as well.
HTML Structure:
<div class="container">
<div class="col box1">1</div>
<div class="col col2">
<div class="box2">2</div>
<div class="box3">3</div>
<div class="box4">4</div>
<div class="box5">5</div>
</div>
</div>
Necessary Styles:
.container {
min-height: 100vh;
display: flex;
}
.col {
flex-grow: 1;
color: #fff;
}
.col2 {
flex-wrap: wrap;
display: flex;
}
.col2 > div {
flex-basis: 50%;
flex-grow: 1;
}
.box1 {
display: flex;
}
* {box-sizing: border-box;}
body {
margin: 0;
}
.container {
min-height: 100vh;
display: flex;
}
.col {
flex-grow: 1;
color: #fff;
}
.col2 {
flex-wrap: wrap;
display: flex;
}
.col2 > div {
flex-basis: 50%;
padding: 10px;
flex-grow: 1;
}
.box1 {
background: brown;
padding: 10px;
display: flex;
}
.box2 {
background: pink;
}
.box3 {
background: black;
}
.box4 {
background: yellow;
}
.box5 {
background: royalblue;
}
<div class="container">
<div class="col box1">1</div>
<div class="col col2">
<div class="box2">2</div>
<div class="box3">3</div>
<div class="box4">4</div>
<div class="box5">5</div>
</div>
</div>
You can use this HTML structure but you need to set fixed height on parent div. Then you just use flex-direction: column and flex-wrap: wrap.
* {
box-sizing: border-box;
}
.content {
height: 100vh;
display: flex;
flex-direction: column;
flex-wrap: wrap;
}
div div:first-child {
flex: 0 0 100%;
width: 50%;
background: #880015;
}
div div:not(:first-child) {
width: 25%;
flex: 0 0 50%;
border: 1px solid black;
}
<div class="content">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
<div class="box">5</div>
</div>
Related
Hi I am trying to build this layout with flexbox.I provided my current code because i dont know how to move further.Even i posted image how iut should look like under the code.I tried everything but i cant achieve these result. Columns 2,3,5,6,7,8 must be same size. Im new to flex box and i really want to achieve this goal. Thanks for any help.
.tall {
height: 300px;
}
.content {
display: flex;
height: 100%;
}
.left {
display: flex;
flex-direction: column;
flex: 1;
}
.box {
padding-bottom: 50px;
}
.right3collumns {
display: flex;
flex-direction: column;
flex: 2;
}
.box2:nth-child(1) {
background-color: teal;
}
.box2:nth-child(2) {
background-color: red;
}
.box2:nth-child(3) {
background-color: blue;
}
.right {
flex: 2;
background: #22B14C;
}
.right2 {
display: flex;
flex-basis: 200px;
flex-direction: column;
background-color: red;
}
.right2small {
flex-basis: 100px;
background-color: turquoise;
}
.box:nth-child(1) {
background: #ED1C24;
}
.box:nth-child(2) {
background: #00A2E8;
}
.box:nth-child(3) {
background: #FFAEC9;
}
<div class="content">
<div class="right">
<img src="assets/group.png" alt="group">
</div>
<div class="left">
<div class="box">Small DIv</div>
<div class="box">Small DIv</div>
</div>
<div class="right2">bigger</div>
<div class="right2small">smaller</div>
<div class="right3collumns">
<div class="box2">Small DIv</div>
<div class="box2">Small DIv</div>
<div class="box2">Small DIv</div>
</div>
</div>
Here is one way of achieving the layout, I strongly advise, if you can, to use CSS Grid instead.
.grid {
display: flex;
flex: 1;
}
.grid--col {
flex-direction: column;
}
.grid__item {
display: flex;
justify-content: center;
align-items: center;
flex: 1;
border: 1px solid #ddd;
}
.grid__item--x2 {
flex: 2;
}
.grid--main {
background: #f5f5f5;
border: 1px dashed #999;
max-width: 960px;
margin: 50px auto;
}
<div class="grid grid--main">
<div class="grid__item">1</div>
<div class="grid__item grid__item--x2">
<div class="grid grid--col">
<div class="grid">
<div class="grid__item">2</div>
<div class="grid__item grid__item--x2">4</div>
<div class="grid__item">8</div>
</div>
<div class="grid">
<div class="grid__item">3</div>
<div class="grid__item">5</div>
<div class="grid__item">6</div>
<div class="grid__item">7</div>
</div>
</div>
</div>
</div>
You can modify the CSS/SCSS code to change the layout for different breakpoints using the CSS #media rules.
For example, you can have everything stacked, when the viewport is less than or equal to 960px.
#media only screen and (max-width: 960px) {
.grid {
flex-direction: column;
}
}
.grid {
display: flex;
flex: 1;
}
.grid--col {
flex-direction: column;
}
.grid__item {
display: flex;
justify-content: center;
align-items: center;
flex: 1;
border: 1px solid #ddd;
}
.grid__item--x2 {
flex: 2;
}
.grid--main {
background: #f5f5f5;
border: 1px dashed #999;
max-width: 960px;
margin: 50px auto;
}
#media only screen and (max-width: 960px) {
.grid {
flex-direction: column;
}
}
<div class="grid grid--main">
<div class="grid__item">1</div>
<div class="grid__item grid__item--x2">
<div class="grid grid--col">
<div class="grid">
<div class="grid__item">2</div>
<div class="grid__item grid__item--x2">4</div>
<div class="grid__item">8</div>
</div>
<div class="grid">
<div class="grid__item">3</div>
<div class="grid__item">5</div>
<div class="grid__item">6</div>
<div class="grid__item">7</div>
</div>
</div>
</div>
</div>
How can I increase the height of a row in flex (the div that contains has the class "row")? I have one row with two columns.
.body2 {
display: flex;
}
.row {
display: flex;
flex-direction: row;
flex-wrap: wrap;
width: 100%;
}
.column {
display: flex;
flex-direction: column;
flex-basis: 100%;
flex: 1;
}
.blue-column {
background-color: blue;
height: 100px;
}
.green-column {
background-color: green;
height: 100px;
}
<section class="body2">
<div class='row'>
<div class='column'>
<div class='blue-column'>
Some Text in Column One
</div>
</div>
<div class='column'>
<div class='green-column'>
Some Text in Column Two
</div>
</div>
</div>
</section>
How can I increase the height of that row? I already tried height:something in .row but it doesn't work
If you set a height on the container, the height will apply to the container, but not necessarily to the content of the container, so it may not look like you've added height.
In this example, a height is added to the container, as illustrated with the red border:
.body2 {
display: flex;
}
.row {
display: flex;
flex: 1;
height: 150px;
border: 1px dashed red;
}
.column {
display: flex;
flex-direction: column;
flex-basis: 100%;
flex: 1;
}
.blue-column {
background-color: aqua;
height: 100px;
}
.green-column {
background-color: lightgreen;
height: 100px;
}
<section class="body2">
<div class='row'>
<div class='column'>
<div class='blue-column'>
Some Text in Column One
</div>
</div>
<div class='column'>
<div class='green-column'>
Some Text in Column Two
</div>
</div>
</div>
</section>
If you want to add height to the descendants, use height or flex-basis (since the nested flex container is in column-direction).
.body2 {
display: flex;
}
.row {
display: flex;
flex: 1;
height: 150px;
border: 1px dashed red;
}
.column {
display: flex;
flex-direction: column;
flex-basis: 100%;
flex: 1;
}
.blue-column {
background-color: aqua;
height: 75px;
}
.green-column {
background-color: lightgreen;
flex-basis: 125px;
}
<section class="body2">
<div class='row'>
<div class='column'>
<div class='blue-column'>
Some Text in Column One
</div>
</div>
<div class='column'>
<div class='green-column'>
Some Text in Column Two
</div>
</div>
</div>
</section>
If you want the descendants to take full height, use flex: 1 instead of an explicit height.
.body2 {
display: flex;
}
.row {
display: flex;
flex: 1;
height: 150px;
border: 1px dashed red;
}
.column {
display: flex;
flex-direction: column;
flex-basis: 100%;
flex: 1;
}
.blue-column {
background-color: aqua;
/* height: 75px; */
flex: 1;
}
.green-column {
background-color: lightgreen;
/* flex-basis: 125px; */
flex: 1;
}
<section class="body2">
<div class='row'>
<div class='column'>
<div class='blue-column'>
Some Text in Column One
</div>
</div>
<div class='column'>
<div class='green-column'>
Some Text in Column Two
</div>
</div>
</div>
</section>
I have a layout that is mainly divided into 3 parts and the middle one should take a full height. And it does.
However, I need an additional div which will play a role of the backdrop and here the problem comes. The child doesn't want to take 100% height.
Here .body is a div that is being stretched when there is not enough content and .bg-gray is the one I want to take its parent full height.
Is there a way achieve this without using relative + absolute positioning?
Also, I'm looking for the answer to my question: why is this happening that way.
html, body {
padding: 0;
margin: 0;
}
.container {
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: stretch;
}
.header {
height: 50px;
background-color: #e6e6e6;
}
.footer {
height: 50px;
background-color: #aaa444;
}
.body {
flex: 1;
}
.bg-gray {
background-color: #eee;
min-height: 100%;
flex: 1;
}
<div class="container">
<div class="header">
</div>
<div class="body">
<div class="bg-gray">
<div>
asdasd
</div>
</div>
</div>
<div class="footer">
</div>
</div>
Apply flexbox to the .body div.
.body {
flex: 1;
display: flex;
flex-direction: column;
}
html,
body {
padding: 0;
margin: 0;
}
.container {
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: stretch;
}
.header {
height: 50px;
background-color: #e6e6e6;
}
.footer {
height: 50px;
background-color: #aaa444;
}
.body {
flex: 1;
display: flex;
flex-direction: column;
}
.bg-gray {
background-color: darkgrey;
min-height: 100%;
flex: 1;
}
.bg-gray div {
background: lightblue;
}
<div class="container">
<div class="header">
</div>
<div class="body">
<div class="bg-gray">
<div>
asdasd
</div>
</div>
</div>
<div class="footer">
</div>
</div>
I have the following flex layout. I need overflow to occur in div.stretchy. I would like div.stretchy to reach the boundary of the page and then overflow it's content. Per this stackoverflow post, I have tried many combinations of min-height: 0 and overflow: hidden, but div.stretchy will not shrink.
body {
margin: 0;
}
.page-wrapper {
display: flex;
height: 100vh;
width: 100vw;
overflow: hidden;
}
.sidebar {
background: blue;
flex: 0 0 40px;
}
.main {
background: green;
display: flex;
flex-direction: column;
flex: 1;
min-width: 0;
}
.topbar {
display: flex;
flex: 0 0 40px;
background-color: red;
}
.content {
display: flex;
overflow: auto;
}
.row {
display: flex;
}
.column {
display: flex;
flex-direction: column;
}
.grow {
flex-grow: 1;
}
.card {
height: 300px;
border: solid 1px;
min-width: 600px;
}
.card .row {
justify-content: space-between;
}
.wrapper {
padding: 16px;
height: fit-content;
}
.stats {
padding: 8px;
background-color: pink;
}
.overflow-hidden {
overflow: hidden;
}
.body .column {
background-color: indigo;
}
.wide-content {
background-color: yellow;
height: 50px;
width: 800px;
}
.block {
flex: none;
width: 300px;
height: 200px;
&:nth-of-type(odd) {
background: darken(green, 10%);
}
}
<div class="page-wrapper">
<div class="sidebar">sidebar</div>
<div class="main">
<div class="topbar">topbar</div>
<div class="content">
<div class="wrapper">
<div class="card column grow">
<div class="stats row">
<span>12345</span>
<span>12345</span>
<span>12345</span>
</div>
<div class="body row grow">
<div class="column">
<span>Dynamic Width Content</span>
</div>
<div class="stretchy column grow overflow-hidden">
<div class="wide-content grow"></div>
</div>
<div class="column">
<span>Dynamic Width Content</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
This is a tough battle. The enemy is cunning, deceitful and ruthless. I say we launch a massive carpet bombing campaign, showering the whole area with min size overrides. That should clear out 80% of the problem. Then we send in the ground troops to finish the job :-)
* {
min-width: 0 !important;
min-height: 0 !important;
}
.page-wrapper {
display: flex;
height: 100vh;
/* width: 100vw; */
/* overflow: hidden; */
}
.sidebar {
background: cornflowerblue;
/* flex: 0 0 40px; */
flex: 0 0 100px; /* changed for demo purposes */
}
.main {
background: lightgreen;
display: flex;
flex-direction: column;
flex: 1;
}
.topbar {
display: flex;
flex: 0 0 40px;
background-color: orangered;
}
.content {
display: flex;
/* overflow: auto; */
flex: 1; /* added */
}
.row {
display: flex;
}
.column {
display: flex;
flex-direction: column;
}
.grow {
flex-grow: 1;
}
.card {
/* height: 300px; */
border: solid 1px;
min-width: 600px;
}
.stretchy {
overflow: auto;
}
.card .row {
justify-content: space-between;
}
.wrapper {
padding: 16px;
/* height: fit-content; */
display: flex; /* added */
}
.stats {
padding: 8px;
background-color: pink;
}
.overflow-hidden {
/* overflow: hidden; */
}
.body .column {
background-color: violet;
}
.wide-content {
background-color: yellow;
height: 50px;
width: 800px;
}
body {
margin: 0;
}
/*
.block {
flex: none;
width: 300px;
height: 200px;
&:nth-of-type(odd) {
background: darken(green, 10%);
}
}
*/
<div class="page-wrapper">
<div class="sidebar">sidebar</div>
<div class="main">
<div class="topbar">topbar</div>
<div class="content">
<div class="wrapper">
<div class="card column grow">
<div class="stats row">
<span>12345</span>
<span>12345</span>
<span>12345</span>
</div>
<div class="body row grow">
<div class="column">
<span>Dynamic Width Content</span>
</div>
<div class="stretchy column grow overflow-hidden">
<div class="wide-content grow">test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br></div>
</div>
<div class="column">
<span>Dynamic Width Content</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
jsFiddle demo
I am a backend programmer by profession. But I have just started to learn flexbox and I want to hit the sky with flexbox.
So, I created a simplest design but which looks most complicated to me when creating it using flexbox.
Here is the design:
Guys, I am not able to figure out, how to use flexbox in such a case as there is no row or column. I don't know but is there anything like rowspan or colspan in flexbox that I can use to arrange these divs as shown in image above?
Here is my code:
HTML:
<div class="wrapper">
<div class="div-wrapper1">
<div class="inner-wrapper1">
<div class="div1"></div>
<div class="fake1"></div>
</div>
<div class="div2"></div>
</div>
<div class="div-wrapper2">
<div class="div3"></div>
<div class="inner-wrapper2">
<div class="fake2"></div>
<div class="div4"></div>
</div>
</div>
<div class="div-center"></div>
</div>
CSS:
.wrapper {
height: 200px;
width: 200px;
border: 1px solid black;
display: flex;
flex-direction: column;
}
.div-wrapper1 {
display: flex;
flex: 1;
}
.div-wrapper2 {
display: flex;
flex: 1
}
.inner-wrapper1 {
display: flex;
flex: 3;
flex-direction: column;
}
.div1 {
background-color: red;
display: flex;
flex: 3
}
.fake1 {
display: flex;
flex: 1
}
.div2 {
background-color: green;
display: flex;
flex: 2
}
.div3 {
background-color: blue;
display: flex;
flex: 2
}
.inner-wrapper2 {
display: flex;
flex: 3;
flex-direction: column;
}
.div4 {
background-color: yellow;
display: flex;
flex: 3
}
.fake2 {
display: flex;
flex: 1
}
.div-center {
background-color: black;
}
This is my output:
Here is the codepen
Maybe a solution is to simply add a negative margin to .div-wrapper1 and you will get the exact layout :
.wrapper {
height: 200px;
width: 200px;
border: 1px solid black;
display: flex;
flex-direction: column;
}
.div-wrapper1 {
display: flex;
flex: 1;
}
.div-wrapper2 {
display: flex;
flex: 1;
margin-top: -30px;
}
.div-wrapper3 {
display: flex;
flex: 1
}
.inner-wrapper1 {
display: flex;
flex: 3;
flex-direction: column;
}
.div1 {
background-color: red;
display: flex;
flex: 3
}
.fake1 {
display: flex;
flex: 1
}
.div2 {
background-color: green;
display: flex;
flex: 2
}
.div3 {
background-color: blue;
display: flex;
flex: 2
}
.inner-wrapper2 {
display: flex;
flex: 3;
flex-direction: column;
}
.div4 {
background-color: yellow;
display: flex;
flex: 3
}
.fake2 {
display: flex;
flex: 1
}
.div-center {
background-color: black;
}
<div class="wrapper">
<div class="div-wrapper1">
<div class="inner-wrapper1">
<div class="div1"></div>
<div class="fake1"></div>
</div>
<div class="div2"></div>
</div>
<div class="div-wrapper2">
<div class="div3"></div>
<div class="inner-wrapper2">
<div class="fake2"></div>
<div class="div4"></div>
</div>
</div>
<div class="div-center"></div>
</div>
And if you want here is another solution without any negative values and a content inside the white part (simply adjust height/width as you need) :
.first,
.second {
display: flex;
height: 100px;
width: 200px;
}
.first:before {
content: "";
background: red;
flex: 3;
}
.first:after {
content: "";
background: green;
flex: 2;
}
.second:before {
content: "";
background: blue;
flex: 2;
}
.second:after {
content: "";
background: yellow;
flex: 3;
}
.fake {
display: flex;
height: 20px;
width: 200px;
}
.fake a {
flex: 1;
text-align: center;
}
.fake:before {
content: "";
background: blue;
flex: 2;
}
.fake:after {
content: "";
background: green;
flex: 2;
}
<div class="first">
</div>
<div class="fake">
link
</div>
<div class="second">
</div>
Here is another solution by simply using multiple linear-gradient:
.box {
display: flex;
height: 220px;
width: 200px;
justify-content: center;
align-items: center;
background-image:linear-gradient(to right,red 66%,green 0%),
linear-gradient(to right,blue 33%,white 0%,white 66%,green 66%),
linear-gradient(to right,blue 33%,yellow 0%);
background-size:100% 100px,100% 20px,100% 100px;
background-position:top,center,bottom;
background-repeat:no-repeat;
}
<div class="box">
link
</div>