Placing container with flex order for different views [duplicate] - html

This question already has answers here:
Left column and stacked right column using flexbox CSS [duplicate]
(2 answers)
Closed 10 months ago.
I want to build with flex the following structure as a desktop first build:
In desktop view i need to place Container 1 and Container 2 side by side with the same height (use the height of the heighest content) and container 2 contains two content boxes.
But in mobile the overall order should be different as seen in the image. The problem i have here is the Container 2 im using here making it difficult to rearange the content as needed for mobile views.
Here is some of my code:
<div class="content-wrapper">
<div class="container-1" >
Content 1
</div>
<div class="container-2">
<div class="content-2">
Content 2
</div>
<div class="content-3">
Content 3
</div>
</div>
</div>
.content-wrapper {
display: flex;
flex-direction: column;
height: 100%;
width: 100%;
#media only screen and (max-width: 900px) {
flex-direction: row;
}
.container-1 {
width: 50%;
display: flex;
flex-direction: column;
order: 2;
justify-content: center;
#media only screen and (max-width: 900px) {
order: 1;
}
}
.container-2{
// height: 100vh;
display: flex;
flex-direction: column;
flex-wrap: nowrap;
order: 1;
width: 50%;
#media only screen and (max-width: 900px) {
order: 2
}
.content-2 {
height: 70%;
}
.content-3 {
height: 30%;
}
}
}
Maybe someone can help me out here how to build this different views with flex (if you can provide a good grid solution im also happy with this)

IMHO the easiest way would be the use of CSS-Grid which controls both horizontal and vertical axis at the same time. For that you dont need wrappers and can simply use grid-template-areas:
.grid {
display: grid;
grid-template-areas:
"one two"
"one two"
"one three";
}
#media only screen
and (max-width: 900px) {
.grid {
grid-template-areas:
"two"
"one"
"three";
}
}
.grid :nth-child(1) {
grid-area: one;
}
.grid :nth-child(2) {
grid-area: two;
}
.grid :nth-child(3) {
grid-area: three;
}
/* for demonstration purpose only */
body {
margin: 0;
}
.grid {
grid-gap: 2px;
height: 100vh;
padding: 2px;
box-sizing: border-box;
}
.grid > div {
box-shadow: 0 0 0 2px black;
display: flex;
justify-content: center;
align-items: center;
font-size: 2em;
}
<div class="grid">
<div>1</div>
<div>2</div>
<div>3</div>
</div>

I try this with flex grid with your desktop view and display flex with your mobile view:
.content-wrapper {
display: grid;
grid-template-columns: 1fr 1fr;
grid-auto-rows: 70% 30%;
height: 100%;
width: 100%;
}
.content-wrapper * {
border: solid 1px;
}
.content-wrapper .content-1 {
grid-row: 1/3;
grid-column: 1/2;
display: flex;
flex-direction: column;
justify-content: center;
}
.content-wrapper .content-2 {
display: flex;
flex-direction: column;
flex-wrap: nowrap;
}
.content-wrapper .content-2 {
grid-column: 2/3;
grid-row: 1/2;
}
.content-wrapper .content-3 {
grid-column: 2/3;
grid-row: 2/3;
}
#media only screen and (max-width: 900px)
{
.content-wrapper {
display: flex;
flex-direction: column;
}
.content-2 {
order: -1;
}
}
</style>
<div class="content-wrapper">
<div class="content-1" >
Content 1
</div>
<div class="content-2">
Content 2
</div>
<div class="content-3">
Content 3
</div>
</div>
</style>
I also change your html.

You can try like this:
.container-1 {
width: 50%;
display: flex;
flex-direction: column;
order: 2;
justify-content: center;
}
#media only screen and (max-width: 900px) {
.container-1 {
order: 2;
}
}
.container-2 {
height: 100vh;
display: flex;
flex-direction: column;
flex-wrap: nowrap;
order: 1;
width: 50%;
}
#media only screen and (max-width: 900px) {
.container-2 {
order: 1
}
}

