Creating special grid by using only flex functionalities - html

I have to create a layout which looks like:
I've prepared code like:
.red {
width: 50px;
height: 50px;
background-color: red;
margin-right: 20px;
}
.yellow {
width: 50px;
height: 50px;
background-color: yellow;
}
.blue {
width: 50px;
height: 50px;
background-color: blue;
justify-self: end;
}
.wrapper {
display: flex;
background-color: green;
width: 100%;
}
<div class="wrapper">
<div class="red"> </div>
<div class="yellow"> </div>
<div class="blue"> </div>
</div>
But this blue div don't want to align to the right side:
Here you can a have a preview of that:
https://jsfiddle.net/ncszob80/17/
I know that I can fix it with margin-left: auto css style for blue div.
But I'm wondering if there is some possibility of creating such layout only by using flex functionality.
So:
we can use only flex functionalities
there needs to be some margin between red div and yellow one
blue div needs to be at the very right
How to achieve that?

You wrote:
I know that I can fix it with margin-left: auto css style for blue div. But I'm wondering if there is some possibility of creating such layout only by using flex functionality.
Actually, margin-left: auto is flex functionality. It's a feature of flex layout.
From the flexbox specification:
ยง 8.1. Aligning with auto
margins
Also see:
In CSS Flexbox, why are there no "justify-items" and "justify-self" properties?
In summary, just use the auto margin. It's the cleanest, simplest and most efficient solution.

My best solution for you would be to change your DOM structure a little bit - but it accomplishes what you're looking for:
.left {
display: flex;
}
.red {
width: 50px;
height: 50px;
background-color: red;
margin-right: 20px;
}
.yellow {
width: 50px;
height: 50px;
background-color: yellow;
}
.blue {
width: 50px;
height: 50px;
background-color: blue;
}
.wrapper {
display: flex;
background-color: green;
width: 100%;
justify-content: space-between;
}
<div class="wrapper">
<div class="left">
<div class="red"> </div>
<div class="yellow"> </div>
</div>
<div class="right">
<div class="blue"> </div>
</div>
</div>
Basically, I wrapped your boxes in .left and .right, and then changed the .wrapper to justify-content: space-between so that the .right box is shoved to the right. Then, we make .left { display: flex; } to fix the issue with those boxes stacking without doing this, or changing the elements inside to display: inline; or display: inline-block;.

You can use nested flex boxes. Make the flex wrapper for your blue item and justify that to the end:
.wrapper {
display: flex;
background-color: green;
width: 100%;
}
.red {
width: 50px;
height: 50px;
background-color: red;
margin-right: 20px;
}
.yellow {
width: 50px;
height: 50px;
background-color: yellow;
}
.blueWrap {
width: 100%;
height: 50px;
display: flex;
justify-content: flex-end;
}
.blue {
width: 50px;
height: 50px;
background-color: blue;
}
<div class="wrapper">
<div class="red"> </div>
<div class="yellow"> </div>
<div class="blueWrap">
<div class="blue"></div>
</div>
</div>

Aside from changing your DOM structure or using the margin-left: auto fix CSS Grid is fantastic for this type of layout. I know you said only Flexbox but if you don't want any of the other solutions Grid might be a nice alternative. You can mix Flex functionality within the grid as well for finer control. I do this regularly to achieve the layout I'm in need of and it works well!
Happy coding!

Here is another idea if you don't want to consider margin:auto and without changing your html but like said in the accepted answer, margin is a feature of flexbox:
.red {
width: 50px;
height: 50px;
background-color: red;
margin-right: 20px;
}
.yellow {
width: 50px;
height: 50px;
background-color: yellow;
}
.blue {
width: 50px;
height: 50px;
background-color: blue;
order:1; /*make the blue the last element*/
}
.wrapper {
display: flex;
background-color: green;
width: 100%;
}
.wrapper:after {
content:"";
flex-grow:1; /*make this hidden element to take all the space and push the blue*/
}
<div class="wrapper">
<div class="red"> </div>
<div class="yellow"> </div>
<div class="blue"> </div>
</div>

Related

Dynamic NavBar in which the logo is always in the middle

