Nested Flexbox Breaking Parent - html

I've been trying to implement a simple nested flexbox function. I'm having an issue where it appears that I can have two levels (vertical columns -> horizontal rows), but if I try to extend beyond that, (vertical -> horizontal -> vertical) it breaks the containers height.
I have a CodePen hosted here that better describes my question.
http://codepen.io/FrederickGeek8/pen/xGoPXd
Compiled HTML:
<div class="workspace">
<div class="vertical">
<div class="item">
<div class="horizontal">
<div style="background:pink" class="item"><a>Up</a></div>
<div class="item">
<div class="vertical">
<div style="background:red" class="item"><a>Left</a></div>
<div style="background:orange" class="item"><a>Strange</a></div>
</div>
</div>
<div style="background:blue" class="item"><a>Another</a></div>
</div>
</div>
<div class="item"><a>Right</a></div>
<div style="background:green" class="item"><a>Dang</a></div>
</div>
</div>
Compiled CSS (autoprefixed on CodePen):
.workspace {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.vertical {
flex: 1;
display: flex;
flex-direction: row;
background: grey;
width: 100%;
height: 100%;
}
.vertical > .item {
flex: 1;
display: flex;
flex-direction: row;
width: 100%;
height: 100%;
margin: auto;
border-left: 1px solid #181a1f;
border-bottom: 1px solid #181a1f;
flex-grow: 1;
}
.horizontal {
flex: 1;
display: flex;
flex-direction: column;
background: grey;
width: 100%;
height: 100%;
}
.horizontal > .item {
flex: 1;
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
margin: auto;
border-left: 1px solid #181a1f;
border-bottom: 1px solid #181a1f;
flex-grow: 1;
}
PS: The platform I will be running the finished product on is a packaged Chromium instance.

I removed some unnecessary height: 100% and the margin: auto
http://codepen.io/anon/pen/waLPzR
.workspace {
position:absolute;
top:0;
left:0;
width:100%;
height:100%;
}
.vertical {
flex:1;
display: flex;
flex-direction: row;
background:grey;
width:100%;
height: 100%;
> {
.item {
flex:1;
display: flex;
flex-direction: row;
width:100%;
border-left: 1px solid #181a1f;
border-bottom: 1px solid #181a1f;
flex-grow: 1;
}
}
}
.horizontal {
flex:1;
display: flex;
flex-direction: column;
background:grey;
width:100%;
> {
.item {
flex:1;
display: flex;
flex-direction: column;
width:100%;
border-left: 1px solid #181a1f;
border-bottom: 1px solid #181a1f;
flex-grow: 1;
}
}
}

Related

How to make DIV element responsive to screen resolution

I'm trying to create element div that contain 3 part, using 2 row and 2 column.
.flex-row {
flex-direction: row;
display: flex;
width: 310px;
}
.flex-column {
flex-direction: column;
display: flex;
}
.flex-body {
display: flex;
margin: 40px 10px 0px 0px;
}
.flex-body div:not([class*="flex"]) {
border: 1px solid white;
flex: 1 1 260px;
width: 764px;
}
<div class="flex-body">
<div class="flex-row">
<div style="background: #0980cc;"></div>
</div>
<div class="flex-column">
<div style="background: #09cc69;"></div>
<div style="background: #cc092f;"></div>
</div>
</div>
I set the width because if I didn't do it, the width wouldn't fit page.
But the div isn't responsive. I've tried but nothing work. How can I make my div responsive the screen resolution?
I've just created a version that uses percentages:
body,
html {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
border: 0;
}
.flex-body {
display: flex;
width: 100%;
height: 100%;
box-sizing: border-box;
padding: 40px;
}
.flex-body div:not([class*="flex"]) {
border: 1px solid white;
flex: 1 1 50%;
position: relative;
box-sizing: border-box;
}
.flex-row {
flex-direction: row;
display: flex;
width: 35%;
background-color: #0980cc;
}
.flex-column {
flex-direction: column;
display: flex;
width: 65%;
}
.flex-column div:nth-child(1) {
background: #09cc69;
width: 100%;
}
.flex-column div:nth-child(2) {
background: #cc092f;
width: 100%;
}
jsfiddle link

Hover-styling a width on a flexible height content box

I have created a hover effect on a flexible content box that changes the width of an inner box to reveal text inside. I need this box to be flexible in height so that more content can be added, however, I don't want the height to change as I hover.
I've linked below what I've got so far, the box on the left shows my desired effect with a static height and box on the right shows what happens when I add more text which causes the issue of the height changing as I hover by wrapping the text inside it.
https://jsfiddle.net/ndpty6xa/
.flex {
display: flex;
justify-content: center;
}
.box {
width: 50%;
background-color: red;
border: 2px solid black;
min-width: 200px;
flex-direction: column;
margin: 10px;
display: flex;
justify-content: center;
align-items: center;
position: relative;
}
.content {
position: relative;
display: flex;
justify-content: center;
align-items: center;
background-color: white;
width: 0%;
height: 90%;
transition: all .5s;
}
.text {
position: relative;
text-align: center;
overflow: hidden;
}
.box:hover>.content {
width: 90%;
}
#media(max-width: 450px) {
.flex {
flex-wrap: wrap;
}
.box {
flex-grow: 1;
}
}
<div class=flex>
<div class=box>
<div class=content>
<div class=text>
<h3>This</h3>
<p>Works</p>
</div>
</div>
</div>
<div class=box>
<div class=content>
<div class=text>
<h3>This doesnt</h3>
<p>TestTe stTestTestTest TestTestTestT estTestT estTes tTestTe stTestTestTest</p>
</div>
</div>
</div>
</div>
I don't think I'm very good at explaining this but hopefully, someone gets the idea.
You can think differently and instead of animating width you animate an overlay above it to simulate the same effect:
.flex {
display: flex;
justify-content: center;
}
.box {
width: 50%;
background-color: red;
border: 2px solid black;
min-width: 200px;
flex-direction: column;
margin: 10px;
display: flex;
justify-content: center;
align-items: center;
position: relative;
}
.content {
position: relative;
display: flex;
flex-direction:column;
justify-content: center;
align-items: center;
text-align: center;
background-color: white;
width: 90%;
height: 90%;
}
.content:before {
content:"";
position:absolute;
top:0;
left:50%;
right:0;
bottom:0;
background:red;
z-index:1;
transition: all .5s;
}
.content:after {
content:"";
position:absolute;
top:0;
right:50%;
left:0;
bottom:0;
background:red;
z-index:1;
transition: all .5s;
}
.box:hover>.content:before {
left: 100%;
}
.box:hover>.content:after {
right: 100%;
}
#media(max-width: 450px) {
.flex {
flex-wrap: wrap;
}
.box {
flex-grow: 1;
}
}
<div class="flex">
<div class="box">
<div class="content">
<h3>This</h3>
<p>Works</p>
</div>
</div>
<div class="box">
<div class="content">
<h3>This also works!</h3>
<p>TestTe stTestTestTest TestTestTestT estTestT estTes tTestTe stTestTestTest</p>
</div>
</div>
</div>
Simply add min-height like min-width to box
.box{
width: 50%;
background-color: red;
border: 2px solid black;
min-width: 200px;
flex-direction: column;
margin: 10px;
display: flex;
justify-content: center;
align-items: center;
position: relative;
min-height: 250px;
}