Related

Complicated flexbox layout

I always struggle with flexboxes. This time is no exception trying to solve this for a solid hour and read a lot of similar questions but none of these gave me the right idea on how to do it with my layout. I hope that some of you could help me out with how to do this :)
I'm creating a MiniPlayer. The desired look of it is like that:
At the moment it looks like this:
This is my current css file:
.MiniPlayer {
position: fixed;
bottom: 0;
left: 0;
right: 0;
height: 100px;
display: flex;
flex-direction: row;
img{
width: auto;
height: 90%;
max-height: 100px;
max-width: 100px;
flex-direction: column;
}
.Title{
flex-direction: column;
flex-wrap: wrap;
}
.Name{
flex-direction: column;
flex-wrap: wrap;
}
.MediaButton{
flex-direction: row;
}
.Slider{
flex-direction: column;
flex-wrap: wrap;
flex-grow: 4;
}
Figured I would add a flexbox solution as initially requested.
* {
text-align: center;
}
.img,
.title,
.name,
.btn,
.slider {
border: solid black 2px;
}
.wrapper {
border: solid 1px orange;
padding: 1em;
display: flex;
}
.wrapper-2 {
margin-left: 1em;
width: 75%;
display: flex;
flex-direction: column;
}
.img {
width: 25%;
}
.title,
.name {
width: 50%;
margin-bottom: 1em;
}
.btn {
width: 25%;
margin-bottom: 1em;
}
.space-between {
display: flex;
justify-content: space-between;
}
<div class="wrapper">
<div class="img">img</div>
<div class="wrapper-2">
<div class="title">title</div>
<div class="space-between">
<div class="name">name</div>
<div class="btn">btn</div>
</div>
<div class="slider">slider</div>
</div>
</div>
Would highly recommend doing this in grid. It is possible by making a lot of clumsy new containers, but you have much better layout control with grid.
If you're not too comfortable with grid, you can use a CSS Grid Generator to do the work for you - works just fine.
.parent {
display: grid;
grid-template-columns: repeat(6, 1fr);
grid-template-rows: repeat(4, 1fr);
grid-gap: 5px;
}
.parent div {
border: 1px solid black;
}
.div1 {
grid-area: 1 / 1 / 5 / 3;
}
.div2 {
grid-area: 4 / 3 / 5 / 7;
}
.div3 {
grid-area: 3 / 6 / 4 / 7;
}
.div4 {
grid-area: 1 / 3 / 2 / 6;
}
.div5 {
grid-area: 2 / 3 / 3 / 6;
}
<div class="parent">
<div class="div1">img</div>
<div class="div2">slider</div>
<div class="div3">pause</div>
<div class="div4">title</div>
<div class="div5">name</div>
</div>

Hide grid column with the rest of columns redistributing

everyone.
I'm trying to implement the grid column that hides when the wrapping container width goes below certain value, while the rest of columns should redistribute over the entire width:
Neither visibility: hidden, nor display: none for disappearing column did work (since the blank space is left in place of removed column, while the left column doesn't take the whole width).
My question is: how do I achieve desired behavior with pure CSS and without modifying grid-template-columns of the parent grid container?
.grid {
display: grid;
grid-template-columns: repeat(3, minmax(100px, 1fr));
}
.column {
background: blue;
color: #fff;
height: 150px;
display: flex;
align-items: center;
justify-content: center;
}
.columnA {
grid-column-start: 1;
grid-column-end: 2;
}
.columnB {
grid-column-start: 2;
grid-column-end: 4;
}
#media (max-width: 800px) {
.columnA {
visibility: hidden;
}
}
<div class="grid">
<div class="columnA column">columnA</div>
<div class="columnB column">columnB</div>
</div>
Simplify your code like below:
.grid {
display: grid;
grid-gap:5px;
grid-auto-columns: minmax(100px, 1fr); /* size of one column */
grid-auto-flow:column; /* column flow */
}
.column {
background: blue;
color: #fff;
height: 150px;
display: flex;
align-items: center;
justify-content: center;
}
.columnB {
grid-column:span 2; /* B takes 2 columns */
}
#media (max-width: 800px) {
.columnA {
display:none;
}
}
<div class="grid">
<div class="columnA column">columnA</div>
<div class="columnB column">columnB</div>
</div>
If you want to keep the template (which is not needed) you can do like below:
.grid {
display: grid;
grid-gap:5px;
grid-template-columns: repeat(3, minmax(100px, 1fr));
}
.column {
background: blue;
color: #fff;
height: 150px;
display: flex;
align-items: center;
justify-content: center;
}
.columnB {
grid-column:span 2;
}
#media (max-width: 800px) {
.columnA {
display:none;
}
.columnB {
grid-column:span 3; /* B will take 3 columns when A is hidden */
}
}
<div class="grid">
<div class="columnA column">columnA</div>
<div class="columnB column">columnB</div>
</div>

