Flexbox: Combine one full-height column with following rows (two-column-layout) - html

I'm working on this for hours but can not achieve a working solution. Basically, I want to combine a full-height column (left) with following rows (right) in a two-column-layout with CSS Flexbox.
The full-height column should match the height of the parent's div (.grid-main > main), which is a grid-layout on the other hand.
Screenshot of the issue:
So the yellow boxes should be next to the full-height column and not continue beneath it.
The column should match the height of .grid-main (which could be achieved with flex-direction: column, but all following divs are also listed in a column then).
HTML-Structure:
<div class="grid-main">
<header>...</header>
<nav>...</nav>
<main>
<div class="col-reports"></div>
<div class="classes"></div>
<div class="classes"></div>
<div class="classes"></div>
<div class="classes"></div>
...
</main>
<footer>...</footer>
</div>
CSS:
.grid-main {
display: grid;
height: 98vh;
width: 98vw;
overflow: hidden;
position: relative;
overflow: -moz-hidden-unscrollable;
grid-template-columns: 175px 1fr 1fr;
grid-template-rows: 0.1fr 1fr 0.05fr;
grid-template-areas:
"header header header"
"nav main main"
"footer footer footer";
animation: fadeIn 1s;
transition: 1s all ease-in-out;
}
.grid-main > main {
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: flex-start;
place-content: flex-start leftjustify-content: flex-start space-evenly;
grid-area: main;
position: relative;
overflow-y: auto;
background: var(--color-accent-main);
}
.col-reports {
flex: 1;
height: 100%;
position: relative;
max-width: 250px;
padding: 20px;
background: rgba(204,204,204,.7);
box-shadow: 1px 1px 25px inset rgb(179, 179, 179);
font-size: .8rem;
font-weight: bold;
line-height: 200%;
}
.classes {
font-family: 'Lora';
line-height: 2rem;
background: #f6efe0;
border-radius: 5px;
padding: 20px;
margin: 10px;
border: 5px solid #eee9dd;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.07);
animation: fadeInUp 1s;
}
Visualized the issue:

I solved the issue basically with the following code. So the hint from #Paulie_D was quite helpful, although I wanted to avoid Grid for this basic layouting.
.grid-reports {
display: grid; /* Grid in Grid */
height: 100%; /* In contrast to Flexbox, Grid can be used to assign height: 100% to a container.
It stretches to the parent container even if the viewport changes. Flexbox does not work with height actually.
Unless you use flex-direction: column; to the parent container. */
grid-template-rows: 1fr; /* optional */
grid-template-columns: 1fr 6fr;
grid-area: main; /* referes to Main in .grid-main */
}
.col-students {
grid-row: 1; /* .col-students must only be in the first row of .grid-reports to stretch */
grid-column: 1; /* Only the first column of .grid-reports */
max-width: 250px;
padding: 20px;
background: rgba(204,204,204,.7);
box-shadow: 1px 1px 25px inset rgb(179, 179, 179);
font-size: .8rem;
font-weight: bold;
line-height: 200%;
}
.col-reports {
grid-column: 2; /* All childs of .col-reports and itself are in the second column of .grid-reports
Note: grid-rows are automatically assigned, because they are not adressed any further */
display: flex; /* .col-reports becomes now a Flexbox to align its child items (box). */
flex-wrap: wrap; /* All child elements automatically break */
flex-direction: row; /* All child elements flow in a row */
align-self: flex-start; /* To align items next to each other and at start of Flex */
padding: 10px;
}
.col-reports .box { /* Further definitions of the element in .grid-main */
flex-basis: 45%; /* So the flex-basis in this case relates to the .col-reports
and not to the whole .grid-reports which makes sense and is desired behaviour.
45% means that 45% of .col-reports are used, which is in the second column. */
/*Note: This needs to be assigned as 100% in the mobile section, because elements
must be placed under each other for mobile devices. */
}

Related

Make element dividing lines equal height with container

