This is a simplified HTML & CSS code to what I currently have in project. Essentially since I'm using ReactJS & routes, I can't wrap everything inside another container with a css grid so I'm looking for solutions to get full page height on both the 'sidebar' & 'content' classes.
I do understand that I could use 100vh and substract from that the height of the header but in this case the header doesn't have a fixed height so I'm looking for alternatives.
.header {
display: grid;
grid-template-columns: auto auto;
background-color: lightblue;
}
.main {
display: grid;
grid-template-columns: 0.2fr 1fr;
}
.sidebar {
background-color: lightpink;
height: 100%;
}
.content {
background-color: orange;
height: 100%;
}
<div class="header">
<div>
One
</div>
<div>
Two
</div>
</div>
<div class="main">
<div class="sidebar">
Menu
</div>
<div class="content">
Content
</div>
</div>
http://jsfiddle.net/de5ut6np/39/
You can consider the body as the main container:
html {
height:100%;
}
body {
margin:0;
height:100%;
display: grid;
grid-template-rows: max-content 1fr;
}
.header {
display: grid;
grid-template-columns: auto auto;
background-color: lightblue;
}
.main {
display: grid;
grid-template-columns: 0.2fr 1fr;
}
.sidebar {
background-color: lightpink;
height: 100%;
}
.content {
background-color: orange;
height: 100%;
}
<div class="header">
<div>
One<br>
more
</div>
<div>
Two
</div>
</div>
<div class="main">
<div class="sidebar">
Menu
</div>
<div class="content">
Content
</div>
</div>
I tested like this and it worked:
html {
height:100%;
}
body {
margin: 0;
height:100%;
display: grid;
grid-template-rows: max-content 1fr;
}
.header {
display: grid;
grid-template-columns: auto auto;
background-color: lightblue;
}
.main {
display: grid;
grid-template-columns: 0.2fr 1fr;
}
.sidebar {
display: grid;
background-color: lightpink;
}
.content {
display: grid;
background-color: orange;
}
<div class="header">
<div>
One
</div>
<div>
Two
</div>
</div>
<div class="main">
<div class="sidebar">
Menu
</div>
<div class="content">
Content
</div>
</div>
Related
I have a very simple grid layout of the menu, header, and content.
I would like the content (blue box) to stretch vertically. As you can see, the grid element (yellow box) already stretches vertically, but the blue element inside of it (which should be dynamic content) does not.
Is there a way to achieve this 1) without switching the whole grid structure to flexbox and 2) without using calc to give the blue content 100vh minus the header height?
.container {
height: 100vh;
display: grid;
grid-template-rows: min-content 1fr;
grid-template-columns: min-content 1fr;
grid-template-areas: "menu header" "menu content";
box-sizing: border-box;
overflow: hidden;
}
.mainMenuWrapper {
grid-area: menu;
height: auto;
}
.headerWrapper {
grid-area: header;
height: auto;
}
.contentWrapper {
grid-area: content;
overflow-y: auto;
height: auto;
background-color: yellow;
}
.menu {
height: 100vh;
background-color: red;
width: 50px;
}
.header {
height: 80px;
background-color: green;
}
.content {
background-color: blue;
width: 100%;
height: ???
}
<div class="container">
<div class="mainMenuWrapper">
<div class="menu">
menu
</div>
</div>
<div class="headerWrapper">
<div class="header">
header
</div>
</div>
<div class="contentWrapper">
<div class="content">
content
</div>
</div>
</div>
Image:
JSFiddle link: https://jsfiddle.net/the2sj1n/3/
You can apply height: 100% on that blue box .content
body {
margin: 0; /*Removed unexpected margins from browsers' default styles*/
}
.container {
height: 100vh;
display: grid;
grid-template-rows: min-content 1fr;
grid-template-columns: min-content 1fr;
grid-template-areas: "menu header" "menu content";
box-sizing: border-box;
overflow: hidden;
}
.mainMenuWrapper {
grid-area: menu;
height: auto;
}
.headerWrapper {
grid-area: header;
height: auto;
}
.contentWrapper {
grid-area: content;
overflow-y: auto;
height: auto;
background-color: yellow;
}
.menu {
height: 100vh;
background-color: red;
width: 50px;
}
.header {
height: 80px;
background-color: green;
}
.content {
background-color: blue;
width: 100%;
height: 100%; /*The change here*/
}
<div class="container">
<div class="mainMenuWrapper">
<div class="menu">
menu
</div>
</div>
<div class="headerWrapper">
<div class="header">
header
</div>
</div>
<div class="contentWrapper">
<div class="content">
content
</div>
</div>
</div>
How do I get rid of the space between the menu bar and the sidebar caused by typing hello.
I have tried
display:inline-block; and overflow:hidden; which got rid of the white space that was there previously and now filled it up with a color. I have also tried taking the content div and moving it so it isn't a parent(?) of .sidebar but then "hello" just ends up on the bottom of the page. I want to keep the "hello" text centered on the yellow area without having a space between the side bar and the menu bar.
Picture of the website
.menucontain{
display:grid;
grid-template-columns:1fr 1fr 1fr 1fr 1fr 1fr;
grid-column-gap:5px;
color:#F2F0D0;
text-align:center;
background-color:#204959;
font-family:helvetica;
padding:15px;
}
.sidebar{
background:#204959;
width:18%;
height:800px;
text-align:center;
color:#F2F0D0;
font-family:helvetica;
display:grid;
grid-template-rows: repeat(6 ,50px);
grid-gap:2px;
}
.side1{
background:gray;
padding-top:15px;
}
.content{
background-color:#F2F0D0;
text-align:center;
overflow:hidden;
}
<div class="menucontain">
<div class="menu1">Menu1</div>
<div class="menu2">Menu2</div>
<div class="menu3">Menu3</div>
<div class="menu4">Menu4</div>
<div class="menu5">Menu5</div>
<div class="menu6">Menu6</div>
<!--menu contain div on next line-->
</div>
<div class="content">
<p>hello</p>
<div class="sidebar">
<div class="side1">About</div>
<div class="side1">Blog</div>
<div class="side1">Sales</div>
<div class="side1">Partners</div>
<div class="side1">Portfolio</div>
<div class="side1">Contact</div>
</div>
</div>
Here is the correct solution to your problem.
First, move the tag <p> in sequence for sidebar. Like this:
...
<div class="sidebar">
<div class="side1">About</div>
<div class="side1">Blog</div>
<div class="side1">Sales</div>
<div class="side1">Partners</div>
<div class="side1">Portfolio</div>
<div class="side1">Contact</div>
</div>
<p>hello</p>
...
Secondly, assign the grid rules for the .content class by adding this to your css:
.content {
display: grid;
grid-template-columns: 18% 1fr;
}
And remove the width rules - width: 18% out of .sidebar selector. Because we defined the width as 18% in the grid rule above.
.menucontain {
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr;
grid-column-gap: 5px;
color: #f2f0d0;
text-align: center;
background-color: #204959;
font-family: helvetica;
padding: 15px;
}
.content {
display: grid;
grid-template-columns: 18% 1fr;
}
.sidebar {
background: #204959;
/*width: 18%;*/
height: 800px;
text-align: center;
color: #f2f0d0;
font-family: helvetica;
display: grid;
grid-template-rows: repeat(6, 50px);
grid-gap: 2px;
}
.side1 {
background: gray;
padding-top: 15px;
}
.content {
background-color: #f2f0d0;
text-align: center;
overflow: hidden;
}
<div class="menucontain">
<div class="menu1">Menu1</div>
<div class="menu2">Menu2</div>
<div class="menu3">Menu3</div>
<div class="menu4">Menu4</div>
<div class="menu5">Menu5</div>
<div class="menu6">Menu6</div>
<!--menu contain div on next line-->
</div>
<div class="content">
<div class="sidebar">
<div class="side1">About</div>
<div class="side1">Blog</div>
<div class="side1">Sales</div>
<div class="side1">Partners</div>
<div class="side1">Portfolio</div>
<div class="side1">Contact</div>
</div>
<p>hello</p>
</div>
The p tag is a block element, to remove the space you have to remove hello <\p> from the 'content' class
Use flex display or grid display on the 'content' class
Re-aling the 3 different parts (menucontain, sidebar, content) into a grid by declaring the body as a grid. Sicne you already use grids to style the menucontain and sidebar, you have to switch them to a subgrid.
body {
margin: 0;
display: grid;
grid-template-columns: 18vw auto;
grid-template-rows: min-content auto;
min-height: 100vh;
}
.menucontain {
grid-column: span 2;
display: grid;
grid-template-columns: repeat(6, 1fr);
grid-template-rows: subgrid;
grid-column-gap: 5px;
color: #F2F0D0;
text-align: center;
background-color: #204959;
font-family: helvetica;
padding: 15px;
}
.sidebar {
background: #204959;
height: 800px;
text-align: center;
color: #F2F0D0;
font-family: helvetica;
display: grid;
grid-template-columns: subgrid;
grid-template-rows: repeat(6, 50px);
grid-gap: 2px;
}
.side1 {
background: gray;
padding-top: 15px;
}
.content {
background-color: #F2F0D0;
text-align: center;
overflow: hidden;
}
<div class="menucontain">
<div class="menu1">Menu1</div>
<div class="menu2">Menu2</div>
<div class="menu3">Menu3</div>
<div class="menu4">Menu4</div>
<div class="menu5">Menu5</div>
<div class="menu6">Menu6</div>
</div>
<div class="sidebar">
<div class="side1">About</div>
<div class="side1">Blog</div>
<div class="side1">Sales</div>
<div class="side1">Partners</div>
<div class="side1">Portfolio</div>
<div class="side1">Contact</div>
</div>
<div class="content">
<p>hello</p>
</div>
I'm learning CSS Grid layout and i have a problem about positioning.
What i want is to create a page layout composed by a left-side menu, top-bar menu and a main content page like the image below:
I have been able to achieve the goal, but now i want to fix the position of the top bar and sidebar while main content is scrolling.
I set position:sticky to both containers but it does not working.
How can i fix?
Here is my code:
* {
margin: 0 !important;
padding: 0 !important;
box-sizing: border-box !important;
}
.grid-container {
display: grid;
grid-template-columns: auto 1fr;
grid-template-rows: 10% 100vh;
grid-template-areas:
"LeftMenu TopMenu"
"LeftMenu Main";
}
.LeftMenu {
background-color: #a4a4a4;
grid-area: LeftMenu;
width: 200px;
height: 100%;
}
.TopMenu {
background-color: #d49494;
grid-area: TopMenu;
width: 100%;
height: 100%;
display: flex;
}
.Main {
background-color: #8990eb;
grid-area: Main;
width: 100%;
height: 100vh;
}
<div class="xdg-component-appnav-menu">
<div class="grid-container">
<div class="LeftMenu">left menu</div>
<div class="TopMenu">top menu</div>
<div class="Main">
<p style="padding-bottom: 1000px;">Content</p>
</div>
</div>
</div>
You don't need position: sticky. It's extra complication and still isn't fully supported by some browsers.
Just use overflow: auto on the main container.
.grid-container {
display: grid;
height: 100vh;
grid-template-columns: 200px 1fr;
grid-template-rows: 10% 90%;
grid-template-areas:
"LeftMenu TopMenu"
" LeftMenu Main ";
}
.LeftMenu {
grid-area: LeftMenu;
background-color: #a4a4a4;
}
.TopMenu {
grid-area: TopMenu;
background-color: #d49494;
}
.Main {
grid-area: Main;
overflow: auto; /* key adjustment */
background-color: #8990eb;
}
body {
margin: 0;
}
<div class="xdg-component-appnav-menu">
<div class="grid-container">
<div class="LeftMenu">left menu</div>
<div class="TopMenu">top menu</div>
<div class="Main">
<p style="height: 1000px;">Content</p>
</div>
</div>
</div>
I have a html page that I don't want to scroll at the body scope, however, when using css grids that are nested, I can't control the body's scrollbar when content inside a nested grid overflows even when it has the property to scroll on overflow. The snippet I provide below I have a container which has grid and it contains a grid-area called workspace which has a component that is also a css grid. The component has content that forces the whole body to scroll, where I only want the content to scroll. I try messing with heights to 100% and 100vh, but no such luck.
body, html {
margin: 0px;
}
.container {
background-color: #282828;
color: whitesmoke;
display: grid;
grid-template-columns: 1fr min-content;
grid-template-rows: 42px 1fr;
grid-template-areas:
'tabs sidebar'
'workspace sidebar';
height: 100vh;
}
.tabs {
grid-area: tabs;
background-color: violet;
}
.sidebar {
grid-area: sidebar;
background-color: tomato;
min-width: 50px;
}
.workspace {
grid-area: workspace;
background-color: blue;
}
.component {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: min-content 1fr;
grid-template-areas:
'header'
'content';
}
.header {
grid-area: header;
}
.content {
grid-area: content;
overflow-y: scroll;
}
<div class="container">
<div class="tabs">
</div>
<div class="sidebar">
</div>
<div class="workspace">
<div class="component">
<div class="header">
<h1>My header</h1>
</div>
<div class="content">
<h1>Temp</h1>
<h1>Temp</h1>
<h1>Temp</h1>
<h1>Temp</h1>
<h1>Temp</h1>
<h1>Temp</h1>
<h1>Temp</h1>
<h1>Temp</h1>
<h1>Temp</h1>
<h1>Temp</h1>
<h1>Temp</h1>
</div>
</div>
</div>
</div>
To have a scrollbar the container should have a height that if the content exceed then the scrollbar will be activated so whenever you want to have a scrollbar you have to keep in your mind that the border of your container should be defined some how.
Now with that being said, if you don't want to have a fixed height then the main div should be a full screen then the nested container can have a scroll otherwise it will keep growing.
the full screen because you don't want to provide any fixed height otherwise , if you have a fixed height then it will be more simple
body, html {
margin: 0px;
}
.container {
background-color: #282828;
color: whitesmoke;
display: grid;
grid-template-columns: 1fr min-content;
grid-template-rows: 42px 1fr;
grid-template-areas:
'tabs sidebar'
'workspace sidebar';
height: 100vh;
position:absolute;
left:0px;
right:0px;
top:0px;
bottom:0px;
}
.tabs {
grid-area: tabs;
background-color: violet;
}
.sidebar {
grid-area: sidebar;
background-color: tomato;
min-width: 50px;
}
.workspace {
grid-area: workspace;
background-color: blue;
position: relative;
overflow-y: hidden;
}
.component {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: min-content 1fr;
grid-template-areas:
'header'
'content';
}
.header {
grid-area: header;
}
.content {
grid-area: content;
overflow: auto;
position: absolute;
bottom: 0px;
right: 0px;
left: 0px;
top: 80px;
}
<div class="container">
<div class="tabs">
</div>
<div class="sidebar">
</div>
<div class="workspace">
<div class="component">
<div class="header">
<h1>My header</h1>
</div>
<div class="content">
<h1>Temp</h1>
<h1>Temp</h1>
<h1>Temp</h1>
<h1>Temp</h1>
<h1>Temp</h1>
<h1>Temp</h1>
<h1>Temp</h1>
<h1>Temp</h1>
<h1>Temp</h1>
<h1>Temp</h1>
<h1>Temp</h1>
</div>
</div>
</div>
</div>
It's possible to "offset" a div in a css grid as in the image ?
Consider negative margin:
.container {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(3, 1fr);
width: 500px;
height: 200px;
border: 1px solid;
}
.box {
grid-column: 2/3;
margin-left: -20px;
margin-right: -80px;
background: red;
}
.box-alt {
grid-column: 2/3;
grid-row:2;
background: blue;
}
<div class="container">
<div class="box"></div>
<div class="box-alt"></div>
</div>
<div class="container">
<div class="area1"></div>
<div class="area2"></div>
</div>
.container{
display: grid;
grid-template: 1fr / repeat(3, 1fr);
grid-template-areas: "area1 offset area2";
}
.area{
width: 100%;
height: 40px;
}
.area1{
background-color: red;
}
.area2{
background-color: yellow;
}
If you are using Mozilla's guide in this link, you can use empty div like this as offset div:
<div class="container">
<div class="row">
<!-- Empty/Offset Div Here -->
<div class="col-xl-2"> </div>
<div class="col-xl-8">
<!-- Content Here -->
</div>
</div>
</div>