So I have a structure pretty similar to the snippet below.
The issue I have is that I am trying to make it so that the divs such as child always take the same height relative to the container even if they are empty. So if there are two children they have to be 50% of the parent if there are three children 33.3% of the parent and ec.
Did a lot of digging, tried usingflex-grow and setting it on the children, adding an after content on the childContent class if it was empty but the empty children still collapse.
Is it even possible to achieve equal heights on the children without using js and fixed heights and if yes how?
.container {
display: flex;
flex-direction: column;
height: 100%;
width: 100%;
overflow: auto;
}
.child {
height: 100%;
display: flex;
flex-direction: column;
}
.childHeader {
display: flex;
flex-direction: row;
}
.headerItem {
background-color: red;
}
.childContent {
background-color: white;
}
.childContent:empty:after {
content: '.';
visibility: hidden;
min-height: 300px;
}
.contentItem {
background-color: skyblue;
border: 3px solid black;
}
<div class="container">
<div class="child">
<div class="childHeader">
<div class="headerItem">1</div>
<div class="headerItem">2</div>
<div class="headerItem">3</div>
<div class="headerItem">4</div>
<div class="headerItem">5</div>
<div class="headerItem">6</div>
<div class="headerItem">7</div>
</div>
<div class="childContent">
<div class="contentItem">1</div>
<div class="contentItem">2</div>
<div class="contentItem">3</div>
<div class="contentItem">4</div>
<div class="contentItem">5</div>
<div class="contentItem">6</div>
<div class="contentItem">7</div>
</div>
</div>
<div class="child">
<div class="childHeader">
<div class="headerItem">1</div>
<div class="headerItem">2</div>
<div class="headerItem">3</div>
<div class="headerItem">4</div>
<div class="headerItem">5</div>
<div class="headerItem">6</div>
<div class="headerItem">7</div>
</div>
<div class="childContent">
</div>
</div>
<div class="child">
<div class="childHeader">
<div class="headerItem">1</div>
<div class="headerItem">2</div>
<div class="headerItem">3</div>
<div class="headerItem">4</div>
<div class="headerItem">5</div>
<div class="headerItem">6</div>
<div class="headerItem">7</div>
</div>
<div class="childContent">
</div>
</div>
</div>
Check this out, I'm not really sure if this is what you want to do.
I just added min-height: calc(100vh - 60px); in your .childContent
.container {
display: flex;
flex-direction: column;
height: 100%;
width: 100%;
overflow: auto;
}
.child {
display: flex;
flex-direction: column;
}
.childHeader {
display: flex;
flex-direction: row;
}
.headerItem {
display:flex;
flex-basis:100%;
background-color: red;
}
.childContent {
background-color: grey;
position: relative;
display: block;
min-height: calc(80vh - 60px);
}
.childContent:empty::after {
content: '.';
visibility: hidden;
}
.contentItem {
background-color: skyblue;
border: 3px solid black;
}
<div class="container">
<div class="child">
<div class="childHeader">
<div class="headerItem">1</div>
<div class="headerItem">2</div>
<div class="headerItem">3</div>
<div class="headerItem">4</div>
<div class="headerItem">5</div>
<div class="headerItem">6</div>
<div class="headerItem">7</div>
</div>
<div class="childContent">
<div class="contentItem">1</div>
<div class="contentItem">2</div>
<div class="contentItem">3</div>
<div class="contentItem">4</div>
<div class="contentItem">5</div>
<div class="contentItem">6</div>
<div class="contentItem">7</div>
</div>
</div>
<div class="child">
<div class="childHeader">
<div class="headerItem">1</div>
<div class="headerItem">2</div>
<div class="headerItem">3</div>
<div class="headerItem">4</div>
<div class="headerItem">5</div>
<div class="headerItem">6</div>
<div class="headerItem">7</div>
</div>
<div class="childContent">
</div>
</div>
<div class="child">
<div class="childHeader">
<div class="headerItem">1</div>
<div class="headerItem">2</div>
<div class="headerItem">3</div>
<div class="headerItem">4</div>
<div class="headerItem">5</div>
<div class="headerItem">6</div>
<div class="headerItem">7</div>
</div>
<div class="childContent">
</div>
</div>
</div>
Check this one out https://developer.mozilla.org/en-US/docs/Web/CSS/calc
Related
I am trying to create a flex-box container following display:
I was able to do:
.garden {
width: 500px;
height: 500px;
background: #CCC;
}
.flower {
border: 1px solid #000;
width: 100px;
height: 100px;
}
.row {
display: flex;
}
.row:first-child {
justify-content: space-between;
}
.row:nth-child(2){
justify-content: center;
}
.row:last-child {
justify-content: space-around;
}
<div class="garden">
<div class="row">
<div class="flower red">Red</div>
<div class="flower green">Green</div>
<div class="flower yellow">Yellow</div>
</div>
<div class="row">
<div class="flower red">Red</div>
<div class="flower green">Green</div>
<div class="flower yellow">Yellow</div>
</div>
<div class="row">
<div class="flower red">Red</div>
<div class="flower green">Green</div>
<div class="flower yellow">Yellow</div>
</div>
</div>
How should I align first row to the top, 2nd row to middle center and last row to bottom?
You could set also the .garden element as a flexbox container, with column direction and proper spacing:
.garden {
width: 500px;
height: 500px;
background: #CCC;
display: flex;
flex-direction: column;
justify-content: space-between
}
.flower {
border: 1px solid #000;
width: 100px;
height: 100px;
}
.row {
display: flex;
}
.row:first-child {
justify-content: space-between;
}
.row:nth-child(2){
justify-content: center;
}
.row:last-child {
justify-content: space-around;
}
<div class="garden">
<div class="row">
<div class="flower red">Red</div>
<div class="flower green">Green</div>
<div class="flower yellow">Yellow</div>
</div>
<div class="row">
<div class="flower red">Red</div>
<div class="flower green">Green</div>
<div class="flower yellow">Yellow</div>
</div>
<div class="row">
<div class="flower red">Red</div>
<div class="flower green">Green</div>
<div class="flower yellow">Yellow</div>
</div>
</div>
I want a layout with a header, body, and footer. I do not want to use display: fixed, so I'm only scrolling the body. I use flex-grow: 1 to force the body section to fill the height.
The body has 4 columns. The columns are taller than the height of the body, so the body scrolls. However, the columns do not scroll, only their content.
In this codepen, scroll the middle section with the 4 columns. Note the gold background of the columns does not scroll. Instead, you see the orange background of the body.
How do I get the body content area to fill the screen if there's less content but also have the content background expand with the content when it scrolls? I've tried adding clearing div's and setting the column height to 100%.
Video illustration of the problem: http://recordit.co/eGpT87EmPp
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
html,
body {
height: 100vh;
}
.App {
background: red;
display: flex;
flex-direction: column;
height: 100vh;
}
.App .Header {
background: violet;
display: flex;
min-height: 2rem;
}
.App .Header .Player {
background: pink;
flex: 1 1;
text-align: center;
}
.App .Body {
background: orange;
display: flex;
flex-grow: 1;
overflow-y: scroll;
}
.App .Body .Column {
background: gold;
box-shadow: inset -1px 0 0 0 black;
display: flex;
flex-direction: column;
flex: 1 1;
padding-top: 1rem;
}
.App .Tile {
background: #111;
color: white;
margin: 0 auto 1rem;
padding: 5rem 0;
text-align: center;
width: 4rem;
}
.App .Footer {
background: deepskyblue;
min-height: 2rem;
}
<div class="App">
<div class="Header">
<div class="Player">Player</div>
<div class="Player">Player</div>
<div class="Player">Player</div>
<div class="Player">Player</div>
</div>
<div class="Body">
<div class="Column">
<div class="Tile">0</div>
<div class="Tile">1</div>
<div class="Tile">2</div>
<div class="Tile">3</div>
<div class="Tile">4</div>
<div class="Tile">5</div>
<div class="Tile">6</div>
<div class="Tile">7</div>
<div class="Tile">8</div>
<div class="Tile">9</div>
<div class="Tile">10</div>
<div class="Tile">11</div>
<div class="Tile">12</div>
<div class="Tile">13</div>
<div class="Tile">14</div>
<div class="Tile">15</div>
<div class="Tile">16</div>
<div class="Tile">17</div>
<div class="Tile">18</div>
<div class="Tile">19</div>
</div>
<div class="Column">
<div class="Tile">0</div>
<div class="Tile">1</div>
<div class="Tile">2</div>
<div class="Tile">3</div>
<div class="Tile">4</div>
<div class="Tile">5</div>
<div class="Tile">6</div>
<div class="Tile">7</div>
<div class="Tile">8</div>
<div class="Tile">9</div>
<div class="Tile">10</div>
<div class="Tile">11</div>
<div class="Tile">12</div>
<div class="Tile">13</div>
<div class="Tile">14</div>
<div class="Tile">15</div>
<div class="Tile">16</div>
<div class="Tile">17</div>
<div class="Tile">18</div>
<div class="Tile">19</div>
</div>
<div class="Column">
<div class="Tile">0</div>
<div class="Tile">1</div>
<div class="Tile">2</div>
<div class="Tile">3</div>
<div class="Tile">4</div>
<div class="Tile">5</div>
<div class="Tile">6</div>
<div class="Tile">7</div>
<div class="Tile">8</div>
<div class="Tile">9</div>
<div class="Tile">10</div>
<div class="Tile">11</div>
<div class="Tile">12</div>
<div class="Tile">13</div>
<div class="Tile">14</div>
<div class="Tile">15</div>
<div class="Tile">16</div>
<div class="Tile">17</div>
<div class="Tile">18</div>
<div class="Tile">19</div>
</div>
<div class="Column">
<div class="Tile">0</div>
<div class="Tile">1</div>
<div class="Tile">2</div>
<div class="Tile">3</div>
<div class="Tile">4</div>
<div class="Tile">5</div>
<div class="Tile">6</div>
<div class="Tile">7</div>
<div class="Tile">8</div>
<div class="Tile">9</div>
<div class="Tile">10</div>
<div class="Tile">11</div>
<div class="Tile">12</div>
<div class="Tile">13</div>
<div class="Tile">14</div>
<div class="Tile">15</div>
<div class="Tile">16</div>
<div class="Tile">17</div>
<div class="Tile">18</div>
<div class="Tile">19</div>
</div>
</div>
<div class="Footer">Footer</div>
</div>
So it doesn't look like you want the individual columns to scroll. If I've misinterpreted that requirement, then the solution is simple.
Make these adjustments to your code:
.Body {
background: orange;
display: flex;
flex-grow: 1;
/* overflow-y: scroll; */
min-height: 0; /* new */
}
.Column {
overflow: auto; /* new */
background: gold;
box-shadow: inset -1px 0 0 0 black;
display: flex;
flex-direction: column;
flex: 1 1;
padding-top: 1rem;
}
codepen
Here's an explanation for the modifications above: Why don't flex items shrink past content size?
If you just want the .Body element to scroll, add a wrapper:
<div class="Body">
<section><!---- NEW ----->
<div class="Column">
<div class="Tile">0</div>
<div class="Tile">1</div>
<div class="Tile">2</div>
<div class="Tile">3</div>
. . .
.Body {
background: orange;
flex-grow: 1;
overflow: auto;
}
section {
display: flex;
}
codepen
Here's an explanation for the modifications above: Make background color extend into overflow area
how can I have my grid container always stay centered but the elements with fixed width are still floating left, even on breaking? Just like in my example, but as shown, its not centered. Is there a need of js or is it fixable with css only? Thanks.
Here what I mean:
#wrap {
width: 100%;
background: #f8f8f8;
height: 300px;
}
#container {
width: 100%;
max-width: 400px;
background: #f1f1f1;
margin: auto;
}
#item {
background: white;
height: 50px;
width: 50px;
float: left;
padding: 5px;
}
#item1 {
width: 100%;
height: 100%;
background: red;
}
<div id="wrap">
<div id="container">
<div id="item">
<div id="item1"></div>
</div>
<div id="item">
<div id="item1"></div>
</div>
<div id="item">
<div id="item1"></div>
</div>
<div id="item">
<div id="item1"></div>
</div>
<div id="item">
<div id="item1"></div>
</div>
<div id="item">
<div id="item1"></div>
</div>
<div id="item">
<div id="item1"></div>
</div>
<div id="item">
<div id="item1"></div>
</div>
<div id="item">
<div id="item1"></div>
</div>
<div id="item">
<div id="item1"></div>
</div>
</div>
</div>
Note: Use class for multiple items instead of id. Same id should not be repeated in the code.
You can use Flexbox here. Use justify-content:center for align center of items.
Stack Snippet
#wrap {
width: 100%;
background: #f8f8f8;
height: 300px;
}
#container {
width: 100%;
max-width: 400px;
background: #f1f1f1;
margin: auto;
display: flex;
flex-wrap: wrap;
flex-direction: row;
}
.item {
background: white;
height: 50px;
width: 50px;
padding: 5px;
box-sizing: border-box;
}
.item1 {
width: 100%;
height: 100%;
background: red;
}
<div id="wrap">
<div id="container">
<div class="item">
<div class="item1"></div>
</div>
<div class="item">
<div class="item1"></div>
</div>
<div class="item">
<div class="item1"></div>
</div>
<div class="item">
<div class="item1"></div>
</div>
<div class="item">
<div class="item1"></div>
</div>
<div class="item">
<div class="item1"></div>
</div>
<div class="item">
<div class="item1"></div>
</div>
<div class="item">
<div class="item1"></div>
</div>
<div class="item">
<div class="item1"></div>
</div>
<div class="item">
<div class="item1"></div>
</div>
</div>
</div>
I have a dummy screen with background image. The background image correctly expands or contracts with the size of the viewport. I have dummy flexbox content that I intentionally make overflow the bottom of the page.
The scrollbar correctly appears, but it will not scroll far enough to show all the content that overflowed.
Apologies: the content is varied so I can tell what IS NOT showing.
Dummy header menu bar is fine.. it is supposed to scroll up - and it does.
CSS:
html {
box-sizing: border-box;
}
body {
box-sizing: border-box;
overflow-y: auto;
min-height: 100vh;
width: 100%;
margin: 0; padding: 0; border: 0; cursor: default
}
ul {
list-style: none;
li {
display: inline;
margin-left: 50px;
margin-top: 50px;
}
}
.blockStyleEven {
display: flex;
flex-direction: row;
color: white;
justify-content: space-evenly;
}
.blockSpaceAround {
display: flex;
flex-direction: row;
color: white;
justify-content: space-around;
}
.blockSpaceBetween {
display: flex;
flex-direction: row;
color: white;
justify-content: space-between;
}
.blockStart {
display: flex;
flex-direction: row;
color: white;
justify-content: flex-start;
}
.blockEnd {
display: flex;
flex-direction: row;
color: white;
justify-content: flex-end;
}
.blockCenter {
display: flex;
flex-direction: row;
color: white;
justify-content: center;
}
.maroon {
width: 100px;
height: 100px;
background-color: maroon;
}
.red {
width: 100px;
height: 100px;
background-color: red;
}
.green {
width: 100px;
height: 100px;
background-color: green;
}
.blue {
width: 100px;
height: 100px;
background-color: blue;
}
.workspace {
background: url("././Features.jpg") no-repeat center center fixed;
background-size: cover;
height: 100vh;
width: 100vw;
overflow: hidden;
h1 {
color: #E0B228;
}
h2 {
color: #2856E0;
}
}
HTML:
<div [ngStyle]="{'width': '100vw', 'height': '100vh'}">
<div [ngStyle]="{'display': 'flex', 'flex-direction': 'column'}">
<div [ngStyle]="{'background-color': 'beige'}">
<ul>
<li>First</li>
<li>Second</li>
<li>Third</li>
</ul>
</div>
<div class="workspace">
<div class="blockStyleEven">
<div class="maroon">space-evenly</div>
<div class="red">RED</div>
<div class="green">GREEN</div>
<div class="blue">BLUE</div>
</div>
<div class="blockSpaceAround">
<div class="maroon">space-around</div>
<div class="red">RED</div>
<div class="green">GREEN</div>
<div class="blue">BLUE</div>
</div>
<div class="blockSpaceBetween">
<div class="maroon">space-between</div>
<div class="red">RED</div>
<div class="green">GREEN</div>
<div class="blue">BLUE</div>
</div>
<div class="blockStart">
<div class="maroon">start</div>
<div class="red">RED</div>
<div class="green">GREEN</div>
<div class="blue">BLUE</div>
</div>
<div class="blockEnd">
<div class="maroon">end</div>
<div class="red">RED</div>
<div class="green">GREEN</div>
<div class="blue">BLUE</div>
</div>
<div class="blockCenter">
<div class="maroon">center</div>
<div class="red">RED</div>
<div class="green">GREEN</div>
<div class="blue">BLUE</div>
</div>
<div class="blockStyleEven">
<div class="maroon">space-evenly</div>
<div class="red">RED</div>
<div class="green">GREEN</div>
<div class="blue">BLUE</div>
</div>
<div class="blockSpaceAround">
<div class="maroon">space-around</div>
<div class="red">RED</div>
<div class="green">GREEN</div>
<div class="blue">BLUE</div>
</div>
<div class="blockSpaceBetween">
<div class="maroon">space-between</div>
<div class="red">RED</div>
<div class="green">GREEN</div>
<div class="blue">BLUE</div>
</div>
<div class="blockStart">
<div class="maroon">start</div>
<div class="red">RED</div>
<div class="green">GREEN</div>
<div class="blue">BLUE</div>
</div>
<div class="blockEnd">
<div class="maroon">end</div>
<div class="red">RED</div>
<div class="green">GREEN</div>
<div class="blue">BLUE</div>
</div>
<div class="blockCenter">
<div class="maroon">center</div>
<div class="red">RED</div>
<div class="green">GREEN</div>
<div class="blue">BLUE</div>
</div>
</div>
</div>
</div>
Thanks in advance.
Yogi
Finally figured it out. The problem was the scrollbar was "too short" to show all the content. This was because my workspace class was on a div below the dummy menu bar. When I put the workspace (containing Margin: auto) on the outer move div, it worked perfectly.
Thanks for all your help.
Apologies for the earlier poor formatting, which has now been cleaned up.
Yogi
How can I force flexbox items to have same height.
In examples I found online, people are using align-items: stretch css property, but my example is more complex.
Here is a codepen example:
.container {
background-color: red;
display: flex;
align-items: stretch;
}
.boxes {
background-color: yellow;
margin: 5px;
display: flex;
}
.boxes-column {
flex-direction: column;
}
.box {
background-color: green;
width: 100px;
margin: 5px;
}
.heading {
background-color: pink;
}
<body>
<div class="container">
<div class="boxes boxes-column">
<div class="heading">This is heading</div>
<div class="boxes">
<div class="box">Content content content content content content content</div>
<div class="box">Content content</div>
<div class="box">Content</div>
<div class="box">Contento contento</div>
<div class="box">Cc</div>
<div class="box">Contetno contento contento</div>
</div>
</div>
<div class="boxes boxes-column">
<div class="heading">This is heading 2</div>
<div class="boxes">
<div class="box">Content</div>
<div class="box">Contentno Contetn</div>
<div class="box">C</div>
</div>
</div>
</div>
</body>
Height of items items below 'Heading' and height of items below 'Heading 2' should be equal.
Used this css and now the boxes have the same height:
.container > .boxes > .boxes {
flex: 1;
}
Take a look at the below snippet:
.container {
background-color: red;
display: flex;
align-items: stretch;
}
.boxes {
background-color: yellow;
margin: 5px;
display: flex;
}
.boxes-column {
flex-direction: column;
}
.box {
background-color: green;
width: 100px;
margin: 5px;
}
.heading {
background-color: pink;
}
.container > .boxes > .boxes {
flex: 1;
}
<body>
<div class="container">
<div class="boxes boxes-column">
<div class="heading">This is heading</div>
<div class="boxes">
<div class="box">Content content content content content content content</div>
<div class="box">Content content</div>
<div class="box">Content</div>
<div class="box">Contento contento</div>
<div class="box">Cc</div>
<div class="box">Contetno contento contento</div>
</div>
</div>
<div class="boxes boxes-column">
<div class="heading">This is heading 2</div>
<div class="boxes">
<div class="box">Content</div>
<div class="box">Contentno Contetn</div>
<div class="box">C</div>
</div>
</div>
</div>
</body>