CSS trick to display multiple divs - html

I want to separate my window in 2 equal parts, same height but width is 50% for each.
So I used this
.container {
display: flex;
height : 100%;
}
.column {
flex: 1;
height : 100%;
}
.column-one {
order: 1;
}
.column-two {
order: 2;
}
My html is structured like this
<div class="container">
<div class="column column-one"> Column 1
<div class="x" id="sliceX" ></div>
<div class="y" id="sliceY"></div>
<div class="z" id="sliceZ"></div>
</div>
<div class="column column-two"> Column 2
<div class="x" id="sliceX2"> </div>
<div class="y" id="sliceY2"></div>
<div class="z" id="sliceZ2"></div>
</div>
</div>
This is working well.
Now I want that my .x will take 100% of width but 50% of height. .y and .z will be displayed just after. Both taking 50% of height(the rest). But each class will only take 50% of width so .y will be displayed on the left and .z on the right
Like this:
Col1 Col2
xxxx xxxx
xxxx xxxx
yyzz yyzz
yyzz yyzz
How can I structure my css get this working with my actual separation in 2 columns ?

One thing you could try is to make your .column a flex container also and set it's wrap to allowing wrapping. Then set .x to width:100%; and .y, .z to width:50%; then give them all a height:50%;
Like this:
.column {
flex: 1;
height : 100%;
display:flex;
flex-wrap:wrap;
}
.x{
width:100%;
height:50%;
}
.y, .z{
width:50%;
height:50%;
}
See this fiddle.

