Flexbox rearrange orders in between 2 nested items - html

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>

Related

Placing container with flex order for different views [duplicate]

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

Flex CSS with fixed width and equal height

I have three sections in a container. When I resize my browser to the max-width of 668px, I need to make the section 1 and section 3 in one row and the section 2 in the below row. The section 2 width should be proportional to the section 1 and section 3 width.
But now once I minimize the browser size to 668px and below, then section 3 is not visible.
This is what I tried.
#media (max-width: 668px) {
.container {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-self: flex-start;
}
.container .section1 {
height: 300px;
}
.container .section1,
.container .section3 {
flex: 0 0 262px;
margin: 3px;
display: block;
flex-grow: 0;
flex-shrink: 0;
}
.container .section2 {
flex: 0 0 500px;
flex-grow: 0;
flex-shrink: 0;
order: 1;
min-height: 235px;
}
}
#media (max-width: 940px) {
.container {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-self: flex-start;
}
.container .section1 {
height: 300px;
}
.container .section1,
.container .section3 {
flex: 0 0 262px;
margin: 3px;
display: block;
flex-grow: 0;
flex-shrink: 0;
}
.container .section2 {
flex: 0 0 500px;
flex-grow: 0;
flex-shrink: 0;
order: 1;
min-height: 235px;
}
}
<div class="container">
<div class="section1">Section 1</div>
<div class="section2">Section 2</div>
<div class="section3">Section 3</div>
</div>
You don't have any height specified on .section3.
On .section1 you have height: 300px.
On .section2 you have min-height: 235px.
But on .section3 you have nothing. Try this adjustment to your code:
.section1, .section3 {
height: 300px;
}
jsFiddle demo

How do I eliminate this huge unwanted margin between two rows of flex items? [duplicate]

This question already has an answer here:
Remove space (gaps) between multiple lines of flex items when they wrap
(1 answer)
Closed 6 years ago.
html, body {
height: 100%;
}
.flex{
min-height: 100%;
display: flex;
justify-content:center;
flex-flow: row wrap;
align-items: center;
background: red;
}
.coloring {
background:#CCC;
border-radius:7px;
padding: 20px;
margin: 0px;
}
.Projects{
order: 1;
flex: 0 1 100%;
}
.Tribute{
order: 2;
flex: 1 1;
}
.Portfolio{
order: 3;
flex: 1 1;
}
<section class="flex">
<div class="coloring Projects">Projects</div>
<div class="coloring Tribute">Tribute</div>
<div class="coloring Portfolio">Portfolio</div>
</section>
When you narrow the screen there is going to be 3 rows and now there are 2 such huge unwanted margins. I don’t know what to do. If I eliminate align-items: center the boxes will fill the entire page, but that is not what I want.
Aligning between multiple flex lines is handled by the align-content property - try align-content: center to eliminate the margins - see demo below:
html,
body {
height: 100%;
}
.flex {
min-height: 100%;
display: flex;
justify-content: center;
flex-flow: row wrap;
align-items: center;
align-content: center;
background: red;
}
.coloring {
background: #CCC;
border-radius: 7px;
padding: 20px;
margin: 0px;
}
.Projects {
order: 1;
flex: 0 1 100%;
}
.Tribute {
order: 2;
flex: 1 1;
}
.Portfolio {
order: 3;
flex: 1 1;
}
<section class="flex">
<div class="coloring Projects">Projects</div>
<div class="coloring Tribute">Tribute</div>
<div class="coloring Portfolio">Portfolio</div>
</section>
only you have to remove
min-height from .flex class

Re-arranging flex items for mobile and desktop

