Avoid flex-wrap gap for different size divs? - html

I'm trying to achieve two different looks based on browser resolution only with CSS. The first fiddle works perfectly besides the weird space due to the rows needing to be the same size:
HTML:
<div id="box-container">
<div id="box1"></div>
<div id="box2"></div>
<div id="box3"></div>
<div id="box4"></div>
</div>
Mobile:
https://jsfiddle.net/c1xLqmdc/4/
CSS:
#box-container{
display:flex;
flex-flow: wrap;
}
#box1{
background-color:cyan;
width:50%;
height:200px;
order:1
}
#box2{
background-color:magenta;
width:50%;
height:150px;
order:2;
}
#box3{
background-color:yellow;
width:50%;
height:100px;
order:3;
}
#box4{
background-color:black;
width:50%;
height:150px;
order:4;
}
#box1,#box2,#box3,#box4{
width:100%;
}
Desktop:
https://jsfiddle.net/c1xLqmdc/
CSS:
#box-container{
display:flex;
flex-flow: wrap;
}
#box1{
background-color:cyan;
width:50%;
height:200px;
order:1
}
#box2{
background-color:magenta;
width:50%;
height:150px;
order:2;
}
#box3{
background-color:yellow;
width:50%;
height:100px;
order:3;
}
#box4{
background-color:black;
width:50%;
height:150px;
order:4;
}
/*#box1,#box2,#box3,#box4{
width:100%;
}*/
So I tried switching to columns to fix the gap, and now it works perfectly for desktop but they are in the wrong order for mobile.
HTML:
<div id="box-container">
<div id="box-column-left">
<div id="box1"></div>
<div id="box3"></div>
</div>
<div id="box-column-right">
<div id="box2"></div>
<div id="box4"></div>
</div>
</div>
Mobile:
https://jsfiddle.net/ar90Ly20/2/
CSS:
#box-container{
display:flex;
flex-flow:row wrap;
}
#box-column-left{
width:100%;
}
#box-column-right{
width:100%;
}
#box1{
background-color:cyan;
width:100%;
height:200px;
order:1
}
#box2{
background-color:magenta;
width:100%;
height:150px;
order:2;
}
#box3{
background-color:yellow;
width:100%;
height:100px;
order:3;
}
#box4{
background-color:black;
width:100%;
height:150px;
order:4;
}
Desktop:
https://jsfiddle.net/ar90Ly20/
CSS:
#box-container{
display:flex;
flex-flow:row wrap;
}
#box-column-left{
width:50%;
}
#box-column-right{
width:50%;
}
#box1{
background-color:cyan;
width:100%;
height:200px;
order:1
}
#box2{
background-color:magenta;
width:100%;
height:150px;
order:2;
}
#box3{
background-color:yellow;
width:100%;
height:100px;
order:3;
}
#box4{
background-color:black;
width:100%;
height:150px;
order:4;
}
Is this possible to accomplish the first mobile example, and the second desktop example without changing the HTML?

The simple solution would be to just offset the top margin for box 4.
FIDDLE
HTML:
<div id="box-container">
<div id="box1"></div>
<div id="box2"></div>
<div id="box3"></div>
<div id="box4"></div>
</div>
CSS:
#box-container{
display:flex;
flex-flow: wrap;
}
#box1{
background-color:cyan;
width:50%;
height:200px;
order:1
}
#box2{
background-color:magenta;
width:50%;
height:150px;
order:2;
}
#box3{
background-color:yellow;
width:50%;
height:100px;
order:3;
}
#box4{
background-color:black;
width:50%;
height:150px;
margin-top: -50px;
order:4;
}
#media screen and (max-width: 425px) {
#box-container{
flex-flow: row wrap;
}
#box4{
margin-top: 0px;
}
#box1,#box2,#box3,#box4{
width:100%;
}
}

Related

float div to left of parent div not working