I'm trying to do a simple navbar, but the size of the border matches the size of the text and not its container's height. I'm trying to 'close' each text inside its own 'rectangle'. How do I achieve that?
.flex-r {
display: flex;
justify-content: space-around;
justify-items: center;
flex-wrap: nowrap;
gap: 1em;
align-items: center;
border: 1px solid black;
min-height: 40px;
}
.nav-item {
border-right: 1px solid black;
width: auto;
}
<div class='flex-r'><a class='nav-item'>Release</a><a class='nav-item'>Statistics</a><a class='nav-item'>Frequent releases</a></div>
You have the container set to min-height: 40px.
Add the same code to the items.
But here's a better overall solution that may work for you:
.flex-r {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1px; /* sets the dividing line width */
background-color: black; /* sets the dividing line color */
border: 1px solid black; /* sets the border around the container */
min-height: 40px;
}
.nav-item {
background-color: white; /* restores background color */
/* center the content */
display: flex;
justify-content: center;
align-items: center;
text-align: center;
}
<div class='flex-r'>
<a class='nav-item'>Release</a>
<a class='nav-item'>Statistics</a>
<a class='nav-item'>Frequent releases</a>
</div>

How to make grid element 100% available height in flex column parent?

I have this html structure:
I want to make .SceneWithHistory-Container to have 100% of available height in parent. Here is my css:
.Module-Container
margin-top: 120px
display: flex
flex-direction: column
height: 300px
.Funnel-Container
display: grid
grid-template-columns: 1fr
grid-gap: 16px
.SceneWithHistory-Container
position: relative
display: grid
grid-template-columns: minmax(450px, 532px) 1fr
margin-left: -16px
width: calc(100% + 32px)
flex: 1
.Module-SubmitFormButtons
background: #fff
height: 64px
bottom: 0
width: calc(100% + 32px)
margin-left: -16px
padding: 0px 16px
border-top: 0
box-shadow: var(--whiteBoxShadow)
display: flex
align-items: center
margin-top: 0 !important
flex-shrink: 0
I'v tried to make SceneWithHistory-Container flex: 1, but i'ts not getting 100% of available height. If my container .Moudule-Container has 300px of height, i want to make .SceneWithHistory-Container 300px - height of Funnel-Container and - Module-SubmitFormButtons.
Please don't ask me to add height: calc() prop, because i want to have dynamic calculation in my parent, that's not depend of children
flex-grow makes an element inside a flexbox use all available space.
So
flex: 1
should work.
I tested your code and it seems to work: https://jsfiddle.net/w5uLf4s6/4/
Or isn't that what you want?
There is no difference between a greed element and any other block element in terms of setting height, and as long as it is a flex item and it's container has column direction and you've set flex: 1 so flex-grow is 1 and it should fill the remaining height as it is, and you can check it in the below snippet.
.Module-Container has a red border and .SceneWithHistory-Container has a green border.
.Module-Container {
margin-top: 120px;
display: flex;
flex-direction: column;
height: 300px;
border: 5px solid red;
}
.Funnel-Container {
display: grid;
grid-template-columns: 1fr;
grid-gap: 16px;
border: 5px solid green;
}
.SceneWithHistory-Container {
position: relative;
display: grid;
grid-template-columns: minmax(450px, 532px) 1fr;
margin-left: -16px;
width: calc(100% + 32px);
flex: 1;
border: 5px solid blue;
}
.Module-SubmitFormButtons {
background: #fff;
height: 64px;
bottom: 0;
width: calc(100% + 32px);
margin-left: -16px;
padding: 0px 16px;
border-top: 0;
box-shadow: var(--whiteBoxShadow);
display: flex;
align-items: center;
margin-top: 0 !important;
flex-shrink: 0;
border: 5px solid pink;
}
<div class="Module-Container">
<div class="Funnel-Container">Funnel</div>
<div class="SceneWithHistory-Container">SceneWithHistory</div>
<div class="Module-SubmitFormButtons">Module-SubmitFormButtons</div>
</div>