I'm trying to make the layout below using flex:
Can I make this layout with flex?
.objectref-use .page-header {
display: flex;
flex-direction: row;
}
.objectref-use .page-header .header-col {
flex: 1;
display: flex;
}
.objectref-use .page-header .header-content {
display: flex;
flex-wrap: wrap;
flex-direction: column;
}
.objectref-use .page-header .header-content .together-content {
flex-wrap: nowrap;
}
.objectref-use .page-header .objectref-title {
margin-right: 8px;
}
.objectref-use .page-header .objectref-title.header-col {
justify-content: flex-start;
}
.objectref-use .page-header .objectref-title .header-content {
flex: 0 1 auto;
background: blue;
}
.objectref-use .page-header .objectref-timeline {
flex: 0 0 35px;
display: flex;
}
.objectref-use .page-header .objectref-timeline .header-content {
background: pink;
flex: 1 1 100%;
}
.objectref-use .page-header .objectref-menu.header-col {
justify-content: flex-end;
}
.objectref-use .page-header .objectref-menu .header-content {
flex: 0 1 auto;
background: green;
}
#media screen and (max-width: 768px) {
.page-header {
flex-direction: column;
}
.page-header .header-row {
flex-direction: row;
}
}
#media screen and (max-width: 480px) {
.page-header {
flex-direction: column;
}
.page-header .header-col {
flex: 1;
}
.page-header .objectef-timeline {
margin: 0;
}
}
<div class="objectref-use">
<div class="page-header">
<div class="header-col objectref-title">
<div class="header-content">
<h1>title here (can be loooong) [block 1]</h1>
<h6>text on next line</h6>
</div>
</div>
<div class="header-col objectref-timeline">
<div class="header-content">timeline [block 3]</div>
</div>
<div class="header-col objectref-menu">
<div class="header-content">
<div class="together-content">
few button groups here [block 2]
</div>
<h6>text on next line</h6>
</div>
</div>
</div>
</div>
This is the current CSS on Codepen. Thanks.
Yes, you can change the order of flex elements with the css order property.
Fiddle
Further you can change the width of flex elements, stack certain ones on top of each other, etc... by adjusting the flex values.
Check out this guide for more information.
Fiddle
ul {
display: -webkit-flex;
display: flex;
flex-wrap: wrap;
padding: 0;
margin: 0;
margin-bottom: 25px;
}
li {
background: lightblue;
text-align: center;
flex: 0 1 50%;
list-style: none;
}
.one {
background: green;
-webkit-order: 2;
order: 2;
}
.two {
background: olive;
-webkit-order: 3;
order: 3;
}
.three {
-webkit-order: 1;
order: 1;
flex: 1 0 100%;
}
.four, .five, .six {
border: 1px solid red;
flex: 1;
}
.seven, .eight, .nine {
border-bottom: 1px solid white;
flex: none;
display: block;
width: 100%;
}
<ul>
<li class="one">1</li>
<li class="two">2</li>
<li class="three">3</li>
</ul>
<ul>
<li class="four">1</li>
<li class="five">2</li>
<li class="six">3</li>
</ul>
<ul>
<li class="seven">1</li>
<li class="eight">2</li>
<li class="nine">3</li>
</ul>

Flexbox children, mix of rows and columns

