achieving equal height columns with flexbox - html

I am trying to build a layout which has two separate content groups: one on the left side and right side, with fixed width (20%/80%) for now. On each side, I am trying to arrange contents by using flexbox: left panel with flex-direction: column and right panel with flex-direction: row wrap. The number of contents on each side can be flexible. The panel with less contents should match the height of the other, 'taller' side.
So far, I was able to achieve the basic layout, as shown in this jsfiddle. However, my problem is that I cannot make the the 'shorter' panel to fill the height, even though I set the height to be 100%. In the given example, there is an empty space between 'C' div of left panel and 'Box7' div of the right panel. The html/css code is show below.
How could I fix this problem or is there nicer simpler layout solutions? Any help would be appreciated.
HTML
<div class='top'>
<div class='left'>
<div class='litem'>A</div>
<div class='litem'>B</div>
<div class='litem'>C</div>
</div>
<div class='right'>
<div class='ritem'>Box 1</div>
<div class='ritem'>Box 2</div>
<div class='ritem'>Box 3</div>
<div class='ritem'>Box 4</div>
<div class='ritem'>Box 5</div>
<div class='ritem'>Box 6</div>
<div class='ritem'>Box 7</div>
</div>
</div>
CSS
* { outline: 1px solid Grey; }
html {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
background-color: Cornsilk;
}
.top {
margin: 0;
padding: 0;
display: flex;
flex-direction: row;
width: 100%;
height: 100%;
}
.left {
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
width: 20%;
height: 100%;
}
.right {
margin: 0;
padding: 0;
display: flex;
flex-direction: row;
flex-wrap: wrap;
width: 80%;
height: 100%;
}
.litem, .ritem {
margin: 0;
padding: 0;
}
.litem { height: 50%; }
.ritem { height: 50%; width: 33.3%;}
.litem:nth-child(1) { background-color: Cyan; }
.litem:nth-child(2) { background-color: DarkCyan; }
.litem:nth-child(3) { background-color: DarkSeaGreen; }

When you apply height: 100% to html and body, you limit the growth of the child elements to 100% of the screen.
In your code, your .left flex item is indeed stretching to height: 100%, as specified. Add a border around .left for an illustration: DEMO
If you remove all the fixed heights, you'll enable the flex container to stretch all flex items, per the default setting: align-items: stretch (the setting that creates equal height columns). DEMO
When you add flex: 1 to the .left flex items (.litem), they then distribute all available space in the container evenly among themselves. DEMO.
In a nutshell, when you use the height property you override align-items: stretch, the flex setting for equal height columns.

Related

change grid layout based on generic container size (not using classes)

In the following example I have two containers for a flex item. When the container is 300px I want the two 150px boxes to be side by side (as seen in the example). When the container is 150 however I'd like to change the container display to block to have them stacked on each other (we shouldn't see the yellow below).
Is it possible to write CSS WITHOUT leveraging the example_1 or example_2 classes and just referencing their container? I tried Chromes #container query but this didn't work... any help appreciated!!
.example_1 {
width: 300px;
height: 30px;
background-color: yellow;
}
.example_2 {
width: 150px;
height: 60px;
background-color: yellow;
}
.flex-thing {
display: flex;
flex-direction: row;
width: max-content;
justify-content: stretch;
}
.flex-thing .item {
background-color: red;
width: 150px;
height: 30px;
border: solid 1px black;
}
<div class="example_1">
<div class="flex-thing">
<div class="item"></div>
<div class="item"></div>
</div>
</div>
<br>
<div class="example_2">
<div class="flex-thing">
<div class="item"></div>
<div class="item"></div>
</div>
</div>
If you want the red box to auto wrap down to second line, you need to add flex-wrap: wrap; to the container. or you can add
.example_2 .flex-thing{
flex-direction: column;
}

Flex box isn't filling remaining space when using flex-grow 1

I am trying to fill the remaining space of a containing flex box with the green div. I want the top flex row (blue) to only be the height of its contents and then the row below (green) to fill the rest. For some reason it just seems to split the flex rows evenly down the div. I have read a few questions on here already which all say to make sure the containing div has its height set to 100%. I have set the containing div height to 200px as this is my desired height, but I have also tried adding another container within this to 100% to no avail. I've also made sure to set the flex-grow property on the second row to 1. Every time I think I'm beginning to understand flex it throws another curve ball and it's driving me up the wall. Please help! Thank you.
P.S. for some reason the HTML code snippet below refuses to include the first line of my html but it is contained in the following div: <div class="rmCtrlList_item"
.rmCtrlList_item {
width: 80vw;
margin: 3vw 8.5vw;
height: 200px;
background-color: $primary-color;
border-radius: 10px;
padding: 5px;
display: flex;
flex-flow: row;
flex-wrap: wrap;
// ROWS
&_row {
width: 100%;
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
#row-1 {
//max-height: 20px;
background-color: blue;
}
#row-2 {
flex-grow: 1;
align-items: center;
justify-content: center;
background-color: green;
}
// COLUMNS
&_col {
text-align: left;
flex-direction: column;
}
#col-1b {
flex-grow: 1;
}
}
<div class="rmCtrlList_item">
<div class="rmCtrlList_item_row" id="row-1">
<div class="rmCtrlList_item_col" id="col-1a">
<i class="icon__panel-2 fas fa-lightbulb"></i>
</div>
<div class="rmCtrlList_item_col" id="col-1b">
<a href="lights.html">
<h1 class="panel__title">Lights</h1>
</a>
</div>
<div class="rmCtrlList_item_col" id="col-1c">
<i class="icon__enlarge fas fa-plus-circle"></i>
</div>
</div>
<div class="rmCtrlList_item_row" id="row-2">
div to fill remaining space
</div>
</div>
how about to use flex-direction and below code what I used? green will fill ramaining space automatically, if you use its height's 100%
.container{
display: flex;
flex-direction: column;
width: 200px;
height: 300px;
border: 1px solid black;
}
.blue{
width: 100%;
height: 90px; /*change only blue's height size, green will be filled automatically*/
background: blue;
}
.green{
width: 100%;
height: 100%;
background: green;
}
<div class="container">
<div class="blue"></div>
<div class="green"></div>
</div>