My goal: A responsive navbar where the logo is always in the middle and an element
is always on the left. Depending on the context (page dependent), buttons can be
displayed in the right area or not.
My approach: I use a flexbox for the navbar. I have three divs in the flexbox. I have given all divs a fixed width. The middle box is also a flexbox. The div with a logo is located there. I position the logo on the right edge of the middle flexbox. The div with the logo has a fixed width (80px).
The problem: The approach works but I don't find this way very nice. Because the widths are dependent on each other. If you would change the logo and it would be wider or narrower then you would have to adjust the relative width of the middle and right box. The second problem is if the device smaller as 900px then this solution dont work.
Question: What other possibilities are there and what possibilities would resolve this "width" dependency?
#app {
margin: 0 auto;
max-width: 900px;
width:100%;
}
header {
height: 80px;
display: flex;
justify-content:space-between;
}
.header-left {
width:20%;
background: green;
}
.header-middle {
width:34%;
background: gray;
display: flex;
justify-content:flex-end;
}
.header-right {
width:46%;
background: green;
}
.logo {
background-color: red;
width:80px;
height: 80px;
text-align:center;font-size:70px;
}
<div id="app">
<small>width: 900px</small>
<header>
<div class="header-left">Burger Menu</div>
<div class="header-middle">
<div class="logo">
I
</div>
</div>
<div class="header-right">Context Buttons</div>
</header>
<div>
<div style="width:50%; background: black;color:white; text-align:center;">Controller Div 50%</div>
</div>
</div>
You can use flex-grow: 1 on the left and right elements, the middle element will be in center naturally. In this case, you don't need to set widths on elements.
#app {
margin: 0 auto;
max-width: 900px;
width:100%;
}
header {
height: 80px;
display: flex;
justify-content:space-between;
}
.header-left {
flex-grow: 1;
background: green;
}
.header-middle {
background: gray;
display: flex;
justify-content:flex-end;
}
.header-right {
flex-grow: 1;
background: green;
}
.logo {
background-color: red;
width:80px;
height: 80px;
text-align:center;font-size:70px;
}
<div id="app">
<small>width: 900px</small>
<header>
<div class="header-left">Burger Menu</div>
<div class="header-middle">
<div class="logo">
I
</div>
</div>
<div class="header-right">Context Buttons</div>
</header>
<div>
<div style="width:50%; background: black;color:white; text-align:center;">Controller Div 50%</div>
</div>
</div>
Since you're looking for different possibilities i'll suggest you to take the approch used by Tepken Vannkorn :
Centering brand logo in Bootstrap Navbar
Based on your comments, I would suggest the following code as a simple solution.
I have added a max-width value to your .logo CSS class and I have also moved your inline CSS from the front-end code, and created a .controller CSS class for it.
#app {
margin: 0 auto;
max-width: 900px;
width: 100%;
}
header {
height: 80px;
display: flex;
justify-content: space-between;
}
.header-left {
width: 20%;
background: green;
}
.header-middle {
width: 34%;
background: gray;
display: flex;
justify-content: flex-end;
}
.header-right {
width: 46%;
background: green;
}
.logo {
background-color: red;
width: 80px;
height: 80px;
text-align: center;
font-size: 70px;
max-width: 80px;
}
.controller {
width: 50%;
background: black;
color: white;
text-align: center;
}
<div id="app">
<small>width: 900px</small>
<header>
<div class="header-left">Burger Menu</div>
<div class="header-middle">
<div class="logo">
I
</div>
</div>
<div class="header-right">Context Buttons</div>
</header>
<div>
<div class="controller">Controller Div 50%</div>
</div>
</div>
A solution would be to use a mix of flex and position: absolute. Then you need only the left and the right container. the logo you can center with position left: left: calc(50% - calc(80px / 2));. The 80px is the width from your logo.
* {
margin: 0;
padding: 0;
}
#app {
margin: 0 auto;
max-width: 900px;
width:100%;
}
.header {
display: flex;
justify-content: space-between;
height: 80px;
background: yellow;
position: relative;
}
.header-left {
background-color: green;
width: 20%
}
.header-right {
background-color: green;
width: 44%;
}
.logo {
background-color: red;
width:80px;
height: 80px;
text-align:center;
font-size:70px;
position: absolute;
left: calc(50% - calc(80px / 2));
}
<div id="app">
<div class="header">
<div class="header-left">left</div>
<div class="logo">X</div>
<div class="header-right">right</div>
</div>
<div style="width:50%; background: black;">Controller Div 50%</div>
</div>

Put two outside divs above center div on smaller screen