You'll probably have best results with a second flex definition. You can use flex-wrap to wrap the layout quite effectively. Something like this:
html,
body {
height: 100%;
margin: 0;
}
.container {
display: flex;
height: 100%;
align-items: stretch;
}
.column {
flex: 0 0 50%;
display: flex;
flex-wrap: wrap;
align-items: stretch;
}
.x {
flex: 0 0 100%;
}
.y, .z {
flex: 0 0 50%;
}
.x {background-color: #ff8080}
.y {background-color: #80ff80}
.z {background-color: #8080ff}
<div class="container">
<div class="column column-one">
<div class="x" id="sliceX"></div>
<div class="y" id="sliceY"></div>
<div class="z" id="sliceZ"></div>
</div>
<div class="column column-two">
<div class="x" id="sliceX2"></div>
<div class="y" id="sliceY2"></div>
<div class="z" id="sliceZ2"></div>
</div>
</div>
In the above, the .x takes 100% of the width, pushing the .y and .z onto the second row. Each of these then takes 50% of the width, making a nice result. You can of course further adjust the balance to 30/70 or anything you choose.
Great job on using Flex, by the way - it's definitely a great tool for this job :)

Related

Have flex children only use space if they need it to not scroll, but otherwise share space equally and scroll

I have two flex children that may either each be small or large, and I'm defining small as < 50% of the container's height and large as > 50% the container's height. The sum of the heights of the children may be larger than 100% of the container's height, in which case I'd want one or both to scroll.
If one child is small and the other is large, I'd like the small element to use exactly the space it needs: it should not shrink to accommodate the large element, nor grow to 50%, and it should not scroll its contents. I'd like the large element to use the rest of the space, and scroll its contents if necessary.
If both are large, I'd like them to each use 50% of the container's height and scroll their contents.
I have this Codepen started as an example to help illustrate what I'm trying to achieve, but unfortunately it currently does no amount of scrolling or resizing: https://codepen.io/joeysilva/pen/wvmPqLK. It has both a small-large and a large-large case.
.flex-container {
height: 100px;
width: 100px;
display: flex;
flex-direction: column;
display: inline-block;
overflow: hidden;
}
.child {
flex: 50%;
overflow: auto;
}
.small {
background: red;
height: 30px;
}
.large {
background: blue;
height: 110px;
}
<div class="flex-container">
<div class="child">
<div class="small">Small</div>
</div>
<div class="child">
<div class="large">Large</div>
</div>
</div>
<div class="flex-container">
<div class="child">
<div class="large">Large 1</div>
<div class="large">Large 2</div>
</div>
</div>
Note 1: Not use disply:inline-block and display:flex the same time. Simply add another wrapper to show elements inside a row or column.
Note 2: flex: 50%; is equivalent to flex: 1 1 50%; and this is the shorthand form of flex-grow: 1; flex-shrink: 1; flex-basis: 50%;. Here in your code no need to use them because you have strictly defined the height of elements and also the basis of 50% height is wrong since you'd like the small element to use exactly the space it needs; no grow & no shrink, so it should be omitted.
.wrapper {
display: flex;
flex-direction: row;
}
.flex-container {
height: 100px;
width: 100px;
display: flex;
flex-direction: column;
overflow: hidden;
}
.child {
overflow: auto;
}
.small {
background: red;
height: 30px;
}
.large {
background: blue;
height: 110px;
}
<div class="wrapper">
<div class="flex-container">
<div class="child">
<div class="small">Small</div>
</div>
<div class="child">
<div class="large">Large</div>
</div>
</div>
<div class="flex-container">
<div class="child">
<div class="large">Large 1</div>
</div>
<div class="child">
<div class="large">Large 2</div>
</div>
</div>
</div>

Create rows in html which will share height?

<div class="container-fluid">
<div calss="row" style="height:20%; display: block;">
<h1>20 percent height</h1>
</div>
<div calss="row">
<h1>height should be 80 percent</h1>
</div>
</div>
I tried some example which is shown here but it's not working.
My requirement is if i keep first height as 10% or 20% second row should occupy height automatically without setting the height explicitly.
Use flexbox for this type of stuff. Also instead of 80 and 20 you could use 4 and 1, it's just the ratio that matters
.parent {
display: flex;
width: 100vw;
height: 100vh;
flex-direction:column;
}
.top {
flex: 80;
background: red;
}
.bottom {
flex: 20;
background: blue;
}
<div class="parent">
<div class="top"></div>
<div class="bottom"></div>
</div>
Use flex display. Add display: flex and flex-direction: column for the parent and for the second content provide flex-grow: 1 which will fit that div in rest of the space.
.container-fluid {
display: flex;
flex-direction: column;
height: 500px;
}
.container-fluid div {
margin: 5px;
border: 1px solid black;
}
.row-two {
flex-grow: 1;
}
<div class="container-fluid">
<div class="row" style="height:20%; display: block;">
<h1>20 percent height</h1>
</div>
<div class="row row-two">
<h1>height should be 80 percent</h1>
</div>
</div>

CSS: four divs dynamically sharing height of a parent

I have a parent div in a grid with height of 29rem + 1fr. In the div there are four children. First and third have a fixed height (both have the same height as their content that does not change), and second and fourth must have dynamical height because of their content.
HTML:
<body>
<div class="unplanned"> Index
<div class= "header"> </div>
<div class="filter_line">filter: line </div>
<div class="filter_date">filter: date </div>
<div class="table">table </div>
</div>
</body>
CSS:
.unplanned {z-index: 1500;
grid-area: unplanned;
width: 30rem;
height: 96vh;/*right now it's set as fixed height that does not work it there is less content in filter_line*/}
.fitler_line {display: inline-block;
margin-bottom: 3rem;
margin-top: 3.3rem;
margin-left: 2.9rem;}
.fitler_date {margin-left: 4rem;
margin-bottom: 3rem;
position: relative;
padding-bottom: 2rem;}
.table {text-align: center;
overflow-y: auto;
height: calc( 100% - 32rem ); /*right now it's set as fixed height that does not work it there is less content in filter_line*/}
I have tried adding height: auto to "filter_line" and "table" and it works to an extend. It fits all lines in "filter_line" but it cuts off the table without scroll. Flex will not work, because it messes with grid.
Is there an elegant solution in CSS or Sass that will fit all of "table" content without JS?
The answer lays in flex attribute.
You can use flex for extending last div to available space. Very good tutorial for flex is here. (Do read for further understanding)
The solution is described here:
.parent {
background-color:red;
height:500px;
display: flex;
flex-flow: column;
}
.first {
background-color:blue;
height:50px
}
.second {
background-color:green;
flex: 0 1 auto;
}
.third {
background-color:yellow;
flex: 1 1 auto;
}
<div class="parent">
<div class="first"></div>
<div class="second">bdjasbdajsbdajsbd
das<br>
das<br>
das<br>
d<br>
asd<br>
a</div>
<div class="third"></div>
</div>

How can I accomplish this design with flexbox?

I'm trying to accomplish this design by using flexbox:
It's supposed to be a one page website.
.container {
display: flex;
}
.big {
flex: 2;
height: 70vh;
background: gray;
}
.small {
flex: 1;
height: 70vh;
background: gray;
}
<div class="container">
<div class="small">
</div>
<div class="smallest">
</div>
<div class="big">
</div>
</div>
I have no idea how to implement the "smallest" div to be 25% of the big, let alone make the "small" 75% of the big one.
Also the height really confuses me, I need them to always have the same height.
With flexbox you can wrap the small and the smallest into a separate div and use column flexbox on the left section.
I have no idea how to implement the "smallest" div to be 25% of the big
25% to 75% ratio means 1:3 ratio - and in flexbox language that is flex: 1 to the small element and flex: 3 to the big element.
Also the height really confuses me, I need them to always have the same height.
You can set the height of the container to the container element - your flexbox will fill to this height.
See demo below:
.container {
display: flex;
height: 70vh;
}
.big {
flex: 3;
background: gray;
margin-left: 5px;
}
.left {
flex: 1;
display: flex;
flex-direction: column;
}
.left .small {
background: gray;
flex: 3;
}
.left .smallest {
margin-top: 5px;
background: gray;
flex: 1;
}
<div class="container">
<div class="left">
<div class="small">
</div>
<div class="smallest">
</div>
</div>
<div class="big">
</div>
</div>

place two divs per row

so I have X divs and I want to put 2 divs in one row next to each other. If the screen size width is below n px there should be 1 div per row.
Currently I have this
#container {
display: flex;
}
.box {
width: 50px;
background: red;
}
#media(max-width: 300px) {
#container {
display: block;
}
}
<div id="container">
<div class="box"> 1 </div>
<div class="box"> 2</div>
<div class="box"> 3 </div>
<div class="box"> 4 </div>
</div>
How can I limit the flex box to two divs per row?
Add 50% width on .box and flex-wrap:wrap on the container
Additionally, what you did by changing display: flex to block was not required. Just change the .box elements width to 100%
#container {
display: flex;
flex-wrap: wrap;
}
.box {
width: 50%;
background: red;
}
#media(max-width: 300px) {
.box {
width: 100%;
}
}
<div id="container">
<div class="box"> 1 </div>
<div class="box"> 2</div>
<div class="box"> 3 </div>
<div class="box"> 4 </div>
</div>
Just add a property in your container class like
.container {
display: flex;
flex-wrap: wrap;
}
And in box class just specify the width of your box as 50% like
.box {
width: 50%;
background: red;
}
That should do the trick.
Flex will do a trick for you. flex-wrap: wrap for #container will make children wrap when necessary. .box with 50% and after breakpoint 100%.`
According to MDN:
The CSS flex-wrap property specifies whether flex items are forced into a single line or can be wrapped onto multiple lines. If wrapping is allowed, this property also enables you to control the direction in which lines are stacked.
If you are new to flexbox I recommend this guide.
Snippet
#container {
display: flex;
flex-wrap: wrap;
}
.box {
width: 50%;
background: red;
}
#media(max-width: 300px) {
.box {
width: 100%;
}
}
<div id="container">
<div class="box"> 1 </div>
<div class="box"> 2 </div>
<div class="box"> 3 </div>
<div class="box"> 4 </div>
</div>