Stretch columns in two columns layout with shared header using flexbox

I'm using flexbox to create a two-columns layout with a header row.
* {
box-sizing: border-box;
position: relative;
}
.container {
border: 2px solid gray;
display: flex;
flex-wrap: wrap;
height: 300px;
}
.header {
flex-basis: 100%;
border: 2px solid magenta;
height: 50px;
line-height: 50px;
text-align: center;
}
.column1 {
flex-basis: 150px;
/* height: calc(100% - 50px); */
border: 2px solid green;
}
.column2 {
/* height: calc(100% - 70px); */
flex: 1;
border: 2px solid orange;
}
<div class='container'>
<div class='header'>it's a header</div>
<div class='column1'>column 1</div>
<div class='column2'>column 2</div>
</div>
Feel free to see the full example here.
As you can see in the example there is a gap between columns and header. My aim is to stretch columns vertically to fill whole empty space in the container.
I can achieve it by setting height property like calc(100% - <header-height>). Is it the correct way?
I just tried to use "flex" style and set align-items: stretch to the container and align-self: stretch to columns but without success. Did I probably miss something trying to implement it this way?
I think specifying flex-direction as column is appropriate in this case.
The second row is itself a flex element with the flex-direction: row. You can fill the rest of the remaining space using flex: 1, which is equivalent to flex-grow: 1.
* {
box-sizing: border-box;
}
.container {
border: 2px solid gray;
display: flex;
flex-direction: column;
flex-wrap: wrap;
height: 300px;
}
.header {
border: 2px solid magenta;
height: 50px;
line-height: 50px;
text-align: center;
}
.subcontainer {
display: flex;
flex-direction: row;
flex: 1;
}
.column1 {
flex-basis: 150px;
border: 2px solid green;
}
.column2 {
flex: 1;
border: 2px solid orange;
}
<div class='container'>
<div class='header'>it's a header</div>
<div class="subcontainer">
<div class='column1'>column 1</div>
<div class='column2'>column 2</div>
</div>
</div>
Do it like shown below
* {
box-sizing: border-box;
}
body,
html {
height: 100%;
}
.container {
border: 2px solid gray;
display: flex;
flex-direction: column;
height: 100%;
}
.header {
width: 100%;
border: 2px solid magenta;
height: 50px;
line-height: 50px;
text-align: center;
}
.body-container {
display: flex;
width: 100%;
flex: 1;
}
.column1 {
width: 50%;
border: 2px solid green;
}
.column2 {
width: 50%;
border: 2px solid orange;
}
<div class='container'>
<div class='header'>it's a header</div>
<div class="body-container">
<div class='column1'>column 1</div>
<div class='column2'>column 2</div>
</div>
</div>