CSS grid not aligning in Y-axis

It's a small problem but I don't get it. I am just trying to align the text in y-axis, but it only goes a little distance down when I put align-self : end or center. Container is the main grid, which contains the col div (columns) which has the con div (content) which contains the text inside the box div
CSS
.container{
display: grid;
grid-template-columns: repeat(4,22.45em);
grid-template-rows: 48rem;
grid-template-areas:
"colone coltwo colthr colfour";
/*text-align: center;*/
}
.con{
/*
padding-left: 0.5rem auto;
padding-right: 0.5rem auto;
padding-top: 0.5rem auto;
padding-bottom: 0.5rem auto;*/
display: grid;
grid-area: con;
justify-content: center;
align-items: center;
padding-left: 0.5rem;
padding-right: 0.5rem;
position: relative;
}
.col{
border-right: 0.005rem solid white;
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 16rem;
grid-template-areas: "con";
color: grey;
z-index: 1;
}
.box{
position: absolute;
padding-left: 0.5rem;
padding-right: 0.5rem;
justify-self: start;
align-self: end;
}
here is the codepen link : https://codepen.io/aronnora/project/editor/DkyrVM
You would probably need to put the content inside its own container and then give it some properties of its own
.center-Container {
display: flex;
justify-content: center;
align-items: center;
}
or a simpler way to just add a padding-top: 40%; to your existing content
Welcome to StackOverflow.
So I went through your CSS. I inspected the elements and found out that the child element with class .con have the default height and is also not inheriting the parent's height because you haven't set height to parent which is not necessary since you are using the grid-template-rows: 48em.
So I would suggest you to set height of .con
for eg.
.con {
height: 48em;
}
I hope this solves your query.

Re-arranging flexbox layout for mobile view

I have 4 divs that I am using flexbox to align. At desktop size, there are 3 equal width columns with the first and last divs taking up the entire height of the container. The second and third divs stack vertically in the middle with each taking up 50% of the height. That's working fine.
At mobile size, I want the last div to be on top and to stretch the entire width of the container. Then I want the first div to align left underneath the top div and take up 50% of the width and the remaining height of the container.
The problem I'm having is I want the second and third div to align right under the top div and take up the remaining 50% of the width but to stack vertically so each takes up 50% of the remaining height.
I've tried changing the flex-direction in the media query and everything else I can think of but it's not working.
* {
margin: 0;
padding: 0;
}
.box-wrapper {
display: flex;
flex-direction: column;
flex-wrap: wrap;
height: 70vh;
align-items
}
.boxa {
background: red;
flex: 0 0 100%;
width: 33%;
}
.boxb {
background: orange;
}
.boxc {
background: lightgreen;
}
.boxb,
.boxc {
flex: 0 0 50%;
width: 33%;
}
.boxd {
background: grey;
flex: 0 0 100%;
width: 33%;
}
#media (max-width: 700px) {
.boxa {
order: 2;
width: 50%;
flex: 0 0 75%;
}
.boxb {
order: 3;
width: 50%;
flex: 0 0 37.5%;
}
.boxc {
order: 4;
width: 50%;
flex: 0 0 37.5%;
}
.boxd {
order: 1;
flex: 0 0 25%;
width: 100%;
}
}
<div class="box-wrapper">
<div class="boxa"></div>
<div class="boxb"></div>
<div class="boxc"></div>
<div class="boxd"></div>
</div>
The layout you want is difficult to achieve with flexbox because flexbox is not well-suited for 2-dimensional grids. It excels at 1-dimensional grids (placing flex items in rows or columns), but has limited capacity in 2-dimensional grids (placing flex items in rows and columns).
Being that your desired layout involves items having to cross row and column lines, flex is not your best option. With CSS Grid, your layout is simple and easy.
jsFiddle demo
.box-wrapper {
display: grid;
grid-template-columns: 1fr 1fr 1fr; /* 3 equal width columns */
grid-template-rows: 1fr 1fr; /* 2 equal height rows */
height: 70vh;
grid-column-gap: 5px;
grid-row-gap: 5px;
padding: 5px;
grid-template-areas: " first second last "
" first third last ";
}
.boxa { grid-area: first; background: red; }
.boxb { grid-area: second; background: orange; }
.boxc { grid-area: third; background: lightgreen; }
.boxd { grid-area: last; background: grey; }
#media ( max-width: 700px) {
.box-wrapper {
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr;
grid-template-areas: " last last "
" first second "
" first third ";
}
}
* { margin: 0; padding: 0; }
/* for placing and styling numbers only */
.box-wrapper > div {
font-size: 1.5em; display: flex; align-items: center; justify-content: center; }
<div class="box-wrapper">
<div class="boxa">1</div>
<div class="boxb">2</div>
<div class="boxc">3</div>
<div class="boxd">4</div>
</div>
More information:
Is it possible for flex items to align tightly to the items above them?

