Add a row to a nested flex container on media query - html

I have one primary container that holds all the divs using a flex-direction of row.
A second container that is nested holds two divs that have a flex-direction of column, to stack up two divs in one row in the outer container.
Using flex-box and media query, I was attempting to change the existing two row column div 'smaller-container' into a three row column div once the browser width is less than 1000px.
I tried doing this by creating a third empty div within smaller-container and swapping its order with a div outside the smaller-container once the browser width is less than 1000px.
It didn't work. I think this is because the two divs in question (the empty div and the outer div) are at a different nesting level.
It would be great if someone can find a solution to turn the two row in one column to three row in one column.
Even better if that solution has no need of a nested container. Javascript solution is also welcome if it doesn't require a plugin.
Image of how it should look:
/*Basic Reset*/
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html,
body {
height: 100%;
}
body {
max-width: 1366px;
margin: auto;
width: 100%;
}
.container {
display: flex;
flex-wrap: wrap;
flex-direction: row;
}
.box-1 {
order: 1;
background-color: red;
height: 150px;
width: 50%;
}
.smaller-container {
display: flex;
flex-wrap: wrap;
flex-direction: column;
width: 50%;
order: 2;
}
.box-2 {
order: 3;
background-color: blue;
height: 75px;
width: 100%;
}
.box-3 {
order: 4;
background-color: green;
height: 75px;
width: 100%;
}
.box-4 {
order: 5;
width: 100%;
}
.box-5 {
order: 6;
background-color: orange;
height: 150px;
width: 100%;
}
#media screen and (max-width: 1000px) {
.box-2 {
height: 50px;
}
.box-3 {
height: 50px;
}
/******* Here we swap the empty div that hasbeen existing in the smaller container
with an outer div ********/
.box-5 {
order: 5;
height: 50px;
}
.box-4 {
order: 6;
background-color: purple;
height: 150px;
}
}
[image of desired solution][1] [1]:http://i.stack.imgur.com/vlvlx.png
<div class="container">
<div class="box-1"></div>
<div class="smaller-container">
<div class="box-2"></div>
<div class="box-3"></div>
<div class="box-4"></div>
</div>
<div class="box-5"></div>
</div>
https://jsfiddle.net/lukindo/nuv603h9/1/

Well, you're right that the order property doesn't work at different nesting levels. It only works among siblings.
Scripting is one option you can pursue. Another, a bit hackish, is to duplicate an HTML element. Specifically, place the orange box element (.box-5) in both the primary and nested container.
Then use display: none on both orange and purple boxes per your media query.
Here's an example:
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html,
body {
height: 100%;
}
body {
max-width: 1366px;
margin: auto;
width: 100%;
}
.container {
display: flex;
flex-wrap: wrap;
flex-direction: row;
}
.box-1 {
order: 1;
background-color: red;
height: 150px;
width: 50%;
}
.smaller-container {
display: flex;
flex-wrap: wrap;
flex-direction: row;
width: 50%;
order: 2;
}
.box-2 {
order: 3;
background-color: blue;
height: 75px;
width: 100%;
}
.box-3 {
order: 4;
background-color: green;
height: 75px;
width: 100%;
}
.smaller-container > .box5 {
display: none;
}
.container > .box-5 {
order: 6;
background-color: orange;
height: 150px;
width: 100%;
}
#media screen and (max-width: 1000px) {
.box-2 {
height: 50px;
}
.box-3 {
height: 50px;
}
.container > .box-4 {
order: 6;
background-color: purple;
height: 150px;
width: 100%;
}
.smaller-container > .box-5 {
display: block;
height: 50px;
background-color: orange;
width: 100%;
order: 6;
}
.container > .box-5 {
display: none;
}
}
<div class="container">
<div class="box-1"></div>
<div class="smaller-container">
<div class="box-2"></div>
<div class="box-3"></div>
<div class="box-5"></div>
</div>
<div class="box-4"></div>
<div class="box-5"></div>
</div>
Revised Fiddle

Related

CSS stack a right side of a row to under the left one when making the web smaller