Align multiple elements with flex

I want to do something like that with flexbox:
.wrap {
display: flex;
flex-wrap: wrap;
}
.elem1 {
width: 20%;
height: 100px;
border: 1px solid red;
}
.elem2, .elem3 {
width: 75%;
border: 1px solid red;
}
<div class="wrap">
<div class="elem1">1</div>
<div class="elem2">2</div>
<div class="elem3">3</div>
</div>
JSFIDDLE
Switch to flex-direction: column.
Add flex-wrap: wrap.
Define a height for the container (so the flex items know where to wrap).
Box #1 will consume all space in the first column, forcing the following boxes to wrap to a new column.
No changes to the HTML.
.wrap {
display: flex;
flex-wrap: wrap;
flex-direction: column; /* NEW */
height: 100px; /* NEW */
justify-content: space-between; /* NEW */
}
.elem1 {
width: 20%;
flex-basis: 100%; /* NEW */
border: 1px solid red;
}
.elem2,
.elem3 {
width: 75%;
flex-basis: 40%; /* NEW */
border: 1px solid red;
}
<div class="wrap">
<div class="elem1">1</div>
<div class="elem2">2</div>
<div class="elem3">3</div>
</div>
Something like this maybe (tweak values as desired):
1. Using your height (100px) & widths (20% & 75%):
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
html,
body {
height: 100%;
width: 100%;
}
.wrap {
height: 100px;
display: flex;
flex-flow: row wrap;
}
.row {
width: 75%;
display: flex;
flex-flow: column wrap;
}
.elem1 {
width: 20%;
border: 1px solid lightgray;
}
.elem2 {
height: 50%;
border: 1px solid lightgray;
flex: 1;
margin: 10px;
}
.elem3 {
height: 50%;
border: 1px solid lightgray;
flex: 1;
margin: 10px;
}
<div class="wrap">
<div class="elem1">1</div>
<div class="row">
<div class="elem2">2</div>
<div class="elem3">3</div>
</div>
</div>
2. Full width & height option:
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
html,
body {
height: 100%;
width: 100%;
}
.wrap {
height: 100%;
display: flex;
flex-flow: row wrap;
justify-content: center;
}
.row {
width: 80%;
display: flex;
flex-flow: column wrap;
}
.elem1 {
width: 20%;
border: 1px solid lightgray;
}
.elem2 {
height: 50%;
border: 1px solid lightgray;
flex: 1;
}
.elem3 {
height: 50%;
border: 1px solid lightgray;
flex: 1;
}
<div class="wrap">
<div class="elem1">1</div>
<div class="row">
<div class="elem2">2</div>
<div class="elem3">3</div>
</div>
</div>