Organize items within a container like flex-direction: column with 3 columns but unknown height

So, I hope I get this right. Here is the jsfiddle I came up with so far https://jsfiddle.net/fymo97zn/7/
So, I have a .page element that has fixed height and width to fit on a A4 page.
Within this are 2 containers one .units has width 100% and a dynamic (unknown) height.
The second container contains multiple (1...n) .upgrade elements.
Now, I want to fill those unit elements in a 3 column ways but not from left to right but form top to bottom, like a newspaper, or just like column-count: 3 would do, but filling the first column first.
The issue seems to be, that it does not know how to wrap because I don't know the height of .units and this not the available space for .upgrades.
Does anyone have an idea?
I'm working with nuxt and scss.
.page {
max-height: 400px;
max-width: 400px;
min-height: 400px;
min-width: 400px;
background-color: lime;
}
.units {
height: 100px;
width: 400px;
background-color: red;
}
.rest {
background-color: blue;
display: flex;
flex-wrap: wrap;
flex-direction: column;
height: 250px;
width: 100%;
overflow: hidden;
}
.upgrade {
background-color: orange;
width: 28%;
height: 50px;
padding: 5px;
margin: 5px;
}
<div class="page">
<div class="units">
</div>
<div class="rest">
<div class="upgrade"></div>
<div class="upgrade"></div>
<div class="upgrade"></div>
<div class="upgrade"></div>
<div class="upgrade"></div>
<div class="upgrade"></div>
<div class="upgrade"></div>
<div class="upgrade"></div>
</div>
</div>

Why is my first div outside of the window?

I'm just trying the FlexLayout for different screen sizes.
The 3 boxes/divs below should be side to side on a large display, if it shrinks they should be above each other. But my top div is outside of my window and I don't want that.. How can I fix that?
<div class="container" fxLayout="row" fxLayout.lt-md="column" fxLayoutAlign="space-around center">
<div class="asd" [style.background-color]="'black'"></div>
<div class="asd" [style.background-color]="'green'"></div>
<div class="asd" [style.background-color]="'blue'"></div>
</div>
.asd {
min-height: 500px;
min-width: 400px;
}
.container {
height: 100%;
}
Flex elements won't stack unless you use flex-wrap: wrap along with a min-width or flex-basis declaration.
Basically, if the number of flex elements in the row would need to be smaller than their min-width they'll wrap to the next line.
.flexContainer {
display:flex;
max-width: 80%;
margin: 20px;
justify-content: space-between;
flex-wrap: wrap;
}
.flexItem {
background: #dddddd;
padding: 20px;
min-width: 200px;
margin: 0 10px 10px 0;
}
<div class="flexContainer">
<div class="flexItem">Flex</div>
<div class="flexItem">Flex</div>
<div class="flexItem">Flex</div>
<div class="flexItem">Flex</div>
</div>

Having an issue with div layout positioning

I have been fighting with this for a while, I'm trying to make a specific setup and I've gotten so frustrated at it I've resorted to using tables (very bad). So what I'm trying to do:
5 divs.
1 on the right side of the screen, ~120px width, 100% of the page
height
1 in the bottom left of the page, 120px height, 120px width
1 above that one, 120 width, all remaining height
in the middle between these 1 div on the top, with height of 80px,
and width filling between the other divs
and the last div in the middle taking up all remaining space
Any solution I have come up with required at least some JS, which I am doing everything I can to avoid, so I am looking for a purely CSS3 solution!
You could do it using HTML5 and CSS3 using display flex
Something I quickly mocked up http://codepen.io/tom-maton/pen/mbJAs
HTML:
<div class="main">
<div class="left">
<div class="top-left-column">Top left</div>
<div class="bottom-left-column"> bottom left</div>
</div>
<div class="center">
<div class="center-top-column">Top Center</div>
<div class="center-bottom-column">Bottom center</div>
</div>
<div class="right">
<div class="right-column">Right Column</div>
</div>
</div>
CSS:
div {
border: 1px solid #333;
}
.main {
border: 0;
display: flex;
flex-direction: row;
height: 100vh;
}
.top-left-column {
height: calc(100vh - 120px);
width: 120px;
}
.bottom-left-column {
height: 120px;
width: 120px;
}
.center {
display: flex;
align-content: stretch;
flex-direction: column;
flex: 1 1 0;
}
.center-top-column {
height: 80px;
}
.center-bottom-column {
height: calc(100vh - 80px);
}
.right-column {
height: 100vh;
width: 120px;
}
You just need to check your browser support beforehand as flex not supported in IE8/9