The subject says it all, but I am looking for a clean simple way to do this. Essentially think of it like this:
[A][__B_][A]
to
[A][A]
[__B_]
Hopefully that is clear enough but I can elaborate if need be.
Thanks in advance!
you can use flexbox order for that
.flex-container {
padding: 0;
margin: 0;
display: flex;
flex-flow: row wrap;
}
.flex-item {
box-sizing: border-box;
background: green;
padding: 20px;
width: 20%;
height: 100px;
border: 1px solid white;
color: white;
text-align: center;
}
#media screen and (max-width: 900px){
.flex-item {
background: green;
width: 50%;
height: 100px;
color: white;
text-align: center;
}
.flex-item:nth-of-type(2) {
order: 3;
width: 100%
}
}
<div class="flex-container">
<div class="flex-item">div a</div>
<div class="flex-item">div b</div>
<div class="flex-item">div a</div>
</div>
read more here: https://developer.mozilla.org/en/docs/Web/CSS/order
If you're starting with 3 elements in a row together, but you need element B to be outside on it's own, you will want to utilize flexbox.
You'd be focusing on the order property for the selectors, and using flex-grow on element B. Read through that document to get an idea on how to set that up, or to make sure that's exactly what you need. Otherwise, you can turn to jQuery.
You can do this by putting all three divs inside one div:
<div class="allthree">
<div class="twoas">
<div class="a"></div>
<div class="a"></div>
</div>
<div class="oneb">
<div class="b"></div>
</div>
</div>
Now add some CSS to this so the b is 100% width and the a is 50% width. Make sure the a is display: inline-block;
.allthree {
width: <your-width>
}
.allthree .twoas {
width: 100%;
}
.allthree .twoas .a {
display: inline-block;
width: 50%;
}
.allthree .oneb {
width: 100%;
}
.allthree .oneb .b {
width: 100%;
}

Floating div to go below partner

Consider the following HTML structure,
<div class='floated' id='div1'></div>
<div class='floated' id='div2'></div>
<div class='floated' id='div3'></div>
with the following CSS:
.floated {
width: 50%;
float: left;
}
#div1 {
height: 300px;
background-color:red;
}
#div2 {
height: 30px;
background-color: green;
}
#div3 {
height: 30px;
background-color: yellow;
}
This way, #div1 will take up a 300px tall part of the left side of the page, while #div2 and #div3 will get floated to the right side of the page. How could I set up my CSS, so #div1 and #div2 takes up a single row(of height 300px, the maximum height of the two), and #div3 will be placed right below #div1?
I am not controling the height of these divs, this is dynamic, it is possible that sometimes the first one will be only 20 pixels, and the second one will be 1000 pixels, and the other way around is also a possibility
Here's a fiddle: https://jsfiddle.net/1u55fukj/
You can use Flexbox on parent element (body in this case) and use flex-wrap: wrap. This will always make both div's in same row equal height or equal to height of taller one DEMO
body {
display: flex;
flex-wrap: wrap;
}
.floated {
flex: 0 0 50%;
}
#div1 {
height: 300px;
background-color: red;
}
#div2 {
background-color: green;
}
#div3 {
height: 30px;
background-color: yellow;
}
<div class='floated' id='div1'></div>
<div class='floated' id='div2'></div>
<div class='floated' id='div3'></div>
If there will be only 2 divs in row, then you can try to give clear:left to odd child.
.floated {
width: 50%;
float: left;
}
#div1 {
height: 300px;
background-color: red;
}
#div2 {
height: 30px;
background-color: green;
}
#div3 {
height: 30px;
background-color: yellow;
}
div.floated:nth-child(odd) {
clear: left
}
<div class='floated' id='div1'>
</div>
<div class='floated' id='div2'>
</div>
<div class='floated' id='div3'>
</div>
flexbox is your best option i think.
you could use a div container and then use display flex
.container{
height: 500px;
width: 100%;
display: flex;
flex-flow: row wrap;
justify-content: center;
}
.floated {
width: 50%;
}
#div1 {
height: 30%;
background-color:red;
}
#div2 {
height: 60%;
background-color: green;
}
#div3 {
height: 40%;
background-color: yellow;
}
<div class="container">
<div class="floated" id="div1"></div>
<div class="floated" id="div2"></div>
<div class="floated" id="div3"></div>
</div>
you can also center the 3rd div and a lot more :D. Flexbox have a good crossbrowsing support using -moz-, -webkit- etc,

Align 2 divs in same line without using float