I need the container #3, to shrink or to move underneath #2. I don't know how to do this, I might need to do flex but don't know. I need the left one(#2) to stay the same size and the right one (#3) to be the one that moves around. I don't know what more to add or change, I've tried with infinite combinations and have not done it correctly.
I want it like this: enter image description here
and when having the nav smaller like this : enter image description here
* {
margin: 0px;
padding: 0px;
}
div#general {
margin: auto;
display: grid;
margin-top: 0%;
width: 100%;
height: 100%;
background-color: #4f6d7a;
}
div#enlaces {
float: center;
display: center;
width: 100%;
height: 100px;
background-color: #166088;
}
div#tablas_carpetas {
position: relative;
display: flex;
flex-wrap: wrap;
width: 100%;
height: 1400px;
background-color: #DBE9EE;
}
div#tablas {
order: 1;
background-color: #dfc0c0;
height: 600px;
width: 40%;
}
div#carpetas {
order: 2;
width: 60%;
height: 600px;
background-color: green;
}
#media all and (max-width: 450px) {
div#tablas_carpetas {
flex-direction: column;
}
div#tablas {
width: 100%;
order: 1;
}
div#carpetas {
width: 100%;
order: 2;
}
}
<div id="general">
<div id="enlaces">1</div>
<div id="tablas_carpetas">
<div id="tablas">2</div>
<div id="carpetas">3</div>
</div>
<div id="anuncios">4</div>
<div id="pie">5</div>
</div>
You can add a display grid instead of flex on it when your reach the media query you want like below. Let me know If this is what you want.
* {
margin: 0px;
padding: 0px;
}
div#general {
margin: auto;
display: grid;
margin-top: 0%;
width: 100%;
height: 100%;
background-color: #4f6d7a;
}
div#enlaces {
float: center;
display: center;
width: 100%;
height: 100px;
background-color: #166088;
}
div#tablas_carpetas {
position: relative;
display: flex;
flex-wrap: wrap;
width: 100%;
height: 1400px;
background-color: #DBE9EE;
}
div#tablas {
order: 1;
background-color: #dfc0c0;
height: 600px;
width: 40%;
}
div#carpetas {
order: 2;
width: 60%;
height: 600px;
background-color: green;
}
#media all and (max-width: 450px) {
div#tablas_carpetas {
display:grid;
}
div#tablas {
width: 40%;
order: 1;
}
div#carpetas {
max-width: 60%;
order: 2;
}
}
<div id="general">
<div id="enlaces">1</div>
<div id="tablas_carpetas">
<div id="tablas">2</div>
<div id="carpetas">3</div>
</div>
<div id="anuncios">4</div>
<div id="pie">5</div>
</div>

Fitting everything within a static flex column

