Can someone point me out how can I get a grid with Flexbox that is similar to the picture below. I have green column already done but have problem doing red section.
The problem is that I need to have an access to Flex Order just re-order it on mobile resolutions.
What I have already:
JSFiddle
HTML
* {
box-sizing: border-box;
}
main,
div {
display: flex;
padding: 1rem;
}
.desktop {
flex-direction: column;
flex-wrap: wrap;
height: 400px;
width: 100%;
}
.desktop div {
flex: 1;
}
div.orange {
background-color: #FFAD77;
width: 30%;
flex: 0 0 50%;
}
div.yellow {
flex: 0 0 100%;
width: 40%;
background-color: #FFE377;
}
div.purple {
flex: 0 0 50%;
width: 30%;
background-color: #FF77C8;
}
div.green {
background-color: green;
width: 30%;
}
#media(max-width: 480px) {
.desktop div {
flex: 1;
width: 100%;
}
div.orange {
order: 1;
}
div.yellow {
order: 2;
}
div.purple {
order: 3;
}
div.green {
order: 2;
}
}
<div class="desktop">
<div class="yellow">lorem1</div>
<div class="orange">lorem2</div>
<div class="purple">lorem3</div>
<div class="green">lorem4</div>
</div>
Please adjust the width, remove border and other things are per your requirement.
.redouter {
height: 200px;
border: 1px solid green;
display: flex;
flex-direction: column;
flex-wrap: wrap;
}
.red {
background: red;
width: 50%;
min-height: 20px;
text-align: center;
color: white;
font-size: 30px;
}
.one {
border: 2px solid white;
}
.two {
border: 5px solid white;
min-height: 150px;
}
.three {
min-height: 144px;
border: 3px solid white;
}
.four {
min-height: 10px;
border: 3px solid white;
}
#media(max-width: 480px) {
.redouter {
height: 100%;
}
.red {
flex: 1;
width: 100%;
}
.one {
order: 1;
}
.two {
order: 2;
}
.three {
order: 3;
}
.four {
order: 2;
}
}
.desktop {
display: flex;
flex-direction: column;
flex-wrap: wrap;
height: 300px;
width: 100%;
}
.yellow,
.green,
.purple,
.orange {
flex: 1;
}
div.orange {
background-color: #FFAD77;
width: 30%;
flex: 0 0 50%;
}
div.yellow {
flex: 0 0 100%;
width: 40%;
background-color: #FFE377;
}
div.purple {
flex: 0 0 50%;
width: 30%;
background-color: #FF77C8;
}
div.green {
background-color: green;
width: 30%;
}
#media(max-width: 480px) {
.desktop div {
flex: 1;
width: 100%;
}
div[orange] {
order: -1;
flex: 2;
}
div[yellow] {
flex: 5;
}
div[purple] {
flex: 1;
}
div[purple] {
flex: 6;
}
}
<div class="desktop">
<div class="yellow">lorem 1</div>
<div class="orange">lorem 2</div>
<div class="purple">lorem 3</div>
<div class="green">lorem 4</div>
</div>
<div class="redouter">
<div class="red one">1</div>
<div class="red two">2</div>
<div class="red three">3</div>
<div class="red four">4</div>
</div>
Related
I am building a carousel and I want the container to have overflow-x hidden and overflow-y visible.When the items are hovered
a transform: scale() is applied and I want them to overflow from the container but only on the y axis.
I tried to set the container to overflow-x: hidden and the child to overflow-y: visible but that didn't work.
:root {
--item-margin: 5px;
}
body {
display: flex;
justify-content: center;
align-items: center;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
position: relative;
width: 80vw;
margin-top: 60px;
overflow-x: hidden;
}
.wrapper {
height: 90%;
display: flex;
position: relative;
left: calc(-20% - 5px);
transition: .5s ease all;
overflow-y: visible;
}
.left-arrow,
.right-arrow {
display: flex;
cursor: pointer;
justify-content: center;
align-items: center;
font-size: 2rem;
color: white;
width: 50px;
height: 50px;
background: #ED4956;
border-radius: 50%;
transform: translate(-50%, -50%);
position: absolute;
}
.left-arrow {
left: 2%;
top: 50%;
}
.right-arrow {
left: 98%;
top: 50%;
}
.child {
display: inline-flex;
justify-content: center;
align-items: center;
flex-shrink: 0;
height: 250px;
width: 20%;
font-weight: bold;
font-size: 4rem;
transition: .4s ease transform;
}
.child {
margin-right: var(--item-margin);
}
.child:hover {
transform: scale(1.5);
}
.child1 {
background: green;
}
.child2 {
background: blue;
}
.child3 {
background: yellow;
}
.child4 {
background: navy;
}
.child5 {
background: red;
}
.child6 {
background: pink;
}
.child7 {
background: grey;
}
.child8 {
background: brown;
}
.child9 {
background: #ff80ed;
}
#media (max-width: 1400px) {
.child {
width: calc(25% - var(--item-margin));
}
.wrapper {
left: -25%;
}
}
<div class="container">
<div class="wrapper">
<div class="child child1">1</div>
<div class="child child2">2</div>
<div class="child child3">3</div>
<div class="child child4">4</div>
<div class="child child5">5</div>
<div class="child child6">6</div>
<div class="child child7">7</div>
<div class="child child8">8</div>
<div class="child child9">9</div>
</div>
<div class="left-arrow"> ← </div>
<div class="right-arrow"> → </div>
</div>
You just have to give the .container a height, for example: 100vh.
Because the tops of the children are cut off i recommend to use padding-top: 60px instead of margin-top: 60px.
Because of the changed height the arrows are wrong positioned. To adjust this i used a different top value: half of the childrens height plus the containers padding-top (125px + 60px).
Because the .wrapper doesn't need position: relative in this example i removed it. Maybe in your project it is necessary for the arrow function(s)...
Working example: (watch it in "Full page" mode to see it without scrollbars)
:root {
--item-margin: 5px;
}
body {
display: flex;
justify-content: center;
align-items: center;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
position: relative;
width: 80vw;
height: 100vh;
padding-top: 60px;
overflow-x: hidden;
}
.wrapper {
height: 90%;
display: flex;
left: calc(-20% - 5px);
transition: .5s ease all;
overflow-y: visible;
}
.left-arrow,
.right-arrow {
display: flex;
cursor: pointer;
justify-content: center;
align-items: center;
font-size: 2rem;
color: white;
width: 50px;
height: 50px;
background: #ED4956;
border-radius: 50%;
transform: translate(-50%, -50%);
position: absolute;
top: 185px;
}
.left-arrow {
left: 2%;
}
.right-arrow {
left: 98%;
}
.child {
display: inline-flex;
justify-content: center;
align-items: center;
flex-shrink: 0;
height: 250px;
width: 20%;
font-weight: bold;
font-size: 4rem;
transition: .4s ease transform;
}
.child {
margin-right: var(--item-margin);
}
.child:hover {
transform: scale(1.5);
}
.child1 {
background: green;
}
.child2 {
background: blue;
}
.child3 {
background: yellow;
}
.child4 {
background: navy;
}
.child5 {
background: red;
}
.child6 {
background: pink;
}
.child7 {
background: grey;
}
.child8 {
background: brown;
}
.child9 {
background: #ff80ed;
}
#media (max-width: 1400px) {
.child {
width: calc(25% - var(--item-margin));
}
.wrapper {
left: -25%;
}
}
<div class="container">
<div class="wrapper">
<div class="child child1">1</div>
<div class="child child2">2</div>
<div class="child child3">3</div>
<div class="child child4">4</div>
<div class="child child5">5</div>
<div class="child child6">6</div>
<div class="child child7">7</div>
<div class="child child8">8</div>
<div class="child child9">9</div>
</div>
<div class="left-arrow"> ← </div>
<div class="right-arrow"> → </div>
</div>
Because the arrows are still cut of you could add an extra container (here .parent) and add height, padding-top and overflow-x to it (instead of to the container).
Working example: (watch in "Full page" mode to see it without scrollbars)
:root {
--item-margin: 5px;
}
body {
display: flex;
justify-content: center;
align-items: center;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
position: relative;
width: 80vw;
}
.parent {
height: 100vh;
padding-top: 60px;
overflow-x: hidden;
}
.wrapper {
height: 90%;
display: flex;
left: calc(-20% - 5px);
transition: .5s ease all;
overflow: visible;
}
.left-arrow,
.right-arrow {
display: flex;
cursor: pointer;
justify-content: center;
align-items: center;
font-size: 2rem;
color: white;
width: 50px;
height: 50px;
background: #ED4956;
border-radius: 50%;
transform: translate(-50%, -50%);
position: absolute;
top: 185px;
}
.left-arrow {
left: 2%;
}
.right-arrow {
left: 98%;
}
.child {
display: inline-flex;
justify-content: center;
align-items: center;
flex-shrink: 0;
height: 250px;
width: 20%;
font-weight: bold;
font-size: 4rem;
transition: .4s ease transform;
}
.child {
margin-right: var(--item-margin);
}
.child:hover {
transform: scale(1.5);
}
.child1 {
background: green;
}
.child2 {
background: blue;
}
.child3 {
background: yellow;
}
.child4 {
background: navy;
}
.child5 {
background: red;
}
.child6 {
background: pink;
}
.child7 {
background: grey;
}
.child8 {
background: brown;
}
.child9 {
background: #ff80ed;
}
#media (max-width: 1400px) {
.child {
width: calc(25% - var(--item-margin));
}
.wrapper {
left: -25%;
}
}
<div class="container">
<div class="parent">
<div class="wrapper">
<div class="child child1">1</div>
<div class="child child2">2</div>
<div class="child child3">3</div>
<div class="child child4">4</div>
<div class="child child5">5</div>
<div class="child child6">6</div>
<div class="child child7">7</div>
<div class="child child8">8</div>
<div class="child child9">9</div>
</div>
</div>
<div class="left-arrow"> ← </div>
<div class="right-arrow"> → </div>
</div>
This question already has answers here:
Is it possible for flex items to align tightly to the items above them?
(5 answers)
Closed 4 years ago.
i'm trying to get to the layout from middle to left as shown in the picture.
How can i make the grey div to push itself up using flex? Should i just use fixed position for it? Thought about changing the html to create container div for the orange and grey boxes, but I want to see how to do it without changing the html.
#import 'general.css';
#import 'reg.css';
#import "768.css" screen and (min-width : 992px);
#import "992.css" screen and (min-width : 1200px);
/*general*/
body, html{
margin: 0;
padding:0;
height: 100%;
}
* {
box-sizing: border-box;
}
/*reg*/
.container{
background-color: red;
text-align: center;
display: flex;
height: 100%;
flex-wrap: wrap;
}
.box{
height: 10%;
width: 100%;
}
header{
background-color: black;
color: white;
width: 100%;
order:1;
}
footer{
background-color: navy;
color: white;
width: 100%;
order:5;
}
.main-content{
background-color: dodgerblue;
height: 60%;
width: 100%;
order:2;
}
.grey{
background-color: grey;
order:4;
}
.orange{
background-color: orangered;
order:3;
}
/*768*/
.box{
height: 11%;
}
.main-content{
height: 67%;
}
.grey{
width: 30%;
order:3;
}
.orange{
background-color: orangered;
width: 70%;
order:4;
}
/*992*/
.main-content{
width: 85%;
order:3;
align-self: flex-end;
height: 80%;
}
.grey{
width: 15%;
order:4;
align-self: flex-start;
height:20% ;
}
.orange{
width:15%;
order:2;
align-self: flex-start;
height: 60%;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="css/index.css">
<title>Document</title>
</head>
<body>
<div class="container">
<header class="box">this is the header</header>
<div class="main-content box">this is main content</div>
<div class="orange box">this is the orange</div>
<div class="grey box">this is the grey</div>
<footer class="box">this is the footer</footer>
</div>
</body>
</html>
I don’t see any solution only using flex because boxes will flow in lines. So as you mentioned, using a positioning for the grey box would be the only way to achieve this.
This is a solution using grid though:
body, html {
height: 100%;
padding:0;
margin: 0;
}
* {
box-sizing: border-box;
}
.container {
display: grid;
grid-template-areas:
"a"
"b"
"c"
"d"
"e";
grid-template-rows: 1fr 60% 1fr 1fr 1fr;
height: 100%;
background-color: red;
}
.box {
display: flex;
justify-content: center;
align-items: center;
}
header {
grid-area: a;
color: white;
background-color: black;
}
.main-content {
grid-area: b;
background-color: dodgerblue;
}
.orange {
grid-area: c;
order: 4;
background-color: orangered;
}
.grey {
grid-area: d;
background-color: grey;
}
footer {
grid-area: e;
color: white;
background-color: navy;
}
#media ( min-width: 768px ) {
.container {
grid-template-areas:
"a a"
"b b"
"d c"
"e e";
grid-template-rows: 15% 4fr 1fr 15%;
grid-template-columns: 15% 1fr;
}
#media ( min-width: 992px ) {
.container {
grid-template-areas:
"a a"
"c b"
"d b"
"e e";
grid-template-rows: 15% 4fr 1fr 15%;
grid-template-columns: 15% 1fr;
}
}
<div class="container">
<header class="box">this is the header</header>
<div class="box main-content">this is main content</div>
<div class="box orange">this is the orange</div>
<div class="box grey">this is the grey</div>
<footer class="box">this is the footer</footer>
</div>
You can use the order style of flex children to affect what order they are rendered inside of a flex parent, however this does require some wrapping divs so you'd have to change your HTML slightly, otherwise you must use CSS grid. Snippet with working example of your images below:
:root {
--min-height: 80px;
}
* {
border-sizing: border-box;
padding: 0;
margin: 0;
}
html, body, .container {
height: 100%;
}
body {
padding: 10px;
}
div {
border-radius: 10px;
}
.container {
display: flex;
flex-direction: column;
}
.container > div {
margin-bottom: 10px;
}
.container > div:last-child {
margin: 0;
}
.main-content > div {
margin-bottom: 10px;
}
.main-content > div:last-child {
margin: 0;
}
.side-content > div {
margin-bottom: 10px;
}
.side-content > div:last-child {
margin: 0;
}
.header, .footer, .content {
min-height: var(--min-height);
}
.teal.content {
min-height: calc(5 * var(--min-height));
}
.black {
background: rgb(30, 32, 42);
}
.teal {
background: rgb(74, 161, 162);
}
.orange {
background: rgb(253, 170, 82);
}
.gray {
background: rgb(203, 187, 172);
}
.navy {
background: rgb(61, 94, 109);
}
#media screen and (min-width: 768px) {
.side-content {
display: flex;
flex-direction: row;
}
.side-content > div {
margin: 0;
}
.side-content > div:last-child {
margin-right: 10px;
}
.orange {
flex: 2 0 auto;
order: 1;
}
.gray {
flex: 1 0 auto;
order: 0;
}
}
#media screen and (min-width: 992px) {
.main-content {
display: flex;
flex-direction: row;
}
.main-content > div {
margin: 0;
}
.main-content > div:last-child {
margin-right: 10px;
}
.side-content {
order: 0;
flex: 1 0 auto;
flex-direction: column;
margin-right: 10px;
}
.side-content > div:last-child {
margin: 0;
}
.side-content > div:first-child {
margin-bottom: 10px;
}
.orange {
order: 0;
margin-bottom: 10px;
}
.teal {
order: 1;
flex: 7 0 auto;
}
}
<div class="container">
<div class="black header"></div>
<div class="main-content">
<div class="teal content"></div>
<div class="side-content">
<div class="orange content"></div>
<div class="gray content"></div>
</div>
</div>
<div class="navy footer"></div>
</div>
I've been struggling to arrange this layout of images.
I've been thinking of using flexbox and i'm pretty sure it's doable with it but I can't manage to find the right way to do it.
If anyone is able to help me i'll be glad.
Here is the layout with each square being an img in a link tag :
img layout
The space between each img must be the same, that's why I've been thinking of using flexbox.
Thanks in advance,
j
Edit: I uploaded what I've been working on :
http://163.172.185.65/flexboxuse.html
Flexbox example with percentage:
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
html,
body {
width: 100%;
height: 100%;
}
.container {
height: 100%;
width: 100%;
display: flex;
flex-flow: row wrap;
}
.sidebar {
background: limegreen;
height: 70%;
width: 30%;
}
.rightCont {
height: 70%;
width: 70%;
display: flex;
flex-flow: row wrap;
}
.red {
background: red;
height: calc(50% - 10px);
width: calc(50% - 10px);
margin-left: 10px;
margin-bottom: 10px;
}
.blue {
background: blue;
height: calc(50% - 10px);
width: calc(50% - 10px);
margin-left: 10px;
margin-bottom: 10px;
}
.yellow {
background: yellow;
height: 50%;
width: calc(50% - 10px);
margin-left: 10px;
}
.sky {
background: cyan;
height: 50%;
width: calc(50% - 10px);
margin-left: 10px;
}
.bottom {
background: violet;
height: calc(30% - 10px);
width: 100%;
margin-top: 10px;
}
<div class="container">
<div class="sidebar"></div>
<div class="rightCont">
<div class="red"></div>
<div class="blue"></div>
<div class="yellow"></div>
<div class="sky"></div>
</div>
<div class="bottom"></div>
</div>
You could approach this with flexbox, but even just float:left will do the trick.
Working Example:
section {
width: 312px;
}
div {
float: left;
width: 100px;
height: 100px;
margin: 0 6px 6px 0;
background-color: gray;
}
div:nth-of-type(1) {
height: 206px;
}
div:nth-of-type(6) {
width: 312px;
margin-bottom: 0;
}
div:nth-of-type(3),
div:nth-of-type(5),
div:nth-of-type(6) {
margin-right: 0;
}
div:nth-of-type(1) {
background-color: lime;
}
div:nth-of-type(2) {
background-color: red;
}
div:nth-of-type(3) {
background-color: blue;
}
div:nth-of-type(4) {
background-color: yellow;
}
div:nth-of-type(5) {
background-color: cyan;
}
div:nth-of-type(6) {
background-color: magenta;
}
<section>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</section>
Second approach (this time with element heights relative to the height of the viewport)
section {
width: calc(100vh + 12px);
}
div {
float: left;
width: 33vh;
height: 33vh;
margin: 0 6px 6px 0;
background-color: gray;
}
div:nth-of-type(1) {
height: calc(66vh + 6px);
}
div:nth-of-type(6) {
width: calc(100vh + 12px);
margin-bottom: 0;
}
div:nth-of-type(3),
div:nth-of-type(5),
div:nth-of-type(6) {
margin-right: 0;
}
div:nth-of-type(1) {
background-color: lime;
}
div:nth-of-type(2) {
background-color: red;
}
div:nth-of-type(3) {
background-color: blue;
}
div:nth-of-type(4) {
background-color: yellow;
}
div:nth-of-type(5) {
background-color: cyan;
}
div:nth-of-type(6) {
background-color: magenta;
}
<section>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</section>
Here is a working example using flex and percentage width:
html,body{
border:0;
margin:0;
height:100%;
}
#wrap
{
width:300px;
display: flex;
flex-direction: column;
justify-content: space-between;
height: 100%;
}
#container
{
display:flex;
flex-direction:row;
flex-wrap:wrap;
justify-content:space-between;
height:70%;
}
#green
{
background-color:chartreuse;
width:30%;
order:0;
}
#red
{
background-color:red;
height:48%;
}
#blue
{
background-color:blue;
height:48%;
}
#yellow
{
background-color:yellow;
height:49%;
}
#aquamarine
{
background-color:aqua;
height:49%;
}
#purple
{
background-color:purple;
height:28%;
}
.col
{
width:32%;
display:flex;
flex-direction:column;
justify-content:space-between;
}
<div id="wrap">
<div id="container">
<div id="green"></div>
<div class="col">
<div id="red"></div>
<div id="yellow"></div>
</div>
<div class="col">
<div id="blue"></div>
<div id="aquamarine"></div>
</div>
</div>
<div id="purple"></div>
</div>
I need to have a layout that looks like this on mobile
-----
| 1 |
-----
| 2 |
-----
| 3 |
-----
And like this on desktop:
---------
| | 1 |
| 2 |---|
| | 3 |
| |----
| |
-----
I decided to use flexbox, my code so far:
<div class="row">
<div class="col-xl secound">2</div>
<div class="col-sm first">1<br>2<br>3<br>4</div>
<div class="col-xl third">3</div>
</div>
.row {
display: flex;
flex-flow: row wrap;
}
.col-sm,
.col-xl {
width: 100%;
}
.col-sm {
background: yellow;
}
.col-xl {
&.secound {
background: #ccc;
}
&.third {
background: #aaa;
}
}
#media (min-width: 700px) {
.col-sm {
width: 25%;
background: yellow;
order: 1;
}
.col-xl {
width: 75%;
&.secound {
background: #ccc;
order: 2;
}
&.third {
background: #aaa;
order: 3;
}
}
}
Unfortunately, I can't slide column "3" under "1". What should I do?
Codepen: http://codepen.io/tomekbuszewski/pen/PbprJP?editors=1100
You can try using float for desktop, and using flexbox with order set for mobile.
jsFiddle
.item-1 {background:aqua;}
.item-2 {background:gold;}
.item-3 {background:pink;}
.row {
overflow: hidden;
}
.item {
width: 50%;
}
.item-2 {
float: left;
}
.item-1,
.item-3 {
overflow: hidden;
}
#media (max-width: 768px) {
.row {
display: flex;
flex-direction: column;
}
.item {
width: auto;
float: none;
}
.item-1 {
order: -1;
}
}
<div class="row">
<div class="item item-2">2<br><br><br></div>
<div class="item item-1">1</div>
<div class="item item-3">3</div>
</div>
You could align .third on the right by using flex property justify-content.
You're CSS would look something like this:
.row{
display: flex;
flex-flow: row wrap;
justify-content: flex-end;
}
.row > div{
flex: 0 0 50%;
}
For changing order you can use the order property:
.first{ order: 1; }
.second{ order: 2; }
.third{ order: 3; }
#media (min-width: 700px){
.first{ order: 2; }
.second{ order: 1; }
.third{ order: 3; }
}
Check the fiddle
On CSS-tricks you can find a great guide for using Flex properties.
There are few things I've given sizes too just for the sake of the demo but it will still work without the sizes.
You will need to give your container a size but that can be 100vh/100vw or even percentage rather than actual pixels.
body {
margin: 0;
}
.container {
display: flex;
flex-wrap: wrap;
flex-direction: column;
height: 600px;
width: 100%;
}
.item-1,
.item-2,
.item-3 {
width: 100%;
font-size: 80px;
color: #fff;
text-align: center;
}
.item-1 {
line-height: 100px;
height: 100px;
background: #00bcd5;
}
.item-2 {
line-height: 200px;
height: 200px;
background: #8bc24a;
}
.item-3 {
line-height: 300px;
height: 300px;
background: #fec107;
}
#media (min-width: 700px) {
.item-1,
.item-2,
.item-3 {
width: 50%;
}
.item-1,
.item-3 {
order: 1;
}
.item-2 {
height: 100%;
line-height: 1em;
}
}
<div class="container">
<div class="item-1">1</div>
<div class="item-2">2</div>
<div class="item-3">3</div>
</div>
Hope this is what you're looking for.
You could use float: right for all three elements instead. Together with the appropriate width definitions in media queries, this should work.
Grid:
/* Column */
.item {
width: 100%;
}
/* Wrap */
.row {
display: flex;
flex-flow: column wrap;
}
/* Responsive */
#media screen and (min-width: 700px){
.row {
flex-flow: row wrap;
justify-content: flex-end;
}
.item { width: 50%;}
.item-1 { order: 2; }
.item-2 { order: 1; }
.item-3 { order: 3; }
}
/* Custom style */
.item {
color: #fff;
display: block;
height: 200px;
text-align: center;
line-height: 200px;
font-size: 3rem;
}
.item-1 {
background: #00bcd5;
}
.item-2 {
background:#8bc24a;
}
.item-3 {
background:#fec107;
}
<div class="row">
<div class="item item-1">1</div>
<div class="item item-2">2</div>
<div class="item item-3">3</div>
</div>
grid with hook:
/* Column */
.item {
width: 100%;
}
/* Wrap */
.row {
display: flex;
flex-flow: column wrap;
}
.sub-row {
display: none;
}
.item-1 { order: 1; }
.item-2 { order: 2; }
.item-3 { order: 3; }
/* Responsive */
#media screen and (min-width: 500px){
.row {
flex-flow: row wrap;
justify-content: flex-end;
}
.sub-row {
width: 50%;
display: flex;
flex-flow: column wrap;
}
.sub-row .item { width: 100%;}
.item { width: 50%;}
.hidden { display: none; }
.item-2 { order: 1; }
.sub-row { order: 2; }
}
/* Custom style */
.item {
color: #fff;
text-align: center;
line-height: 200px;
font-size: 3rem;
}
.item-1 {
background: #00bcd5;
}
.item-2 {
background:#8bc24a;
}
.item-3 {
background:#fec107;
}
<div class="row">
<div class="item item-2">2</div>
<div class="sub-row">
<div class="item item-1">1</div>
<div class="item item-3">3</div>
</div>
<div class="item hidden item-1">1</div>
<div class="item hidden item-3">3</div>
</div>
How about using absolute position?
In your media query change the .row class to this:
.row {
position: relative;
align-items: flex-end;
}
And your .item-2 to:
.item-2 { order: 1; position: absolute; top: 0; left: 0; }
/* Column */
.item {
width: 100%;
}
/* Wrap */
.row {
display: flex;
flex-flow: column wrap;
}
/* Responsive */
#media screen and (min-width: 700px){
.row {
position: relative;
align-items: flex-end;
}
.item { width: 50%;}
.item-1 { order: 2; }
.item-2 { order: 1; position: absolute; top: 0; left: 0; }
.item-3 { order: 3; }
}
/* Custom style */
.item {
color: #fff;
display: block;
text-align: center;
line-height: 200px;
font-size: 3rem;
}
.item-1 {
background: #00bcd5;
}
.item-2 {
background:#8bc24a;
}
.item-3 {
background:#fec107;
}
<div class="row">
<div class="item item-1">1</div>
<div class="item item-2">2
<br>2</div>
<div class="item item-3">3</div>
</div>
Revised Codepen
I have done a flexbox grid, it combines text cells with image cells. All the cells have the same height in each resolution, also text cells. Text cells have the text centered vertically, and this is a must. Now I need to assign each text cell a different background-color, but here I have the problem.
With align-items: center the text is centered vertically, but the background color is only applied to the text. Without align-items: center the background expands to all the cell, but the content is not centered vertically.
Here is the codepen
Any suggestions in how to achieve the two features at same time?
vertically centered text
different background-color for each text cell
Thanks!
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
body {
margin: 0;
background: #333;
padding: 30px;
font-family: Helvetica;
}
a {
color: white;
text-decoration: none;
}
h2 {
font-size: 1.2em;
}
.wrap-items {
background-color: #ccc;
padding: 0;
margin: 0 auto;
display: -ms-flexbox;
-ms-flex-wrap: wrap;
-ms-flex-direction: row;
-webkit-flex-flow: row wrap;
flex-flow: row wrap;
display: -webkit-box;
display: flex;
justify-content: center;
align-items: center;
align-content: center;
}
.wrap-items .item {
-webkit-box-flex: 0 1 auto;
-ms-flex: 0 1 auto;
flex: 1 0 33.333%;
width: 33.33333%;
margin: 0;
padding: 0;
color: white;
font-size: 0;
border: none;
background-color: steelblue;
}
.wrap-items .item.span-2 {
-webkit-box-flex: 2 0 auto;
-ms-flex: 2 0 auto;
flex: 2 0 auto;
width: 66.6666%;
height: auto;
}
.wrap-items .item img {
width: 100%;
height: auto;
}
.wrap-items .item > .text {
padding: 10px;
font-size: 20px;
height: 100%;
}
.item.un .text{
background-color: orange;
}
.item.dos {
background-color: brown;
}
.item.tres {
background-color: violet;
}
#media screen and (max-width: 760px) {
.wrap-items .item {
margin: 0;
flex: 50%
}
}
#media screen and (max-width: 400px) {
.wrap-items .item {
margin: 0;
flex: 100%;
}
}
Use transforms instead of flexbox to vertically center the text.
1) Remove align-items: center from the .wrap-items class
2) Adjust the .wrap-items .item > .text class like this:
.wrap-items .item > .text {
padding: 10px;
font-size: 20px;
position: absolute;
top: 50%;
transform: translateY(-50%);
}
Updated Codepen
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
body {
margin: 0;
background: #333;
padding: 30px;
font-family: Helvetica;
}
a {
color: white;
text-decoration: none;
}
h2 {
font-size: 1.2em;
}
.wrap-items {
background-color: #ccc;
padding: 0;
margin: 0 auto;
display: -ms-flexbox;
-ms-flex-wrap: wrap;
-ms-flex-direction: row;
-webkit-flex-flow: row wrap;
flex-flow: row wrap;
display: -webkit-box;
display: flex;
justify-content: center;
//align-items: center;
//align-content: center;
}
.wrap-items .item {
-webkit-box-flex: 0 1 auto;
-ms-flex: 0 1 auto;
flex: 1 0 33.333%;
width: 33.33333%;
margin: 0;
padding: 0;
color: white;
font-size: 0;
border: none;
background-color: steelblue;
position: relative;
}
.wrap-items .item.span-2 {
-webkit-box-flex: 2 0 auto;
-ms-flex: 2 0 auto;
flex: 2 0 auto;
width: 66.6666%;
height: auto;
}
.wrap-items .item img {
width: 100%;
height: auto;
}
.wrap-items .item > .text {
padding: 10px;
font-size: 20px;
position: absolute;
top: 50%;
transform: translate(0, -50%);
}
.item.un {
background-color: orange;
}
.item.dos {
background-color: brown;
}
.item.tres {
background-color: purple;
}
#media screen and (max-width: 760px) {
.wrap-items .item {
margin: 0;
flex: 50%
}
}
#media screen and (max-width: 400px) {
.wrap-items .item {
margin: 0;
flex: 100%;
}
}
<div class="wrap-items">
<!-- row 1 -->
<div class="item span-2">
<div class="text">
<h2>THE TITLE</h2>
<p>Just be water my friend</p>
<p>Small people can do very big things.</p>
</div>
</div>
<div class="item">
<img src="https://placekitten.com/g/800/600" alt>
</div>
<!-- row 2 -->
<div class="item un">
<div class="text ">
one or more lines of text inside the box
</div>
</div>
<div class="item">
<img src="https://placekitten.com/g/800/600" alt>
</div>
<div class="item dos">
<div class="text">
text in the middle
</div>
</div>
<!-- row 3 -->
<div class="item">
<img src="https://placekitten.com/g/800/600" alt="">
</div>
<div class="item tres">
<div class="text">
three lines of text centered vertically in the middle of the box
</div>
</div>
<div class="item">
<img src="https://placekitten.com/g/800/600" alt>
</div>
</div>