With my current code, how do I make the purple div stick to the left side of the green div? I tried float:left which didn't work. I got close when adding position:absolute; and left:50%; to my purple div class but when the screen resized the div fell off screen. Is there a quick way to float the purple div to the left of the green one so it's not in the center?
html, body{
margin:0;
height:100%;
width:100%;
}
#container{
background-color:pink;
height:91%;
width:100%;
display:flex;
}
#left{
width:50%;
background-color:lightblue;
display:flex;
position:relative;
}
#right{
width:50%;
background-color:lightgreen;
display:flex;
}
#logo {
left:0px;
width: 100%;
margin:auto;
max-width:calc(80vh - 25px);
background-color:purple;
}
#logo:before {
content:"";
display:flex;
padding-top: 100%;
}
<div id="container">
<div id="left"></div>
<div id="right">
<div id="logo"></div>
</div>
</div>
Try like this.
html, body{
margin:0;
height:100%;
width:100%;
}
#container{
background-color:pink;
height:91%;
width:100%;
display:flex;
}
#left{
width:50%;
background-color:lightblue;
display:flex;
position:relative;
}
#right{
width:50%;
background-color:lightgreen;
display:flex;
}
#logo {
left:0px;
width: 100%;
margin:auto;
margin-left: 0;
max-width:calc(80vh - 25px);
background-color:purple;
}
#logo:before {
content:"";
display:flex;
padding-top: 100%;
}
<div id="container">
<div id="left"></div>
<div id="right">
<div id="logo"></div>
</div>
</div>

Flexbox float div to right

I need the yellow div to float beside the the purple square. Orange on top, pink on the bottom and yellow to the left of the square. It worked when I took off the flex-wrap:wrap; from the right div but then all three divs went to the left. Is there anyway to just have the yellow div float to the right of the purple square to take up the remainder of the green area while the other two stay in their current spots?
html, body{
margin:0;
height:100%;
width:100%;
}
#container{
background-color:pink;
height:91%;
width:100%;
display:flex;
}
#left{
width:50%;
background-color:lightblue;
display:flex;
position:relative;
}
#right{
width:50%;
background-color:lightgreen;
display: flex;
flex-direction: column;
}
#right>* {
flex: 1;
}
#logo {
width: 100%;
margin:auto;
max-width:calc(80vh - 25px);
background-color:purple;
margin-left:0;
}
#logo:before {
content:"";
display:flex;
padding-top: 100%;
}
#rightsidetop{
background-color:orange;
}
#rightsideright{
background-color:yellow;
}
#rightsidebottom{
background-color:pink;
}
<div id="container">
<div id="left"></div>
<div id="right">
<div id="rightsidetop"></div>
<div id="logo"></div>
<div id="rightsideright"></div>
<div id="rightsidebottom"></div>
</div>
</div>
This should work as intended.
html, body{
margin:0;
height:100%;
width:100%;
}
#container{
background-color:pink;
height:91%;
width:100%;
display:flex;
}
#left{
width:50%;
background-color:lightblue;
display:flex;
position:relative;
}
#right{
width:50%;
background-color:lightgreen;
display: flex;
flex-direction: column;
}
#right>* {
flex: 1;
}
#logo {
width: 100%;
max-width:calc(80vh - 25px);
background-color:purple;
}
#logo:before {
content:"";
display:flex;
padding-top: 100%;
}
#rightsidetop{
background-color:orange;
}
#rightsideright{
background-color:yellow;
flex: 1;
}
#rightsidebottom{
background-color:pink;
}
.wrapper {
display: flex;
}
<div id="container">
<div id="left"></div>
<div id="right">
<div id="rightsidetop"></div>
<div class="wrapper">
<div id="logo"></div>
<div id="rightsideright"></div>
</div>
<div id="rightsidebottom"></div>
</div>
</div>
Edit: To make this answer a bit more universal, here is how the principle works: if you want div A to grow up to a max size, and div B to fill the remaining space, you have to make sure that:
The container is display: flex
A has width: 100% and has a max-width
B has flex: 1
Take note that if A would have flex: 1 as well, its greedy 100% would be overruled by the more generous flexing rule. Therefore the most minimal working example is:
.container {
display: flex;
}
.up-to-max {
width: 100%;
max-width: 100px;
background: red;
}
.filler {
flex: 1;
background: green;
}
<div class="container">
<div class="up-to-max">A</div>
<div class="filler">B</div>
</div>
(Watch in full page to resize the window)
You have to modify your html a bit and to adapt the css.
On a side note, you shouldn't use that much id, use classes.
Also, use flex-basis to give flex children a width.
html, body{
margin:0;
height:100%;
width:100%;
}
#container{
background-color:pink;
height:91%;
width:100%;
display:flex;
}
#left{
width:50%;
background-color:lightblue;
display:flex;
position:relative;
}
#right{
width:50%;
background-color:lightgreen;
display: flex;
flex-direction: column;
}
#right>*,
#right>* > *{
flex: 1;
}
#logo {
width: 100%;
margin:auto;
max-width:calc(80vh - 25px);
background-color:purple;
margin-left:0;
}
#logo:before {
content:"";
display:flex;
padding-top: 100%;
}
#rightsidetop{
background-color:orange;
}
#rightsideright{
background-color:yellow;
}
#rightsidebottom{
background-color:pink;
}
.wrapper {
display: flex;
}
<div id="container">
<div id="left"></div>
<div id="right">
<div id="rightsidetop"></div>
<div class="wrapper">
<div id="logo"></div>
<div id="rightsideright"></div>
</div>
<div id="rightsidebottom"></div>
</div>
</div>