Issues adding a gap between two aligned items [duplicate]

This question already has answers here:
Better way to set distance between flexbox items
(40 answers)
Closed 1 year ago.
As shown in the code snippet below i have created two buttons that are always the same width, but im unable to make a gap between them.
Same goes for the mediaquery version (mobile)
How can i do it?
.flex-container {
display: flex;
justify-content: center;
margin: 1em;
}
.flex-container .flex-container {
display: grid;
grid-template-columns: 1fr 1fr;
}
.flex-item {
height: 1.7rem;
padding: 0 1.2rem;
width: 100%;
}
.item1{
margin-right:1vw; /*wont work*/
}
#media only screen and (max-width: 480px) {
.flex-container .flex-container{
display:flex;
flex-direction: column;
}
}
<div class="flex-container">
<div class="flex-container">
<button class="flex-item item1">Button1</button>
<button class="flex-item">Button2 really long with same width</button>
</div>
</div>
column-gap: 1vw; works as expected:
.flex-container {
display: flex;
justify-content: center;
margin: 1em;
column-gap: 1vw;
}
.flex-container .flex-container {
display: grid;
grid-template-columns: 1fr 1fr;
}
.flex-item {
height: 1.7rem;
padding: 0 1.2rem;
width: 100%;
}
#media only screen and (max-width: 480px) {
.flex-container .flex-container {
display: flex;
flex-direction: column;
}
}
<div class="flex-container">
<div class="flex-container">
<button class="flex-item item1">Button1</button>
<button class="flex-item">Button2 really long with same width</button>
</div>
</div>

Flexbox or CSS Grid: How to let one column be larger than two others?

How would you solve this Layout if you have only 3 Containers:
<div class="main-container">
<div class="blue-container"></div>
<div class="red-container"></div>
<div class="green-container"></div>
</div>
.main-container {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
align-items: stretch;
align-content: stretch;
}
.blue-container, .red-container {
width: 50%;
}
.green-container {
flex-basis: 100%;
width: 100%;
}
I solved it for Desktop (code above) and Mobile (everything flex-basis: 100%). But how to solve the tablet layout without adding more Markup/<div>'s?
The grid solution. Look how compact and nice it is. For all tree conditions. Used grid-template-areas. Try it while resizing the viewport.
.main-container {
display: grid;
grid-template-areas:
"blue red"
"green green";
grid-template-columns: 1fr 1fr;
grid-auto-rows: auto;
grid-gap: 10px;
min-height: 150px; /*just for instance */
}
.blue-container {
grid-area: blue;
background: blue;
}
.red-container {
grid-area: red;
background: red;
}
.green-container {
grid-area: green;
background: green;
}
/* tablet */
#media (max-width: 991.98px) {
.main-container {
grid-template-areas:
"blue red"
"green red";
}
}
/* mobile */
#media (max-width: 575.98px) {
.main-container {
grid-template-areas:
"blue blue"
"red red"
"green green";
}
}
<div class="main-container">
<div class="blue-container"></div>
<div class="red-container"></div>
<div class="green-container"></div>
</div>
Change your flex-direction to column and use the order property. Flex-basis will determine the height:
.main-container {
display: flex;
flex-direction: column;
flex-wrap: wrap;
justify-content: space-between;
align-items: stretch;
align-content: stretch;
height: 100vh;
}
.red-container {
flex-basis: 100%;
background: red;
order: 3;
}
.green-container {
background: green;
order: 2;
flex-basis: 25%;
}
.blue-container {
background: blue;
order: 1;
flex-basis: 75%;
}
<div class="main-container">
<div class="blue-container"></div>
<div class="red-container"></div>
<div class="green-container"></div>
</div>

