height of div is not filling 100% body height - html

I have a sidebar a header and a main container. main container and header is nested inside a parent div. When I set height 100% for both sidebar and main container the sidebar doesn't take 100% of the height of the body. I was thinking to not use any percentage values and let flexbox do the work. But I suspect that as I append elements inside the main container area sidebar will behave the same and not take the height of the body space. How can I fix this?
html {
height: 100%;
}
body {
margin: 0;
}
.sidebar {
display: inline-flex;
min-height: 100vh;
}
.sidebar-container {
background-color: #00ffff;
width: fit-content;
}
.header_main {
display: inline-block;
position: absolute;
color: white;
}
.header {
background-color: black;
width: 100vw;
}
.main {
height: 100vh;
width: 100vw;
background-color: bisque;
}
<div class="sidebar">
<div class="sidebar-container">sidebar</div>
</div>
<div class="header_main">
<div class="header">header</div>
<div class="main">main</div>
</div>

Easiest way would be to use CSS-Grid. Then simply set the body as grid-container and give it a min-height: 100vh:
body {
margin: 0;
min-height: 100vh;
display: grid;
grid-template-columns: min-content auto;
grid-template-rows: min-content auto;
}
aside {
width: fit-content;
background-color: #00ffff;
grid-row: 1 / -1;
}
header {
background-color: pink;
}
main {
background-color: bisque;
}
<aside>Sidebar</aside>
<header>Header</header>
<main>Main</main>

Related

Make an element scroll inside a grid section

I am trying to make a scrollable area inside my div like the image below. I want only the scrollable area to change height on different screen heights and scrolls accordingly.
The problem, is if the scrollable content is big enough to scroll, it will make the whole page scroll. If its small, the footer stays at the bottom correctly.
Here is a what I have so far
* {
margin: 0;
padding: 0;
width: 100%;
}
.container {
display: grid;
grid-template-rows: auto 1fr auto;
height: 100vh;
}
.header {
height: 30px;
background-color: lightblue;
}
.footer {
height: 30px;
background-color: lightblue;
}
.content {
display: grid;
grid-template-rows: auto 1fr;
}
.profile {
height: 60px;
background-color: lightpink;
}
.tabs {
height: 20px;
background-color: lightgreen;
}
.scroller {
background-color: cyan;
height: 100%;
overflow-y: scroll;
}
.scrollable-content {
background-color: yellow;
width: 200px;
height: 600px;
margin: 0 auto;
position: relative;
}
span {
bottom: 0;
left: 0;
position: absolute;
}
<div class="container">
<div class="header">Header</div>
<div class="content">
<div class="profile">Profile</div>
<div class="tab-control">
<div class="tabs">Tabs</div>
<div class="scroller">
<div class="scrollable-content">scrollable content<span>end</span></div>
</div>
</div>
</div>
<div class="footer">Footer</div>
</div>
Any help is appriciated
It works if you set some elements to have overflow: hidden;. Set that for .container, .content, and .tab-control
.container, .content, .tab-control {
overflow: hidden;
}
You will have a small issue with the .scroller element, part of it will be covered by the footer.
To fix that, add this too:
.tab-control {
display: flex;
flex-direction: column;
}
.scroller {
flex: 100% 1 1;
}
Set a fixed height on scroller. 100vh = height of the browser - 140px (the cumulative height of all the other elements on the page)
Set overflow-y: auto on the bar you want to scroll and you can set the height of .scrollable-content to as big as you want.
.scroller {
background-color: cyan;
height: calc(100vh - 140px);
overflow-y: scroll;
}
.scrollable-content {
background-color: yellow;
width: 200px;
height: 600px;
margin: 0 auto;
position: relative;
overflow-y: auto;
}

Child elements of min-height parent is not respecting 100% height of parent