flexbox div goes off screen on small screen

Code first:
html {
display:flex;
width:100%;
height:100%;
}
body {
display:flex;
flex:1;
}
.container {
display:flex;
flex:1;
overflow-y:auto;
flex-direction:column;
justify-content:center;
align-items:center;
}
.block1 {
justify-content:center;
background-color:green;
display:flex;
width:300px;
min-height:150px;
}
.block2 {
background-color:blue;
display:flex;
min-height:300px;
width:500px;
}
<div class="container">
<div class="block1">
<img src="https://tse2.mm.bing.net/th?id=OIP.M252f960f4a4f32c22914d8d87623f066o0&pid=15.1">
</div>
<div class="block2"></div>
</div>
I have two blocks in a container. I want them centered on the screen.
The issue is when the screen height is small, I have a scrollbar that appear but the first block have a part that go offscreen (is invisible)
To reproduce, decrease the height of the jsfiddle preview window. You will understand what I mean by going off screen.
The expected behavior is to let the scroll bar appear and keep the div visible.
I tried by setting flex-shrink to 0 on every element but it isn't working...
You can make use of Flexbox's auto margins.
Remove justify-content: center from .container.
Add margin-top: auto to .block1.
Add margin-bottom: auto to .block2.
html {
display:flex;
width:100%;
height:100%;
}
body {
display:flex;
flex:1;
}
.container {
display:flex;
flex:1;
overflow-y:auto;
flex-direction:column;
align-items:center;
}
.block1 {
justify-content:center;
background-color:green;
display:flex;
width:300px;
min-height:150px;
margin-top: auto;
}
.block2 {
background-color:blue;
display:flex;
min-height:300px;
width:500px;
margin-bottom: auto;
}
<div class="container">
<div class="block1">
<img src="https://tse2.mm.bing.net/th?id=OIP.M252f960f4a4f32c22914d8d87623f066o0&pid=15.1">
</div>
<div class="block2"></div>
</div>
You can add position: absolute; top: 0 to the container:
html {
display:flex;
width:100%;
height:100%;
}
body {
display:flex;
flex:1;
}
.container {
display:flex;
flex:1;
overflow-y:auto;
flex-direction:column;
justify-content:center;
align-items:center;
position: absolute;
top: 0;
}
.block1 {
justify-content:center;
background-color:green;
display:flex;
width:300px;
min-height:150px;
}
.block2 {
background-color:blue;
display:flex;
min-height:300px;
width:500px;
}
<div class="container">
<div class="block1">
<img src="https://tse2.mm.bing.net/th?id=OIP.M252f960f4a4f32c22914d8d87623f066o0&pid=15.1">
</div>
<div class="block2"></div>
</div>

Horizontally scrolling div within display:table div?