I am a new learner in web designing and practicing websites. I want to align 2 divs in one line without using float. I have a parent div with width 1400px. I want 2 child divs of width 600px each to align next to each other and have equal margin from both sides. Below is my code. Please suggest.
Also, what changes does float make to DOM? I observed that if I use float I need to specify the height as well? Is it the case or I was making some mistake in understanding the role of float?
<html>
<head>
<title>
My Page
</title>
</head>
<body>
<div class="main">
<div class="child1">Child 1</div>
<div class="child2">Child 2</div>
</div>
</body>
</html>
.main{
width:1400px;
background-color:#c3c3c3;
position: relative;
display: inline-block;
}
.child1{
background-color:#666;
width: 600px;
margin:auto;
}
.child2{
background-color:#888;
width : 600px;
margin:auto;
}
you can do like this.
.main {
width: 1400px;
background-color: #c3c3c3;
position: relative;
text-align: center;
}
.child1 {
background-color: #666;
width: 600px;
margin: auto;
display: inline-block;
}
.child2 {
background-color: #888;
width: 600px;
margin: auto;
display: inline-block;
}
<div class="main">
<div class="child1">Child 1</div>
<div class="child2">Child 2</div>
</div>
Or you can Improve you css to this.
.main {
width: 1400px;
background-color: #c3c3c3;
position: relative;
text-align: center;
}
.main div {
display: inline-block;
width: 600px;
margin: auto;
}
.main div.child1 {
background-color: #666;
}
.main div.child2 {
background-color: #888;
}
<div class="main">
<div class="child1">Child 1</div>
<div class="child2">Child 2</div>
</div>
You can use flexbox like this:
.main {
display: flex;
justify-content: space-between;
}
Can be done with:
.main div { display: inline-block; }
Expect a whitespace between the divs.
This should do the trick (at least roughly):
.main{
width:1400px;
background-color:#c3c3c3;
position: relative;
display: table-row;
}
.child1{
background-color:#666;
width: 600px;
margin:auto;
display: table-cell;
}
.child2{
background-color:#888;
width : 600px;
margin:auto;
display: table-cell;
}
Float is really intended to put a picture (or a similar element) on one side of the page and have the text flow around it. It's often "abused" to pack elements next to each other horizontally, but that creates its own problems.
A lot of the answers you've been given are good, and people have been doing this since CSS became a thing. Another way you can do it, and really whichever method you'd like depends solely on your circumstances is by using position:relative on the parent wrapper, and position:absolute any the child elements.
.wrapper {
border: 1px solid red;
min-height: 50vh;
min-width: 100vw;
position: relative;
}
.wrapper > div {
position: absolute;
}
.wrapper .first {
top: 0;
left: 0;
width: 48vw;
border:1px dotted green;
height:100%;
}
.wrapper .second {
top: 0;
right: 0;
width: 48vw;
border:1px dashed orange;
height:100%;
}
<div class="wrapper">
<div class="first">
This is content number 1
</div>
<div class="second">
This is content number two.
</div>
</div>
Another way is by setting the container div to display as a row, and then have the two child elements be displayed as table cells. Tables were kind of the old-go-to back before CSS became extensive (can you believe there was a time before border-radius?)
.wrapper {
display: table-row;
background-color: red;
width: 100%;
height: 50vh;
}
.wrapper > div {
display: table-cell;
width: 48%;
}
.first {
border: 1px solid orange;
}
.second {
border: 1px dotted green;
}
<div class="wrapper">
<div class="first">
First Child
</div>
<div class="second">
Second Child
</div>
</div>
Really there's a bunch, you just need to figure out which one works best for you.

Vertically aligning images in magnific popup

I am trying to align my images in the web page's gallery vertically so all the bottoms match up on one line? I am using magnific popup. How can I do this? Currently they are centered vertically like so:
If you are looking for help with HTML and CSS you should post what you have tried so far or something else otherwise. In any case I'm going to assume you want a HTML/CSS based answer and make a suggestion to use flex box layout like so:
.parent {
display: flex;
align-content: flex-end;
align-items: baseline;
}
.red {
height: 100px;
width: 50px;
background: red;
}
.blue {
height: 200px;
width:200px;
background: blue;
}
.green {
height: 50px;
width: 80px;
background: green;
}
<div class="parent">
<div class="red"></div>
<div class="blue"></div>
<div class="green"></div>
</div>
Flexbox isn't supported in IE9 or earlier so be careful about that.
Alternatively, you could add display: inline-block and vertical-align: bottom to the images (divs in the example)
.parent > div {
display: inline-block;
vertical-align: bottom;
}
.red {
height: 100px;
width: 50px;
background: red;
}
.blue {
height: 200px;
width:200px;
background: blue;
}
.green {
height: 50px;
width: 80px;
background: green;
}
<div class="parent">
<div class="red"></div>
<div class="blue"></div>
<div class="green"></div>
</div>