I'm attempting to create a 2 column layout, with a header and footer. I want the page to initially be full height (100vh), with the ability to expand its height if the content was long.
Here's a CodePen showing part of what I'm attempting to achieve:
https://codepen.io/realslimsutton/pen/eYWzavw
The problem with the above CodePen, is that its height is fixed to 100vh. If I change the height of the container to be min-height: 100vh; instead of height: 100vh;, then the 2 columns reset their height back to 0.
An example of it not working with min-height set can be found at this CodePen: https://codepen.io/realslimsutton/pen/xxdONjO.
I've already tried the following things:
height: 100%; on all child elements of .container .content
align-self: stretch; on all child elements of .container .content
align-items: stretch; on all parent elements inside .container .content
None of the above attempts worked, the columns never filled the height of the parent.
Changed only a couple things. Don't forget the default is display: block
* {
box-sizing: border-box;
}
html, body {
margin: 0;
padding: 0;
}
.container {
min-height: 100vh;
width: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.container > .header, .container > .footer {
height: 10vh;
width: 100%;
}
.container .header {
background-color: rgb(239, 68, 68);
}
.container .footer {
background-color: rgb(59, 130, 246);
}
.container .content {
/*Line added since the default is block it wasn't working with
flex grow*/
display: flex;
flex-grow: 1;
}
.container .grid {
/*Now that your content "grows" you can inherit its height*/
height: inherit;
width: 100%;
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
}
.container .grid > div {
height: 100%;
width: 100%;
}
.container .grid .left, .container .grid .right {
height: 100%;
width: 100%;
}
.container .grid .left {
background: rgb(16,185,129);
}
.container .grid .right {
background: rgb(139,92,246);
}
<div class="container">
<div class="header"></div>
<div class="content">
<div class="grid">
<div>
<div class="left">
</div>
</div>
<div>
<div class="right">
</div>
</div>
</div>
</div>
<div class="footer"></div>
</div>

html css increase parents height if child height increases on scroll

Here is my html mockup
html, body {
margin:0px;
padding:0px;
height: 100vh;
background-color: gray;
}
.container {
display: flex;
width: 100%;
height: 100%;
background-color: red;
}
.left {
flex: 0.5;
height: 500px;
background: blue;
}
.right {
flex: 0.5;
height: 1300px;
background: green;
}
<!DOCTYPE html>
<html>
<body>
<div class="container">
<div class="left"></div>
<div class="right"></div>
</div>
</body>
</html>
Here class "right" has height of 1300px which makes scroll on to the window.
When I scroll the parent "container" is not as the height of "right".
I want the parent "container" height to be increased if child "right" height is increased".
How to achieve this ??
I did not understand what you mean, but test this code..
.container {
display: -ms-grid;
display: grid;
background-color: red;
-ms-grid-columns: 1fr 1fr;
grid-template-columns: 1fr 1fr;
gap:30px;
width: 100vw;
height: 100vh;
}
.left {
height: 200px;
background: blue;
}
.right {
background: green;
}

CSS values for DIV structure setup

I need to setup the following DIV structure (See image below. It tells more than a 1000 words)
The structure consists of 2 colums. The main column (left) has a variable width and 100% height.
The right colums has a FIXED width of 380px and 100% height.
Then inside the right column I need 3 DIVS.
The top DIV has a fixed height of 200px and must be aligned to the top.
The bottom DIV has a fixed height of 150px and must be aligned to the bottom.
The middle DIV has a variable height and must fill up the space vertically.
This is the DIV setup And the CSS I have:
.main-content {
width: 100%;
padding: 0px;
}
.col-1 {
width: calc(100% - 380px);
min-height: calc(var(--vh, 1vh)*100);
background-color: #2693FF;
float: left;
}
.col-2 {
width: 380px;
min-height: calc(var(--vh, 1vh)*100);
float: right;
}
.col-2-top {
height: 200px;
background-color: #00B200;
}
.col-2-middle {
height: 100%;
background-color: #FF8000;
}
.col-2-bottom {
height: 100px;
background-color: #B25900;
}
<div class="main-content">
<div class="col-1"></div>
<div class="col-2">
<div class="col-2-top"></div>
<div class="col-2-middle"></div>
<div class="col-2-bottom"></div>
</div>
</div>
Then... Column 1 and 2 should stack when the viewport width becomes less than 768px.
Column 1 on top and Column 2 below it.
Like this:
I think I'm almost there, but I'm having problems with the height of the Main DIV and the heights and aligning of the DIV col-2 middle DIV. I also need a bit helpt to get these divs stack nicely above each each other.
I would suggest that you use grid layout instead of floating around your <div>s, grid layout allows you to structure your layout and separate them in columns and rows, and areas using grid-template-areas.
for max-width:748 just add media query, here is how it might be implemented:
body {
padding: 0;
margin: 0;
}
.main-content {
display: grid;
background-color: #2196F3;
grid-template-areas:
'main fixed-top'
'main variable-mid-area'
'main fixed-bottom';
background-color: #2196F3;
height: 100vh;
grid-template-columns: 1fr 380px;
grid-template-rows: 200px 1fr 150px;
}
.main-content > div {
color: #fff;
font-size: 30px;
vertical-align: middle;
display: flex;
justify-content: center;
align-items: center;
}
.main {
grid-area: main;
background-color: #2693FC;
}
.variable-mid-area {
grid-area: variable-mid-area;
background-color: #FF8015;
}
.fixed-top {
grid-area: fixed-top;
background-color:#00B21F;
}
.fixed-bottom {
grid-area: fixed-bottom;
background-color: #B2590B;
}
#media only screen and (max-width: 768px) {
.main-content {
grid-template-areas:
'main'
'fixed-top'
'variable-mid-area'
'fixed-bottom';
grid-template-rows: 300px 200px 1fr 150px;
grid-template-columns: 100%;
height: auto;
}
}
<div class="main-content">
<div class="main"> main </div>
<div class="fixed-top"> 200 </div>
<div class="variable-mid-area"> auto </div>
<div class="fixed-bottom"> 150 </div>
</div>
If you have any questions how the css works, feel free to ask them in the comments.
I know the background-colors are irrelevant but they help to visualize it.
.container {
min-width: 768px;
width: 100%;
display: grid;
grid-template-columns: calc(100% - 380px) 1fr;
min-height: 100vh;
}
.col1 {
background-color: dodgerblue;
}
.col2 {
display: flex;
flex-direction: column;
}
.col2-row1 {
height: 200px;
background-color: orange;
}
.col2-row2 {
background-color: forestgreen;
height: 100%;
}
.col2-row3 {
height: 150px;
background-color: red;
}
#media (max-width: 768px) {
.container {
grid-template-columns: 1fr;
}
}
<div class="container">
<div class="col1">1</div>
<div class="col2">
<div class="col2-row1">2</div>
<div class="col2-row2">3</div>
<div class="col2-row3">4</div>
</div>
</div>