flexbox: stretching the height of elements with flex-direction: row

I want to stretch two div elements (.sideline and .main-contents) to reach the bottom of the page and stay at a certain height from the footer.
The two divs are nested inside a div (.row-elements) with the flex-direction: row since I wanted them to be on the same row.
/* body {
display:flex;
flex-direction:column;
} */
.one-above-all {
display: flex;
flex-direction: column;
/* flex: 1 0 auto; */
/* min-height: 1100px; */
border: solid black 1px;
}
.top-block {
margin: 0 auto;
border: solid black 1px;
width: 300px;
height: 30px;
margin-top: -15px;
}
.headline {
border: solid black 1px;
width: 90%;
align-self: flex-end;
margin-top: 40px;
margin-right: 10px;
height: 160px;
display: flex;
box-sizing: border-box;
}
.row-elements {
display: flex;
flex-direction: row;
margin-top: 40px;
align-items: stretch;
/* min-height: 900px;
flex: 1 0 auto;
*/
}
.sideline {
width: 160px;
border: solid 1px;
margin-left: calc(10% - 10px);
box-sizing: border-box;
flex-shrink: 1
}
.main-contents {
border: solid 1px;
margin-left: 40px;
/* align-self: stretch; */
flex: 1 1 auto;
margin-right: 10px;
box-sizing: border-box;
}
.bottom-block {
align-self: flex-end;
margin-top: auto;
border: black solid 1px;
margin: auto;
width: 300px;
height: 30px;
margin-bottom: -10px;
/* margin-top: 880px; */
}
/* .stretch-test {
border:solid, 1px;
display: flex;
flex-direction: column;
flex: 1 0 auto;
} */
<div class="one-above-all">
<div class="top-block"></div>
<div class="headline"></div>
<!-- <div class="stretch-test"> -->
<div class="row-elements">
<div class="sideline"></div>
<div class="main-contents">jhjkdhfjksdhafjksdahfl</div>
<!--</div> -->
</div>
</div>
<div class="bottom-block">footer</div>
Codepen
The commented out code in the css is the things I have tried.
I tried to set the body as flex and give the row-elements class flex property of 1 0 auto which didn't work.
I tried nesting the row-elements class (which has the flex-direction of row) in another div with a flex-direction of column and setting .row-elements to flex:1 0 auto which also didn't work.
I tried totally removing the the row-elements class but the two divs won't come on the same row.
Any solution will be appreciated.
To stick the footer to the bottom, here are two methods:
Method #1: justify-content: space-between
Align the container vertically with flex-direction: column. Then pin the last element to the bottom with justify-content: space-between.
revised codepen
Method #2: auto margins
Also with the container in column-direction, apply margin-top: auto to the footer, which spaces it away from the other flex items. (Seems you're already familiar with this method.)
Here's a detailed explanation for both: Methods for Aligning Flex Items
Make sure to define a height for your container, unless you simply want content height. In my example I've used height: 100vh on body.