I am trying to fit 4 divs within the view bounds of a non-scrolling column flexbox but I can't seem to get it working.
What I want:
What I experience:
I have no idea what I am doing and just randomly permutating flex-related CSS fields to try and fix it haha. If someone could point out what is wrong I would love you forever.
Here is the gist of my code:
body {
overflow: hidden;
margin: 0;
width: 100%;
height: 100%;
}
#flexcontent {
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
}
#header #firstContent #secondContent {
flex: 1 1 auto;
}
#header {
background-color: green;
font-weight: 700;
align-content: center;
font-size: 7rem;
}
#firstContent {
background-color: red;
}
#secondContent {
background-color: yellow;
}
#picture {
background-color: blue;
flex: 0 1 auto;
}
<body>
<div id="flexcontainer">
<div id="header">Title</div>
<div id="picture"><img src="https://s3-us-west-2.amazonaws.com/uw-s3-cdn/wp-content/uploads/sites/6/2017/11/04133712/waterfall-1140x760.jpg"/></div>
<div id="firstContent">first</div>
<div id="secondContent">second</div>
</div>
</body>
Try this below. And use object-fit if image doesn't expand or shrink as expected or aspect ratio changes.
#flexcontainer {
display: flex;
flex-direction: column;
height: 100vh;
}
#picture {
flex: 1;
min-height: 0;
}
body {
margin: 0;
}
img {
object-fit: contain;
height: 100%;
width: auto;
}
<div id="flexcontainer">
<div id="header">Title</div>
<div id="picture"><img src="https://s3-us-west-2.amazonaws.com/uw-s3-cdn/wp-content/uploads/sites/6/2017/11/04133712/waterfall-1140x760.jpg" /></div>
<div id="firstContent">first</div>
<div id="secondContent">second</div>
</div>
Please check your container div id
<div id="flexcontainer">
change
#flexcontent {
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
}
to
#flexcontainer {
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
}
try object-fit for img
img {
object-fit: contain;
height: 100%;
}
there is a few thing to fix in your CSS, typo and value used
html, /* to inherit height */
body {
margin: 0;
width: 100%;
height: 100%;
}
#flexcontainer {
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
min-height: 0; /* force size calculation*/
}
#header,/* you meant each one of them */
#firstContent,
#secondContent {
flex: 1;
margin: 2px 5vw;/* for demo */
}
#header {
background-color: green;
font-weight: 700;
/* align-content: center; or did you forget display:flex here */
font-size: calc(1rem + 2vw);
}
#firstContent {
background-color: red;
}
#secondContent {
background-color: yellow;
}
#picture {
display: flex;
min-height: 0; /* force size calculation*/
}
img {
max-height: 90%;/* whatever */
margin: auto;/* or align-content + justify-content : center on flex parent*/
}
<div id="flexcontainer">
<div id="header">Title</div>
<div id="picture"><img src="https://s3-us-west-2.amazonaws.com/uw-s3-cdn/wp-content/uploads/sites/6/2017/11/04133712/waterfall-1140x760.jpg" /></div>
<div id="firstContent">first</div>
<div id="secondContent">second</div>
</div>
Allow the item holding the image to shrink below its content size.
Define the parameters of the image.
(Tested in Chrome, Firefox and Edge.)
#flexcontainer {
display: flex;
flex-direction: column;
height: 100vh;
}
#picture {
min-height: 0;
background-color: blue;
}
#picture>img {
width: 100%;
max-height: 100%;
object-fit: contain;
}
#header {
background-color: green;
font-weight: 700;
font-size: 7rem;
}
#firstContent {
background-color: red;
}
#secondContent {
background-color: yellow;
}
body {
margin: 0;
}
<div id="flexcontainer">
<div id="header">Title</div>
<div id="picture"><img src="https://s3-us-west-2.amazonaws.com/uw-s3-cdn/wp-content/uploads/sites/6/2017/11/04133712/waterfall-1140x760.jpg" /></div>
<div id="firstContent">first</div>
<div id="secondContent">second</div>
</div>
jsFiddle demo
I've tidied up your html a little and simplified the CSS. You want to take the overflow: hidden off of the body tag, and give each of your elements a class instead of an id. Finally, simplify the image section by making the image tag itself a flexbox item:
html,
body {
height: 100%
}
body {
/*overflow: hidden;*/
margin: 0;
}
.flexContainer {
display: flex;
flex-direction: column;
height: 100%;
}
.flexContainer__header,
.flexContainer__firstContent,
.flexContainer__secondContent {
flex: 1 1 auto;
}
.flexContainer__header {
background-color: green;
font-weight: 700;
align-content: center;
font-size: 7rem;
}
.flexContainer__firstContent {
background-color: red;
}
.flexContainer__secondContent {
background-color: yellow;
}
.flexContainer__picture {
display: block;
width: 100%;
}
<div class="flexContainer">
<div class="flexContainer__header">Title</div>
<img class="flexContainer__picture" src="https://s3-us-west-2.amazonaws.com/uw-s3-cdn/wp-content/uploads/sites/6/2017/11/04133712/waterfall-1140x760.jpg" />
<div class="flexContainer__firstContent">first</div>
<div class="flexContainer__secondContent">second</div>
</div>

flexbox displaying sub-div at the top