I am able to make a horizontally scrolling div using the following:
CSS
.scroll {
width:100%;
height:100px;
overflow-x:auto;
white-space:nowrap;
}
.box {
width:200px;
height:100%;
display:inline-block;
vertical-align:top;
}
HTML
<div class="scroll">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
However, once this is nested inside a div with display:table, the .scroll div no longer scrolls and instead stretches the .scroll div to show all of the boxes.
Pretty sure there's an easy fix for this, any ideas?
For reference: http://jsbin.com/makigome/29/edit?html,css,output
Try this CSS, hope it helps
.table {
display: block;
width:100%;
}
.table-cell {
display:block;
width:100%;
}
.scroll {
height:100px;
width:100%;
overflow-x:auto;
border:1px solid red;
white-space:nowrap;
margin:10px 0px;
}
.box {
width:200px;
height:100%;
background:orange;
display:inline-block;
vertical-align:top;
}
Is not possible using table and table cell, you can do it using float like this:
.table {
float:left;
width:100%;
}
.table-cell {
float:left;
width:100%;
}
.scroll {
clear:both;
height:100px;
width:100%;
overflow-x:auto;
border:1px solid red;
white-space:nowrap;
margin:10px 0px;
}
.box {
width:200px;
height:100%;
background:orange;
display:inline-block;
vertical-align:top;
}
For anyone interested, I fixed this by setting position:absolute to the .scroll div and wrapping it within another div with position:relative like so:
http://jsbin.com/makigome/39/edit?html,css,output
<div class="table">
<div class="table-cell">
<div class="scroll-wrapper">
<div class="scroll">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
</div>
</div>
</div>
.table {
display:table;
width:100%;
}
.table-cell {
display:table-cell;
width:100%;
}
.scroll-wrapper {
height:100px;
position:relative;
}
.scroll {
height:100%;
width:100%;
overflow-x:auto;
white-space:nowrap;
position:absolute;
}
.box {
width:200px;
height:100%;
display:inline-block;
vertical-align:top;
}

Three column layout using CSS

I am trying to do a 3-column layout and was wondering why the blue (right) column wraps around. This works fine in IE but fails to work in Chrome (30.0.1599.101m)
http://jsfiddle.net/V85JF/
HTML
<body>
<div class="top">
<div class="left">
</div>
<div class="center">
</div>
<div class="right">
</div>
</div>
</body>
CSS
body
{
height:100%;
margin:0;
background:gray;
}
.top
{
width:225px;
height:200px;
background:black;
}
.left
{
width:75px;
height:200px;
background:Red;
float:left;
display:inline-block;
}
.center
{
width:75px;
height:200px;
background:green;
float:none;
display:inline-block;
}
.right
{
width:75px;
height:200px;
background:Blue;
float:right;
display:inline-block;
}
EDIT
I need the center element to have fluid height. Top should take whatever height center takes.
Use float:left for .center and .right as well.
For fluid height, keep min-height:200px of .center.
Try this:
.top{overflow:hidden;}
.left,.center,.right{float:left;}
.center{min-height:220px;}
Fiddle here.
jsFiddle demo
Html
<body>
<div class="top">
<div class="left">
</div><div class="center">
</div><div class="right">
</div>
</div>
</body>
CSS
body
{
height:100%;
margin:0;
padding:0;
background:gray;
}
.top
{
width:225px;
height:auto;
background:black;
}
.left
{
width:75px;
height:200px;
background:Red;
display:inline-block;
}
.center
{
width:75px;
height:570px;
background:green;
display:inline-block;
clear:both;
}
.right
{
width:75px;
height:200px;
background:Blue;
display:inline-block;
}
Try this
This Layout is Fluid
Fiddle DEMO
CSS
body
{
height:100%;
margin:0;
background:gray;
}
.top
{
width:100%;
height:200px;
background:black;
}
.left
{
width:20%;
height:200px;
background:Red;
float:left;
display:inline-block;
}
.center
{
width:60%;
height:200px;
background:green;
float:left;
display:inline-block;
}
.right
{
width:20%
height:200px;
background:Blue;
float:right;
display:inline-block;
}