Absolute Position Vertical Nav with Flexbox

I want to make a vertical nav that say will be 50px and then I want to have a flex area that has my header, main content area and footer.
Right now when I use absolute the flexbox container gets covered over as absolute it doing it's own thing. I am wondering if I can tell my flex container to start 50px from the left so I don't have to worry about icons and such getting swallowed up by it.
Do I have to make the flex container absolute as well?
You don't need any positioning or margins, just make it natural with the additional flex wrapper:
body {margin: 0}
.outerFlex {
display: flex; /* displays flex-items (children) inline */
height: 100vh; /* 100% of the viewport height */
}
nav {
flex-basis: 50px; /* initial width */
background: lightblue;
}
.innerFlex {
flex: 1; /* takes the remaining width */
display: flex;
flex-direction: column; /* stacks flex-items vertically */
background: lightgreen;
}
main {
flex: 1; /* takes the remaining height */
}
<div class="outerFlex">
<nav>Nav</nav>
<div class="innerFlex">
<header>Header</header>
<main>Main</main>
<footer>Footer</footer>
</div>
</div>
You can use margin-left:50px on the flex area to make it start at 50px;
see code sample
body {
margin: 0;
height: 100vh;
}
.container {
height: 100%;
}
.nav {
position: absolute;
width: 50px;
background: green;
height: 100%;
}
.flex-container {
display: flex;
background: yellow;
height: 100%;
margin-left: 50px;
}
<div class="container">
<div class="nav"></div>
<div class="flex-container">text sample</div>
</div>
You just need to position your nav as absolute or fixed, then give padding/margin that equals the width of your nav to the main content.
Here's an example.
.container {
width: 100%;
}
.left-nav {
position: fixed;
width: 50px;
height: 100%;
background: black;
}
.main {
display: flex;
flex-direction: column;
justify-content: space-between;
padding-left: 50px;
background: rgba(255,0,0,0.1);
}
.main-header {
background: red;
}
.main-body {
background: green;
}
.main-footer {
background: blue;
}
<div class="container">
<div class="left-nav">Nav</div>
<div class="main">
<div class="main-header">Header</div>
<div class="main-body">Body</div>
<div class="main-footer">Footer</div>
</div>
</div>