This is what I want to do:
I have the brown part separately at the top as a div. Then the other colors in a content div.
I don't understand how to bring the blue part at the top for < 768px since it is inside the content div .
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
body{
margin: 0;
padding: 0;
}
.container{
display: flex;
flex-direction: column;
}
.aquablue{
padding: 50px;
background-color: #B0C4DE;
order: 1;
}
.brownC{
padding: 50px;
background-color: #663300;
}
.yellowC{
padding: 50px;
background-color: #FFCC00;
order: 3;
}
.greenC{
padding: 50px;
background-color: #00FF00;
order: 4;
}
.blueC{
padding: 50px;
background-color: #336699;
order: 5;
}
#media(min-width: 768px){
.container{
display: flex;
flex-direction: column;
}
.content{
display: flex;
order: 2;
}
.left{
display: flex;
flex-direction: column;
width: 50%;
}
.right{
display: flex;
flex-direction: column;
width: 50%;
}
.brownC{
padding: 50px;
background-color: #663300;
width: 100%;
order: 1;
}
.yellowC{
padding: 50px;
background-color: #FFCC00;
}
.greenC{
padding: 50px;
background-color: #00FF00;
}
.blueC{
padding: 50px;
background-color: #336699;
}
}
</style>
</head>
<body>
<div class="container">
<div class="brownC"></div>
<div class="content">
<div class="left">
<div class="aquablue"></div>
<div class="yellowC"></div>
</div>
<div class="right">
<div class="greenC"></div>
<div class="blueC"></div>
</div>
</div>
</div>
</body>
</html>
For pure css you can use this solution. What you do is to remove your "structual divs", on your .container is to add flex: row; and flex-wrap: wrap, then give your elements the width they should be, as in this case was width: 100%; for .brownC and width: 50%; for the rest. Does it make sense?
Check the JSFIDDLE
css
* {
box-sizing: border-box;
}
.container {
display: flex;
flex-direction: column;
}
.aquablue {
padding: 50px;
background-color: #B0C4DE;
order: 1;
}
.brownC {
padding: 50px;
background-color: #663300;
order: 2;
}
.yellowC {
padding: 50px;
background-color: #FFCC00;
order: 3;
}
.greenC {
padding: 50px;
background-color: #00FF00;
order: 4;
}
.blueC {
padding: 50px;
background-color: #336699;
order: 5;
}
#media(min-width: 768px) {
.container {
flex-direction: row;
flex-wrap: wrap;
}
.brownC {
width: 100%;
order: 1;
}
.aquablue {
order: 2;
width: 50%;
}
.yellowC {
order: 4;
width: 50%;
}
.greenC {
order: 3;
width: 50%;
}
.blueC {
order: 5;
width: 50%;
}
}
html
<div class="container">
<div class="brownC">
</div>
<div class="aquablue">
</div>
<div class="yellowC">
</div>
<div class="greenC">
</div>
<div class="blueC">
</div>
</div>
You can use the move the elements using jQuery on window resize event.
JS FIDDLE : https://jsfiddle.net/tejashsoni111/pdr8qyut/
$(document).ready(function(){
$(window).resize(function(){
if($(window).width() <= 768){
jQuery(".aquablue").after(jQuery(".brownC"));
}else{
jQuery(".content").before(jQuery(".brownC"));
}
})
})

Re-sizing and re-ordering elements between desktop and mobile layouts

