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>
Related
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:
I am a backend programmer by profession. But I have just started to learn flexbox and I want to hit the sky with flexbox.
So, I created a simplest design but which looks most complicated to me when creating it using flexbox.
Here is the design:
Guys, I am not able to figure out, how to use flexbox in such a case as there is no row or column. I don't know but is there anything like rowspan or colspan in flexbox that I can use to arrange these divs as shown in image above?
Here is my code:
HTML:
<div class="wrapper">
<div class="div-wrapper1">
<div class="inner-wrapper1">
<div class="div1"></div>
<div class="fake1"></div>
</div>
<div class="div2"></div>
</div>
<div class="div-wrapper2">
<div class="div3"></div>
<div class="inner-wrapper2">
<div class="fake2"></div>
<div class="div4"></div>
</div>
</div>
<div class="div-center"></div>
</div>
CSS:
.wrapper {
height: 200px;
width: 200px;
border: 1px solid black;
display: flex;
flex-direction: column;
}
.div-wrapper1 {
display: flex;
flex: 1;
}
.div-wrapper2 {
display: flex;
flex: 1
}
.inner-wrapper1 {
display: flex;
flex: 3;
flex-direction: column;
}
.div1 {
background-color: red;
display: flex;
flex: 3
}
.fake1 {
display: flex;
flex: 1
}
.div2 {
background-color: green;
display: flex;
flex: 2
}
.div3 {
background-color: blue;
display: flex;
flex: 2
}
.inner-wrapper2 {
display: flex;
flex: 3;
flex-direction: column;
}
.div4 {
background-color: yellow;
display: flex;
flex: 3
}
.fake2 {
display: flex;
flex: 1
}
.div-center {
background-color: black;
}
This is my output:
Here is the codepen
Maybe a solution is to simply add a negative margin to .div-wrapper1 and you will get the exact layout :
.wrapper {
height: 200px;
width: 200px;
border: 1px solid black;
display: flex;
flex-direction: column;
}
.div-wrapper1 {
display: flex;
flex: 1;
}
.div-wrapper2 {
display: flex;
flex: 1;
margin-top: -30px;
}
.div-wrapper3 {
display: flex;
flex: 1
}
.inner-wrapper1 {
display: flex;
flex: 3;
flex-direction: column;
}
.div1 {
background-color: red;
display: flex;
flex: 3
}
.fake1 {
display: flex;
flex: 1
}
.div2 {
background-color: green;
display: flex;
flex: 2
}
.div3 {
background-color: blue;
display: flex;
flex: 2
}
.inner-wrapper2 {
display: flex;
flex: 3;
flex-direction: column;
}
.div4 {
background-color: yellow;
display: flex;
flex: 3
}
.fake2 {
display: flex;
flex: 1
}
.div-center {
background-color: black;
}
<div class="wrapper">
<div class="div-wrapper1">
<div class="inner-wrapper1">
<div class="div1"></div>
<div class="fake1"></div>
</div>
<div class="div2"></div>
</div>
<div class="div-wrapper2">
<div class="div3"></div>
<div class="inner-wrapper2">
<div class="fake2"></div>
<div class="div4"></div>
</div>
</div>
<div class="div-center"></div>
</div>
And if you want here is another solution without any negative values and a content inside the white part (simply adjust height/width as you need) :
.first,
.second {
display: flex;
height: 100px;
width: 200px;
}
.first:before {
content: "";
background: red;
flex: 3;
}
.first:after {
content: "";
background: green;
flex: 2;
}
.second:before {
content: "";
background: blue;
flex: 2;
}
.second:after {
content: "";
background: yellow;
flex: 3;
}
.fake {
display: flex;
height: 20px;
width: 200px;
}
.fake a {
flex: 1;
text-align: center;
}
.fake:before {
content: "";
background: blue;
flex: 2;
}
.fake:after {
content: "";
background: green;
flex: 2;
}
<div class="first">
</div>
<div class="fake">
link
</div>
<div class="second">
</div>
Here is another solution by simply using multiple linear-gradient:
.box {
display: flex;
height: 220px;
width: 200px;
justify-content: center;
align-items: center;
background-image:linear-gradient(to right,red 66%,green 0%),
linear-gradient(to right,blue 33%,white 0%,white 66%,green 66%),
linear-gradient(to right,blue 33%,yellow 0%);
background-size:100% 100px,100% 20px,100% 100px;
background-position:top,center,bottom;
background-repeat:no-repeat;
}
<div class="box">
link
</div>
I'm trying to build media query, which will be working like on the sketch. Any suggestion?
.container {
display: flex;
flex-direction: row;
justify-content: space-between;
background-color: lightblue;
width: 100%;
padding: .5rem;
box-sizing: border-box;
}
.name {
background-color: white;
padding: 1rem;
margin: .25rem;
flex-basis: 40px
}
.options {
display: flex;
flex-direction: row;
}
.option {
background-color: white;
padding: 1rem;
margin: .25rem;
flex-basis: 80px;
}
.action {
background-color: white;
padding: 1rem;
margin: .25rem;
}
#media (max-width: 350px){
.name {order: 1}
.action {order: 2}
.options {order: 3}
.container {
flex-direction: column;
flex-wrap: wrap;
}
}
<div class="container">
<div class="name">Lorem ipsum</div>
<div class="options">
<div class="option">2</div>
<div class="option">3</div>
<div class="option">4</div>
</div>
<div class="action">
5
</div>
</div>
I have already started, but I'm not really satisfied :). I need something more stable, as I will want to use it here later.
https://codepen.io/danzawadzki/pen/mwPYMz
At this moment I'm changing order and flex-direction in media query, but it's not good enough. Box number 1 will contain name of the segment, so it should have fixed width. There will be multiple items like that in one column, so I would prefer to keep it looks clean with same proportions.
Use this may be it will work for you
#media (max-width: 350px){
.options {order: 3; flex:0 0 100%;}
.container {
flex-wrap: wrap;
}
}
If you change your #media and remove flex-direction: column and add flex-basis: 100% to the option, it will flow as your image shows
#media (max-width: 350px){
.options {
order: 1; flex-basis: 100%;
}
.container {
flex-wrap: wrap;
}
}
Note, I also removed the .name and .action rules, as they are not necessary
Fiddle demo
Stack snippet
.container {
display: flex;
flex-direction: row;
justify-content: space-between;
background-color: lightblue;
width: 100%;
padding: .5rem;
box-sizing: border-box;
}
.name {
background-color: white;
padding: 1rem;
margin: .25rem;
flex-basis: 40px
}
.options {
display: flex;
flex-direction: row;
}
.option {
background-color: white;
padding: 1rem;
margin: .25rem;
flex-basis: 80px;
}
.action {
background-color: white;
padding: 1rem;
margin: .25rem;
}
#media (max-width: 350px){
.options {
order: 1; flex-basis: 100%;
}
.container {
flex-wrap: wrap;
}
}
<div class="container">
<div class="name">Lorem ipsum</div>
<div class="options">
<div class="option">2</div>
<div class="option">3</div>
<div class="option">4</div>
</div>
<div class="action">
5
</div>
</div>
Updated
By setting .options { flex-grow: 1; } and .option { flex: 1 1 80px; }, you can have the options/option elements to fill the remaining space on wider screens
Fiddle demo 2
Stack snippet 2
.container {
display: flex;
flex-direction: row;
justify-content: space-between;
background-color: lightblue;
width: 100%;
padding: .5rem;
box-sizing: border-box;
}
.name {
background-color: white;
padding: 1rem;
margin: .25rem;
flex-basis: 40px
}
.options {
flex-grow: 1;
display: flex;
}
.option {
background-color: white;
padding: 1rem;
margin: .25rem;
flex: 1 1 80px;
}
.action {
background-color: white;
padding: 1rem;
margin: .25rem;
}
#media (max-width: 350px){
.options {
order: 1; flex-basis: 100%;
}
.container {
flex-wrap: wrap;
}
}
<div class="container">
<div class="name">Lorem ipsum</div>
<div class="options">
<div class="option">2</div>
<div class="option">3</div>
<div class="option">4</div>
</div>
<div class="action">
5
</div>
</div>
I have tried to emulate the excellent flexbox tutorials by Wes Bos. I wanted to convert one specific tutorial he has on responsive flexbox menu. But I wanted my menu to be done with mobile first so I did my media queries with min-width.
But I am not able to make it work properly on the default mobile layout. In the menu created by Wes, the li items are stacked upon each other and the social icons at the bottom have flex:1 1 25%. But my social icons are also stacked.
On the other breakpoints my layout follows the one that Wes created.
I have set up a codepen for my code.
.flex-nav ul {
list-style: none;
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
}
.flex-nav .social {
flex: 1 1 25%;
}
#media all and (min-width:500px) {
.flex-nav li {
flex: 1 1 50%;
}
.flex-nav ul {
flex-wrap: wrap;
flex-direction: row;
}
.flex-nav ul {
border: 1px solid black;
}
}
#media all and (min-width:800px) {
.flex-nav li {
flex: 3;
}
.flex-nav .social {
flex: 1;
}
}
This is your default code (no media queries applied):
.flex-nav ul {
display: flex;
flex-direction: column;
}
.flex-nav .social {
flex: 1 1 25%;
}
Yes, you've given each social media icon a flex-basis: 25%.
BUT, your container is flex-direction: column.
So the flex rule applied to your social media icons works vertically, not horizontally.
Consider this method instead:
.flex-nav ul {
display: flex;
flex-wrap: wrap;
}
li {
flex: 0 0 100%; /* sized to fit one item per row */
}
.flex-nav .social {
flex: 0 0 25%; /* sized to fit four items per row */
}
revised demo
I've created a container for the social links so it's more easy (at least for me) structure the menu.
SEE IN CODEPEN
Here the html:
<div class="wrapper">
<nav class="flex-nav">
<ul>
<li>item01</li>
<li>item02</li>
<li>item03</li>
<li>item04</li>
<li>item05</li>
<li>item06</li>
<div class="social-container">
<li class="social"><i class="fa fa-gift"></i></li>
<li class="social"><i class=" fa fa-glass"></i></li>
<li class="social"><i class=" fa fa-calendar"></i></li>
<li class="social"><i class=" fa fa-cutlery"></i></li>
</div>
</ul>
</nav>
</div>
CSS:
html {
box-sizing: border-box;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
body {
font-family: sans-serif;
margin: 0;
}
a {
color: white;
font-weight: 100;
letter-spacing: 2px;
text-decoration: none;
background: rgba(0, 0, 0, 0.2);
padding: 20px 5px;
display: inline-block;
width: 100%;
text-align: center;
transition: all 0.5s;
}
a:hover {
background: rgba(0, 0, 0, 0.3);
}
.wrapper {
max-width: 1000px;
margin: 0 auto;
padding: 50px;
}
.flex-nav ul {
list-style: none;
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
height: 100%; /* ADDED */
}
.flex-nav .social {
flex: 1 1 25%;
}
.social-container { //just make it flex container
display: flex;
width: 100%;
}
#media all and (min-width:500px) {
.flex-nav li {
flex: 1 1 50%;
}
.flex-nav ul {
flex-wrap: wrap;
flex-direction: row;
}
.flex-nav ul {
border: 1px solid black;
}
}
#media all and (min-width:800px) {
.flex-nav li {
flex: 1;
}
.flex-nav .social {
/*flex: 1;*/
}
.social-container {
flex: 2; /* set the value as many as you want */
}
.flex-nav ul { //change the direction
flex-direction: row;
flex-wrap: no-wrap;
}
}
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>