Flexbox rearrange orders in between 2 nested items

I have a flexbox that has 2 boxes on the left and 1 box on the right. I need for the box on the right to wedge between the two boxes on the left.
[EDIT:Clarification]Box 3 should fully expand to consume the same space as boxes 1 and 2 on the left side.[/EDIT]
.rowParent {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: flex-start;
align-content: stretch;
align-items: stretch;
}
.flexChild {
flex: 1;
-webkit-align-self: auto;
-ms-flex-item-align: auto;
align-self: auto;
}
.flexChild2 {
flex: 1 100%;
-webkit-align-self: auto;
-ms-flex-item-align: auto;
align-self: auto;
}
#columnChild41158 {
background-color: green;
order: 1;
}
#columnChild61714 {
background-color: red;
order: 3;
}
#rowChild24054 {
background-color: blue;
order: 2;
}
#media (min-width: 1000px) {
.columnParent {
-webkit-box-orient: vertical;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
}
.flexChild2 {
-webkit-box-flex: 1;
-webkit-flex: 1;
-ms-flex: 1;
flex: 1;
}
}
<div id="container" class="flexChild rowParent">
<div id="rowChild71124" class="flexChild2 columnParent">
<div id="columnChild41158" class="flexChild">1</div>
<div id="columnChild61714" class="flexChild">2</div>
</div>
<div id="rowChild24054" class="flexChild">3</div>
</div>
Here's a codepen of what I am trying to do:
http://codepen.io/ants/pen/rLYVPa
Currently it is:
1 3
2
Once the browser is under 1000px I want it to stack as 100% width items but as:
1
3
2
I tried using order but that doesn't seem to work.
I don't think there is other way to do this unless you set fixed height on flex container. To change order of elements you can't have nested elements in you HTML.
* {
box-sizing: border-box;
margin: 0;
}
.content {
display: flex;
height: 100vh;
flex-direction: column;
flex-wrap: wrap;
}
.box {
flex: 0 0 50%;
width: 50%;
border: 1px solid black;
}
.last {
flex: 1;
background: lightblue;
}
#media(max-width: 768px) {
.box {
flex: 1;
width: 100%;
}
.last {
order: 2;
}
.second {
order: 3;
}
}
<div class="content">
<div class="box first">1</div>
<div class="box second">2</div>
<div class="box last">3</div>
</div>
If you can remove the extra wrapper div to make all flex items at the same level, you can do it with flex-flow: column nowrap; and flex-flow: row wrap; in the media queries, plus order and width tricks.
.rowParent {
display: flex;
flex-flow: column nowrap;
}
.flexChild {
width: 100%;
}
.flexChild2 {
order: 1;
}
#media (min-width: 1000px) {
.rowParent {
flex-flow: row wrap;
}
.flexChild {
width: 50%;
}
}
.flexChild1 { background-color: lightgreen; }
.flexChild2 { background-color: lightpink; }
.flexChild3 { background-color: lightblue; }
<div class="rowParent">
<div class="flexChild flexChild1">1</div>
<div class="flexChild flexChild2">2</div>
<div class="flexChild flexChild3">3</div>
</div>