Can please someone point me out how can I split out second flex item vertically and horizontally like I have in image below ?
I managed to split in half one big box but I failed making it the same for second flex item.
This is what I have right now -> https://jsfiddle.net/paveu/8c9Ls5s8/
Thanks,
HTML
<div class="desktop">
<div class="yellow">lorem</div>
<div class="orange">lorem</div>
<div class="purple">lorem</div>
<div class="green">lorem</div>
</div>
CSS
* {
box-sizing: border-box;
}
main,
div {
display: flex;
padding: 1rem;
}
.desktop {
flex-direction: column;
flex-wrap: wrap;
height: 400px;
width: 100%;
align-items: center;
justify-content: center;
align-content: stretch;
}
.desktop > div {
flex: 1;
}
div.orange {
background-color: #FFAD77;
width: 30%;
flex: 0 0 70%;
margin-left: 10px;
}
div.yellow {
flex: 0 0 100%;
width: 70%;
background-color: #FFE377;
}
div.purple {
width: 30%;
margin-left: 10px;
background-color: #FF77C8;
}
#media(max-width: 480px) {
.desktop > div {
flex: 1;
width: 100%;
margin: 0 auto;
}
div.orange {
order: -1;
flex: 2;
}
div.yellow {
flex: 5;
}
div.purple {
flex: 1;
}
}
Try this tell me if there is a problem in my answer
html:
<div class="desktop">
<div class="yellow">lorem</div>
<div class="orange">lorem</div>
<div class="purple">lorem</div>
<div class="green">lorem</div>
</div>
css:
* {
box-sizing: border-box;
}
main,
div {
display: flex;
padding: 1rem;
}
.desktop {
flex-direction: column;
flex-wrap: wrap;
height: 400px;
width: 100%;
}
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;
flex: 2;
}
div[yellow] {
flex: 5;
}
div[purple] {
flex: 1;
}
div[purple] {
flex: 6;
}
}
output:
Related
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
I'm trying to create attached box layout with flexbox.
My example code is below.
My challenge is not mobile but desktop view - box item 1 and 2 are not 1 column in this layout. But once I use nesting like below then "order"doesn't work in flexbox.
parent "flex row" layout -> child "flex column" layout
I suppose "nest" with "mixed row and column flexbox" with "ordering"will not work together.
If someone has any idea to achieve it with flexbox, I want to get help..
.wrapper {
display: flex;
flex-direction: row;
flex-wrap:wrap;
margin: -10px -10px -10px 180px;
}
.wrapper > * {
padding: 10px;
flex: 1 100%;
}
.header {
background: tomato;
height: 60px;
width: 100%;
}
.breadcrumb{
background: green;
height: 30px;
width: 100%;
}
.footer {
background: lightgreen;
}
.main {
text-align: left;
background: deepskyblue;
flex: 1;
}
.aside-1 {
background: pink;
padding: 10px;
flex: 1;
}
.aside-2 {
background: gold;
padding: 10px;
flex: 1;
}
#media only screen and (max-width: 979px) {
.wrapper {
-webkit-flex-direction: column;
flex-direction: column;
-webkit-flex: 1;
flex: 1;
display:flex;
margin: -10px -10px -10px -10px ;
}
.main { order: 2; }
.aside-1 {
order :1;
}
.aside-2 {
order :3; }
.footer { order: 4; }
}
<div class="wrapper">
<header class="header">Header</header>
<div class="breadcrumb">Bread</div>
<div class="aside-1">Menuline1</div>
<div class="aside-2"><p>Menucontent</p>
<p>Menucontent</p>
<p>Menucontent</p>
<p>Menucontent</p>
<p>Menucontent</p>
<p>Menucontent</p>
<p>Menucontent</p></div>
<div class="main">
<p>Contents</p>
<p>Contents</p>
<p>Contents</p>
<p>Contents</p>
</div>
<footer class="footer">フッター</footer>
</div>
.wrapper {
margin: -10px -10px -10px 180px;
}
.wrapper > * {
padding: 10px;
}
.flex{
display: -webkit-box;/* Android4.3以前ブラウザ用 */
display: -webkit-flex;/* iOS8以前Safari用 */
display: flex;
flex-direction: row;
flex-wrap:wrap;
margin: -10px -20px -10px -10px;
flex: 1 100%;
}
.header {
background: tomato;
height: 60px;
width: 100%;
}
.breadcrumb{
background: green;
height: 30px;
width: 100%;
}
.footer {
background: lightgreen;
min-width: 100%;
}
.main {
-webkit-box-flex: 1;/*--- Android4.3以前ブラウザ用 ---*/
-webkit-flex: 1;/*--- iOS8以前Safari用 ---*/
flex: 1;
text-align: left;
background: deepskyblue;
flex: 1;
margin: -150px 0px 0px 0px;
}
.aside-1 {
background: pink;
padding: 10px;
max-width:320px;
height:130px;
}
.aside-2 {
-webkit-box-flex: 1;/*--- Android4.3以前ブラウザ用 ---*/
-webkit-flex: 1;/*--- iOS8以前Safari用 ---*/
flex: 1;
background: gold;
padding: 10px;
max-width:320px;
}
#media only screen and (max-width: 979px) {
.wrapper {
margin: -10px -10px -10px -10px ;
width:100%;
height:100%;
}
.flex{
-webkit-flex-direction: column;
flex-direction: column;
-webkit-flex: 1;
flex: 1;
display:flex;
}
.header{
height:10%;
}
.breadcrumb{
height:10%;
}
.aside-1
{
height: 10%;
min-width: 100%;
}
.main {
margin: 0 0 0 0 ;
order: 1; }
.aside-2 {
order :2;
min-width: 100%;}
}
<div class="wrapper">
<header class="header">ヘッダー画像</header>
<div class="breadcrumb">パンくずリスト</div>
<div class="aside-1">メニュー文言</div>
<div class="flex">
<div class="aside-2"><p>メニュー内容</p>
<p>メニュー内容</p>
<p>メニュー内容</p>
<p>メニュー内容</p>
<p>メニュー内容</p>
<p>メニュー内容</p>
<p>メニュー内容</p></div>
<div class="main">
<p>メインコンテンツがここに入ります</p>
<p>メインコンテンツがここに入ります</p>
<p>メインコンテンツがここに入ります</p>
<p>メインコンテンツがここに入ります</p>
</div>
</div>
<footer class="footer">フッター</footer>
</div>
As #yaycmyk said, box 3 needs absolute layout and to use flexbox only 2 and 3. It is not better solution but it can be one of solution... thank you guys and ladies.
I think you'll need to absolutely position box 3 conditionally to achieve this layout.
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
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>
I have an HTML page with header/content/footer that uses flexbox model and contains <details> tag.
I need to make details content use maximum available height, meaning that when in opened state its content should occupy all space in its container (except for summary of course).
Here is my HTML/CSS code (http://jsfiddle.net/rtojycvk/2/):
HTML:
<div class="wrapper">
<div class="header">Header</div>
<div class="main">
Some text before details
<details class="details" open>
<summary>Details summary</summary>
<div class="content">Details content</div>
</details>
</div>
<div class="footer">Footer</div>
</div>
CSS:
html, body {
height: 100%;
margin: 0; padding: 0;
}
.wrapper {
display: flex;
flex-direction: column;
width: 100%;
min-height: 100%;
}
.header {
height: 50px;
background-color: yellow;
flex: 0 0 auto;
}
.main {
background-color: cyan;
flex: 1;
display: flex;
flex-direction: column;
}
.footer {
height: 50px;
background-color: green;
flex: 0 0 auto;
}
.content {
background-color: blue;
color: white;
flex: 1;
}
.details {
background-color: red;
flex: 1;
display: flex;
flex-direction: column;
}
As you can see, the details tag itself takes all the available space, but not its content.
P.S. I need this to work only in Chrome.
http://jsfiddle.net/rtojycvk/16/
use position absolute on content, position relative on details, and calc() css (to offset the summary height)
.content {
background-color: lightgray;
color: black;
flex: 1;
display:flex;
position:absolute;
height: calc(100% - 18px);
width: 100%;
}
.details {
background-color: gray;
flex: 1;
display: flex;
flex-direction: column;
position:relative;
}
hope this helps! (I changed the colors cause they were a bit bright for me :p)
Absolute positioned .content and details relative.
fiddle
html, body {
height: 100%;
margin: 0; padding: 0;
}
.wrapper {
display: flex;
flex-direction: column;
width: 100%;
min-height: 100%;
}
.header {
height: 50px;
background-color: yellow;
flex: 0 0 auto;
}
.main {
background-color: cyan;
flex: 1;
display: flex;
flex-direction: column;
}
.footer {
height: 50px;
background-color: green;
flex: 0 0 auto;
}
.content {
background-color: blue;
color: white;
flex: 1;
position: absolute;
top: 3%;
bottom: 0;
height: 97%;
width: 100%;
}
details {
position: relative;
}
summary{
height: 3%;
}
.details {
background-color: red;
flex: 1;
display: flex;
flex-direction: column;
}
For those who prefer not to set absolutes positions, or can't do it, there is another way to accomplish it: using vh for height of .content:
html,
body {
margin: 0;
padding: 0;
height:100vh;
background: orange;
}
.wrapper {
display: flex;
flex-direction: column;
width: 100%;
height:100vh;
background: pink;
}
.header,
.footer {
height: 10vh;
min-height: 25px; /* (or max-height, or both!) */
max-height: 50px;
background-color: yellow;
flex: 0 0 auto;
}
.footer {
background-color: green;
}
.main {
background-color: cyan;
flex: 1;
display: flex;
flex-direction: column;
height: calc(100vh - 20vh); /* 10vh * 2 (.header + .footer sizes) */
}
.content {
background-color: blue;
color: white;
flex: 1;
display: flex;
flex-direction: column;
height: calc(100vh - 20vh); /* 10vh * 2 (.header + .footer sizes) */
}
.details {
background-color: red;
flex: 1;
display: flex;
flex-direction: column;
}
<div class="wrapper">
<header class="header">Header</header>
<main class="main">
Some text before details
<details class="details" open>
<summary>Details summary</summary>
<div class="content">Details content</div>
</details>
</main>
<footer class="footer">Footer</footer>
</div>
Fiddle's here: http://jsfiddle.net/ALXWebDev/wxm0v49c/
Hope it helps!