I am using flexbox to align my 4 elements in a row.
I then want to break this down for mobile like so:
I have successfully reordered the elements here:
.flexcontainer {
display: -webkit-flex;
display: flex;
-webkit-flex-direction: row;
flex-direction: row;
-webkit-align-items: flex-start;
align-items: flex-start;
width: 90%;
margin: 0 auto;
background: red;
}
.flexcontainer>div {
height: 100px;
width: 25%;
background-color: #E46119;
border: 1px solid #626262;
margin: 3px;
}
.flexcontainer>div:nth-of-type(1) {
-webkit-flex: 1 0 0;
flex: 1 0 0;
order: 3;
}
.flexcontainer>div:nth-of-type(2) {
-webkit-flex: 2 0 0;
flex: 2 0 0;
order: 2;
}
.flexcontainer>div:nth-of-type(3) {
-webkit-flex: 2 0 0;
flex: 2 0 0;
order: 1;
}
.flexcontainer>div:nth-of-type(4) {
-webkit-flex: 1 0 0;
flex: 1 0 0;
order: 4;
}
<div class="flexcontainer">
<div>one</div>
<div>two</div>
<div>three</div>
<div>four</div>
</div>
But I am stuck on how to break down child elements "two" and "three" into their own rows. And then how to make element "one" and "four" each 50% wide on their own row.
Is what I'm trying to do possible without additional HTML markup? Thanks for your advice.
.flexcontainer {
display: -webkit-flex;
display: flex;
-webkit-flex-direction: row;
flex-direction: row;
-webkit-align-items: flex-start;
align-items: flex-start;
width: 90%;
margin: 0 auto;
background: red;
}
.flexcontainer>div {
height: 100px;
width: 25%;
background-color: #E46119;
border: 1px solid #626262;
margin: 3px;
}
.flexcontainer>div:nth-of-type(1) {
-webkit-flex: 1 0 0;
flex: 1 0 0;
}
.flexcontainer>div:nth-of-type(2) {
-webkit-flex: 2 0 0;
flex: 2 0 0;
}
.flexcontainer>div:nth-of-type(3) {
-webkit-flex: 2 0 0;
flex: 2 0 0;
}
.flexcontainer>div:nth-of-type(4) {
-webkit-flex: 1 0 0;
flex: 1 0 0;
}
<div class="flexcontainer">
<div>one</div>
<div>two</div>
<div>three</div>
<div>four</div>
</div>
The desktop-mobile transition can be achieved with CSS only using flexbox.
No changes are necessary in the HTML.
.flexcontainer {
display: flex;
width: 90%;
margin: 0 auto;
background: red;
}
.flexcontainer > div {
flex: 0 0 25%;
height: 100px;
background-color: #E46119;
border: 1px solid #626262;
margin: 3px;
}
.flexcontainer > div:nth-of-type(1) { flex: 1 0 0; }
.flexcontainer > div:nth-of-type(2) { flex: 2 0 0; }
.flexcontainer > div:nth-of-type(3) { flex: 2 0 0; }
.flexcontainer > div:nth-of-type(4) { flex: 1 0 0; }
#media screen and ( max-width: 500px) {
.flexcontainer { flex-wrap: wrap; }
.flexcontainer > div:nth-of-type(1) { order: 3; flex-basis: 34%; }
.flexcontainer > div:nth-of-type(2) { order: 2; flex-basis: 70%; }
.flexcontainer > div:nth-of-type(3) { order: 1; flex-basis: 70%; }
.flexcontainer > div:nth-of-type(4) { order: 4; flex-basis: 34%; }
}
<div class="flexcontainer">
<div>one</div>
<div>two</div>
<div>three</div>
<div>four</div>
</div>
jsFiddle demo
How it works
The media query kicks in when the screen is 500px or less.
The order property sets the order of items on the screen. The default value is 0 for all items.
With flex-wrap: wrap on the container, flex items can now wrap.
With flex-grow set to a positive integer, there's no need for flex-basis to be precise. Since flex-grow will consume free space on the row, flex-basis only needs to be large enough to force a wrap.
If a precise flex-basis value is preferred, any borders, padding and margins would need to be factored in, maybe using box-sizing: border-box and/or calc (example).
You could group "three" and "two" into their own flex box and use flex-wrap to achieve this.
Here is a JSFiddle: https://jsfiddle.net/zw10dzzn/3/
You may have to play around with the margins and the order to get exactly the layout you want.
.flex-container {
display: flex;
align-items: flex-start;
width: 90%;
margin: 0 auto;
background: red;
flex-wrap: wrap; /* allow elements to wrap in mobile view */
}
.flex-container .one,
.flex-container .two-and-three,
.flex-container .four {
background-color: magenta;
}
.flex-container .one,
.flex-container .four {
height: 100px;
margin: 3px;
flex-grow: 1;
flex-shrink: 0;
flex-basis: auto;
}
.flex-container .two-and-three {
order: 1;
display: flex;
flex: 0 1 100%;
flex-wrap: wrap;
}
.flex-container .two-and-three .two,
.flex-container .two-and-three .three {
background-color: #FC0;
flex: 1 0 100%;
margin: 3px;
height: 100px;
}
.flex-container .two-and-three .two {
order: 2;
}
.flex-container .two-and-three .three {
order: 1;
}
.flex-container .one {
order: 3;
}
.flex-container .four {
order: 4;
}
#media (min-width: 768px) {
.flex-container {
flex-wrap: nowrap; /* back to single row */
}
.flex-container .two-and-three {
flex-grow: 4;
flex-basis: auto; /* stop spanning the whole row */
flex-wrap: nowrap; /* back to single row */
}
.flex-container .two-and-three .two,
.flex-container .two-and-three .three {
flex-basis: 50%;
}
.flex-container .two-and-three .two {
order: 1;
}
.flex-container .two-and-three .three {
order: 2;
}
.flex-container .one {
order: 1;
}
.flex-container .four {
order: 4;
}
}
<div class="flex-container">
<div class="one">one</div>
<div class="two-and-three">
<div class="two">two</div>
<div class="three">three</div>
</div>
<div class="four">four</div>
</div>