Howto scroll a context flex div

I have a simple site layout of Header and a 3 columns main section. The middle column should contain a lengthy content so I would like it to scroll, I can't make it happen.
Here is a prototype of the problem:
http://codepen.io/ValYouW/pen/GZxKBa
UPDATE: Sorry for not mentioning, but I meant for horizontal-scroll, not vertical...
html, body {
height: 100%;
}
body {
margin: 0;
padding: 0;
display: flex;
box-sizing: border-box;
}
#layout {
display: flex;
flex: 1;
flex-direction: column;
border: 4px solid red;
}
#header {
border: 2px solid yellow;
}
#main {
border: 2px solid green;
display: flex;
flex: 1;
flex-direction: row;
}
#facets{
border: 2px solid pink;
display: flex;
width: 100px;
}
#report {
border: 2px solid pink;
display: flex;
flex: 1;
flex-direction: column;
}
#rightside {
border: 2px solid pink;
display: flex;
width: 100px;
}
#chips {
border: 2px solid orange;
}
#leads-grid {
border: 4px solid orange;
display: flex;
flex: 1;
overflow: auto;
}
#grid1 {
border: 2px solid black;
width: 1000px;
}
<div id="layout">
<div id="header">Header</div>
<div id="main">
<div id="facets">Facets</div>
<div id="report">
<div id="chips">Chips</div>
<div id="leads-grid">
<div id="grid1">How to make my parent (#leads-grid) scroll?</div>
</div>
</div>
<div id="rightside">Right side</div>
</div>
<div>
Any ideas how to make #leads-grid to scroll?
Thx.
for the leads-grid have scroll his son (grid1) needs to surpass the content. try to put a lot of br's into the content of grid1 and leads-grid will create a scroll.
Your #leads-grid is scrolling already.
You just need to add more content to #leads-grid.
See code below. I have added height: 5000px to #grid1 as inline style. Scroll appears.
html,
body {
height: 100%;
}
body {
margin: 0;
padding: 0;
display: flex;
box-sizing: border-box;
}
#layout {
display: flex;
flex: 1;
flex-direction: column;
border: 4px solid red;
}
#header {
border: 2px solid yellow;
}
#main {
border: 2px solid green;
display: flex;
flex: 1;
flex-direction: row;
}
#facets {
border: 2px solid pink;
display: flex;
width: 100px;
}
#report {
border: 2px solid pink;
display: flex;
flex: 1;
flex-direction: column;
}
#rightside {
border: 2px solid pink;
display: flex;
width: 100px;
}
#chips {
border: 2px solid orange;
}
#leads-grid {
border: 4px solid orange;
display: flex;
flex: 1;
overflow: auto;
}
#grid1 {
border: 2px solid black;
width: 1000px;
}
<div id="layout">
<div id="header">Header</div>
<div id="main">
<div id="facets">Facets</div>
<div id="report">
<div id="chips">Chips</div>
<div id="leads-grid">
<div id="grid1" style="height: 5000px;">How to make my parent (#leads-grid) scroll?</div>
</div>
</div>
<div id="rightside">Right side</div>
</div>
<div>