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
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>
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>
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>
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>
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>