I'd like to achieve the following with CSS only (left is mobile layout, right is desktop after breakpoint):
The challenge here obviously is that from a float point of view the element order changes: on mobile the green item is the second, but on desktop it's the first.
Is this possible to achieve with pure CSS? Possibility would be flex-box but I don't have enough experience to recreate this layout.
#container {
display: flex;
flex-direction: column;
flex-wrap: wrap;
height: 400px; /* 1 */
}
.box {
width: 50%;
}
.box1 {
background-color: lightgreen;
height: 400px;
}
.box2 {
background-color: orangered;
height: 200px;
}
.box3 {
background-color: aqua;
height: 200px;
}
#media (max-width: 600px) {
#container { height: auto; } /* 2 */
.box { width: 100%; }
.box2 { order: -1; } /* 3 */
}
/* purely decorative styles */
.box {
border: 1px solid #ccc;
display: flex;
justify-content: center;
align-items: center;
font-size: 1.5em;
}
* { box-sizing: border-box; }
<div id="container">
<div class="box box1"><span>1</span></div>
<div class="box box2"><span>2</span></div>
<div class="box box3"><span>3</span></div>
</div>
jsFiddle
Notes:
Without a fixed height in a column wrap container, flex items don't know where to wrap. So, for your larger screen, define a height which forces the second item to a new column.
Now you're in a mobile layout and wrapping is no longer necessary. The container needs to be twice the height of the desktop layout. Release the height.
Tell the red box to re-position itself first on the list. (The initial order value for flex items is 0.)
Yes you can do this if you can set fixed height on flex-container. You just need to use flex-direction: column and flex-wrap: wrap and then change order with media-queries.
.content {
display: flex;
flex-wrap: wrap;
flex-direction: column;
}
.a {
height: 200px;
background: #00FF02;
}
.b {
height: 100px;
background: red;
}
.c {
height: 100px;
background: blue;
}
#media(min-width:768px) {
.content {
height: 200px;
}
.content > div {
width: 50%;
}
}
#media(max-width:768px) {
.b {
order: -1;
}
}
<div class="content">
<div class="a">A</div>
<div class="b">B</div>
<div class="c">C</div>
</div>
There is also no-flex solution, fiddle (just replace media-query min-width with whatever breakpoint you consider phone width ends):
HTML:
<div class="div1"></div>
<div class="div2"></div>
<div class="div3"></div>
CSS:
div {
width: 50%;
}
.div1 {
background-color: red;
float: right;
height: 200px;
}
.div2 {
background-color: green;
float: left;
height: 400px;
}
.div3 {
background-color: blue;
float: right;
height: 200px;
}
#media (max-width: 500px) {
.div1, .div2, .div3 { width: 100%;}
}

CSS3 columns with one smaller

I want to separate my page into a few columns. Actually I need only three but I may need a few more later.
So I used this:
<style>
.container {
display: flex;
}
.column {
flex: 1;
/*for demo purposes only */
background: #f2f2f2;
/*border: 1px solid #e6e6e6;*/
box-sizing: border-box;
padding-left: 100px;
padding-right: 100px;
padding-top: 50px;
text-align: center;
}
.column-one {
order: 1;
}
.column-two {
order: 2;
}
.column-three {
order: 3;
}
</style>
So my page is perfectly separated in three distinct and equal columns. But I want the second smaller than the others (50%).
I already tried to reduce the width of .column-two class but it did not work.
Is it possible to do this with this king of code ?
I really like this structure because if I have to add one more column I do not have to change the whole CSS. That is why I want to keep this code.
.container {
display: flex;
min-height: 200px;
}
.column {
background: #f2f2f2;
border: 1px solid black;
margin: 3px;
}
.column-one {
flex: 1;
}
.column-two {
flex: 0.5;
}
.column-three {
flex: 1;
}
<div class="container">
<div class="column column-one"></div>
<div class="column column-two"></div>
<div class="column column-three"></div>
</div>
If You want to use four column later then.
.column-one {
flex: 1;
}
.column-two {
flex: 0.5;
}
.column-three {
flex: 0.5;
}
.column-four {
flex: 1;
}
If you add flex: 1 to column-two and flex: 2 to other two columns, column-two will be half width or 50% width of other two column. Also you don't need to use order if you are not going to change it.
.container {
display: flex;
min-height: 100vh;
flex-direction: row;
}
.column {
/*for demo purposes only */
background: #f2f2f2;
/*border: 1px solid #e6e6e6;*/
box-sizing: border-box;
padding-top: 50px;
text-align: center;
border: 1px solid black;
margin: 5px;
}
.column-one {
flex: 2;
}
.column-two {
flex: 1;
}
.column-three {
flex: 2;
}
<div class="container">
<div class="column column-one"></div>
<div class="column column-two"></div>
<div class="column column-three"></div>
</div>