CSS3 Layout Grid - Sticky Header - html

I'm trying to build a layout with CSS Grid. I want the header element to be 'sticky'. That is, when the user scrolls, the header stays fixed to top of viewport and other content scrolls up and underneath header. I'd like to give this header a background image.
I've assigned a background image to the header, given it a position value of fixed and applied a z-index value of 999. Other elements below have been positioned and given lower z-index values.
My problem is that this setup doesn't work. I tried a few variations on the CSS but the background image either completely disappears or, on scroll, the header does not stay above other elements as they move up the screen.
What am I doing wrong? I browsed other questions in this forum and also on the web in general but can't find an answer.
Any suggestions much appreciated.
My code is shown below (including various changes to CSS - commented out in most cases).
body {
display: grid;
grid-template-areas: "header header header" "nav article ads" "footer footer footer";
grid-template-rows: 250px 900px 70px;
grid-template-columns: 20% 1fr 15%;
grid-row-gap: 10px;
grid-column-gap: 10px;
height: 100vh;
margin: 0;
}
header {
/* position:fixed;
z-index:999;*/
}
footer, article, nav, div {
padding: 1.2em;
background: gold;
}
#pageHeader {
grid-area: header;
padding: 1.2em;
background: url(https://placeimg.com/50/250/arch) left top repeat-x fixed;
}
#pageFooter {
grid-area: footer;
}
#mainArticle {
grid-area: article;
position: relative;
z-index: 9;
}
#mainNav {
grid-area: nav;
position: relative;
z-index: 8;
}
#siteAds {
grid-area: ads;
position: relative;
z-index: 7;
}
/* Stack the layout on small devices. */
#media all and (max-width: 575px) {
body {
grid-template-areas: "header" "article" "ads" "nav" "footer";
grid-template-rows: 80px 1fr 70px 1fr 70px;
grid-template-columns: 1fr;
}
}
<body>
<header id="pageHeader">Header</header>
<article id="mainArticle">Article</article>
<nav id="mainNav">Nav</nav>
<div id="siteAds">Ads</div>
<footer id="pageFooter">Footer</footer>
</body>

Remove other elements z-index. add position: fixed on your header and give it a width and height then also z-index of 1
Element positioned absolute works kinda like layers. The DOM and z-index (x and y axis is 2d coords and z axis is for the stacking) tells it where to sit depending on where it is on the DOM.
Read through this for a detailed explination...I will most likely screw it up if I try explain any further.

Your <header> element needs to be placed outside of your grid. Currently, the grid encompasses everything, including the header, since it's on the body tag. Instead of using display: grid; on the body, make a container within the body that has display: grid;, and make the header live outside of that container. For example:
HTML:
<body>
<header>Header content!</header>
<div class="container">
<div class="mainNav"></div>
<div class="sidebar"></div>
<div class="siteAds"></div>
<!-- etc. -->
</div>
</body>
And the CSS:
body {
/* your normal body styles go here */
/* but display: grid; should no longer be here */
}
header {
position: fixed;
z-index: 10;
height: 100px;
}
.container {
display: grid;
margin-top: 100px; /* to offset the header's height */
/* and all the rest of your grid styles */
}
What's important to remember here is that the header must not be part of the grid layout.

Use this Jsfiddle...
I have added some css styles and jQuery
CSS
#pageHeader.fixed {
position: fixed;
top:0;
left:0;
width: 100%;
z-index: 99;
}
jQuery
$(window).scroll(function(){
var sticky = $('#pageHeader'),
scroll = $(window).scrollTop();
if (scroll >= $('#pageHeader').height()){
sticky.addClass('fixed');
$('#pageHeader').addClass('fixed');
} else {
sticky.removeClass('fixed');
$('#pageHeader').removeClass('fixed');
}
});

Related

Grid setup in CSS?

I am new to CSS and HTML and have a setup of divs in CSS, something like this:
#topBar {
margin-top: 0;
height: 100px;
width: 100%
}
#sideBar {
width: 50px;
margin-left: 0;
margin-top: 100px;
height: 100%;
}
#main {
margin-left: 50px;
margin-top: 100px;
margin-bottom: 50px;
}
#footer {
margin-bottom: 0;
width: 100%;
}
<div id="container">
<div id="topbar" />
<div id="sidebar" />
<div id="main" />
<div id="footer" />
</div>
But that does not look anything like how I want it. It leaves space for every div, even though their space is restricted to x width and x height.
How could I set up divs to look as desired? Ie have a footer, main, sidebar, and topbar in CSS?
CSS actually has built in grid "builder" that you can use. I was doing something similar not long ago and ended up doing it like this:
#container {
display: grid; //uses grid
height: 100vh; // vh and vw is percentages of the screens width and height, nice for scaling for different devices
width: 100vw;
grid-template-columns: 1fr 9fr; // sets how big columns are, this sets the column quantity to two, and the first one gets 1 fraction of the are, and column two gets 9 fractions. 1fr is for sidebar
grid-template-rows: 1.5fr 15fr 3fr; // Same as with column, but this includes footer, so 1.5 fraction goes to top bar, 15 fractions to sidebar and main area, and 3 fractions to footer
grid-template-areas:
"header header" // sets area to use, the same area given space in above lines. They can be directly referenced in other parts of the css documents.
"navbar main"
"footer footer";
}
#topbar {
grid-area: header; // Referencing previous made areas
display: flex; // I used this to make the top bar, as this would align the items in the bar horizontally with same amount of space between
justify-content: space-between;
align-items: center; //used this to center items vertically
}
#sidebar {
grid-area: sidebar;
text-align: center; // used this to align the text center horizontally
}
#main {
grid-area: main;
}
#footer {
grid-area: footer;
}
You should use the semantic tags such as the header, nav, aside, footer and main.
Then apply the grid directly to the body element instead of wrapping them in an extra container:
body {
margin: 0; /* removes default margin */
display: grid; /* uses grid */
min-height: 100vh; /* will expend the grid to the entire viewport */
grid-template-columns: 1fr 2fr; /* sets the column width and amount */
grid-template-rows: min-content auto min-content; /* sets the row height to push the footer at the bottom and let the main fill the rest */
gap: 5px; /* placing the items apart */
}
header,
footer {
grid-column: 1 / -1; /* letting those element span the entire row */
}
/* for styling purpose only */
header,
aside,
main,
footer {
border: 2px dashed red;
display: flex;
justify-content: center;
align-items: center;
padding: 10px;
}
<header>Topbar</header>
<aside>Sidebar</aside>
<main>Main</main>
<footer>Footer</footer>

CSS grid with fixed widths for some columns

I am trying to achieve this layout by using CSS grid.
Picture:
This is what I have so far:
#wrapper {
display: grid;
gap: 20px;
grid-template-columns: auto 300px 1fr 1fr 180px auto;
grid-template-rows: auto;
grid-template-areas:
"logo nav-primary nav-primary nav-primary nav-primary search"
"nav-secondary nav-secondary nav-secondary nav-secondary nav-secondary nav-secondary"
"aside-1 aside-1 article article aside-2 aside-2"
"footer footer footer footer footer footer";
}
/* Article: use up remaining width */
#article{
grid-area: article;
}
/* Logo: use up a little width as possible */
#logo{
grid-area: logo;
}
/* Nav Primary: use up remaining width */
#nav-primary{
grid-area: nav-primary;
}
/* Nav Secondary: use full width */
#nav-secondary{
grid-area: nav-secondary;
}
/* Search: use up a little width as possible */
#search{
grid-area: search;
}
/* Aside 1: fixed with of 300px */
#aside-1{
grid-area: aside-1;
}
/* Aside 2: fixed with of 180px */
#aside-2{
grid-area: aside-2;
}
/* Footer: use full width */
#footer{
grid-area: footer;
}
/* Demo style */
#wrapper > * {
background: #C4C4C4;
padding: 10px;
}
<div id="wrapper">
<article id="article">Article (use up remaining space)</article>
<header id="logo">Logo</header>
<nav id="nav-primary">Nav Primary</nav>
<nav id="nav-secondary">Nav Secondary</nav>
<form id="search">Search Form</form>
<aside id="aside-1">Aside 1 (fixed width: 300px)</aside>
<aside id="aside-2">Aside 2 (fixed width: 180px)</aside>
<footer id="footer">Footer</footer>
</div>
Codepen: https://codepen.io/aobrien/pen/YzwNZpy
The issue is that Aside1 is not 300px, but instead 300px + the width of the logo column. Same for Aside2, its 180px + the width of the search column.
I can’t seem to set a fixed width for Aside1 and Aside2, while at the same time having the logo and the search be dynamic in width to fit their content and be as small as possible.
The logo box must always be as small as possible so it only fits the content. Same for the search, as small as possible.
Aside1 needs to have a fixed width of 300px and Aside2 needs to have a fixed width of 180px.
My only rule is, I cannot make any changes to the HTML structure as seen, so no nesting of these items. However I can add new HTML elements inside of the current elements, which could contain a fixed width (if that helps?).
I don’t have to rely on grid-template-areas, it can be an explicit or implicit grid. It can also contain more columns if it somehow helps. Any changes to the CSS are welcome.
The only solution I seem to have had so far (which is not a solution I want to settle for) is to assign a fixed width to the logo and the search and then calculate the remaining width to achieve the width of Aside1 and Aside2. However this is really not what I was looking for as I would like to keep it as dynamic as possible without the need to manually set multiple fixed widths across the layout.
Another solution I tried was instead of defining a fixed width of Aside1 via grid-template-columns, I could create a new div inside of Aside1 and give that a width: 300px and set grid-template-columns to auto for that column. This does work except if the logo gets wider than 300px then Aside1 becomes wider than 300px as well.
Does anyone have any solutions or pointers that could help me out?
First of all you have 6 columns, but we can keep only 5 for this task. Second - we don't need to set fixed width in grid-template-columns if we are going to use t cells collapsing. Match easier to set fixed width for specific columns. Here you go
#wrapper {
display: grid;
gap: 15px;
grid-template-columns: auto auto 1fr auto auto;
grid-template-rows: auto;
grid-template-areas:
"logo nav-primary nav-primary nav-primary search"
"nav-secondary nav-secondary nav-secondary nav-secondary nav-secondary"
"aside-1 aside-1 article aside-2 aside-2"
"footer footer footer footer footer";
}
/* Article: use up remaining width */
#article {
grid-area: article;
}
/* Logo: use up a little width as possible */
#logo {
grid-area: logo;
max-width: 300px;
}
/* Nav Primary: use up remaining width */
#nav-primary {
grid-area: nav-primary;
}
/* Nav Secondary: use full width */
#nav-secondary {
grid-area: nav-secondary;
}
/* Search: use up a little width as possible */
#search {
grid-area: search;
max-width: 180px;
}
/* Aside 1: fixed with of 300px */
#aside-1 {
grid-area: aside-1;
width: 300px;
}
/* Aside 2: fixed with of 180px */
#aside-2 {
grid-area: aside-2;
width: 180px;
}
/* Footer: use full width */
#footer {
grid-area: footer;
}
/* Demo style */
#wrapper>* {
background: #C4C4C4;
padding: 10px;
box-sizing: border-box;
}
<div id="wrapper">
<article id="article">Article (use up remaining space)</article>
<header id="logo">Logo</header>
<nav id="nav-primary">Nav Primary</nav>
<nav id="nav-secondary">Nav Secondary</nav>
<form id="search">Search Form</form>
<aside id="aside-1">Aside 1 (fixed width: 300px)</aside>
<aside id="aside-2">Aside 2 (fixed width: 180px)</aside>
<footer id="footer">Footer</footer>
</div>
Note that in this case your Logo should be less than 300px width. And Search should be less than 180px width. If you want Search to be wider than 180px - we should edit the code a bit.
#wrapper {
display: grid;
gap: 15px;
grid-template-columns: auto auto 1fr auto auto auto;
grid-template-rows: auto;
grid-template-areas:
"logo nav-primary nav-primary search search search"
"nav-secondary nav-secondary nav-secondary nav-secondary nav-secondary nav-secondary"
"aside-1 aside-1 article article aside-2 aside-2"
"footer footer footer footer footer footer";
}
/* Article: use up remaining width */
#article {
grid-area: article;
}
/* Logo: use up a little width as possible */
#logo {
grid-area: logo;
max-width: 300px;
}
/* Nav Primary: use up remaining width */
#nav-primary {
grid-area: nav-primary;
}
/* Nav Secondary: use full width */
#nav-secondary {
grid-area: nav-secondary;
}
/* Search: use up a little width as possible */
#search {
grid-area: search;
}
/* Aside 1: fixed with of 300px */
#aside-1 {
grid-area: aside-1;
width: 300px;
}
/* Aside 2: fixed with of 180px */
#aside-2 {
grid-area: aside-2;
width: 180px;
}
/* Footer: use full width */
#footer {
grid-area: footer;
}
/* Demo style */
#wrapper>* {
background: #C4C4C4;
padding: 10px;
box-sizing: border-box;
}
<div id="wrapper">
<article id="article">Article (use up remaining space)</article>
<header id="logo">Logo</header>
<nav id="nav-primary">Nav Primary</nav>
<nav id="nav-secondary">Nav Secondary</nav>
<form id="search">Search Form</form>
<aside id="aside-1">Aside 1 (fixed width: 300px)</aside>
<aside id="aside-2">Aside 2 (fixed width: 180px)</aside>
<footer id="footer">Footer</footer>
</div>

Understanding auto in css grids [duplicate]

This question already has answers here:
Percentage Height HTML 5/CSS
(7 answers)
Closed 2 years ago.
I am pretty new to Web development and I am trying to learn CSS grids. While learning the CSS grid I tried to make one simple layout. It has one header section, one menu section, one sidebar section, and one footer section.
I used auto while defining grid template rows for the 2nd row, and gave conatiner height as 100%, so that 2nd row will stretch fully in the remaining space left by row 1 and 2.
But it didn't work that way, i am trying to figure out why 2nd row is not stretching vertically in the remaning space left.
Here is the conatiner css in which i defined the 2nd row as auto and conatiner height as 100%.
.container {
height: 100%;
display: grid;
grid-template-columns: repeat(12, 1fr);
grid-template-rows: 40px auto 40px;
}
fiddle link:
https://jsfiddle.net/791vtd4z/
That is because you did not give body a fixed height, yet you have .container a relative height: therefore, when the child .container simply stretches to its content height and not any further, since there's nothing absolute to compare against by using 100% (ask yourself: "100% of what?").
A solution will be to set .container { min-height: 100vh; } to fix that, which tells the element to at least be as tall as the viewport, and allow it to grow should the content inside menu or sidebar grow beyond what the viewport can contain.
* {
margin: 0;
top: 0;
bottom: 0;
font-family: sans-serif;
font-size: 1.2em;
}
title {
display: none;
}
.container {
min-height: 100vh;
display: grid;
grid-template-columns: repeat(12, 1fr);
grid-template-rows: 40px auto 40px;
}
.Header {
background-color: beige;
grid-column: 1/-1;
}
.Menu {
background-color: red;
}
.Sidebar {
background-color: burlywood;
grid-column: 2/-1;
}
.Footer {
background-color: aquamarine;
grid-column: 1/-1;
}
<div class="container">
<div class="Header">Header</div>
<div class="Menu">Menu</div>
<div class="Sidebar">Sidebar</div>
<div class="Footer">Footer</div>
</div>
To build on Terry's answer, you can achieve your desired result by giving body a height of 100vh, you could change the height of .container to 100vh, or you could give html and body a height of 100% (and keep the 100% height of .container).
This is because 100vh gives an element the full height of the viewport regardless of the height of its parents, while setting an element's full height using a percentage (i.e. 100%) means the element takes the full height of its parent, whatever that is. So an element with a height of 100% could still be zero, if its parent has no height.
To put this another way, when setting an element's height to 100% all of its parents need to be 100% as well for that element to take up the full viewport.
html, body{
height: 100%;
}
* {
margin: 0;
top: 0;
bottom: 0;
font-family: sans-serif;
font-size: 1.2em;
}
title {
display: none;
}
.container {
height: 100%;
display: grid;
grid-template-columns: repeat(12, 1fr);
grid-template-rows: 40px auto 40px;
}
.Header {
background-color: beige;
grid-column: 1/-1;
}
.Menu {
background-color: red;
}
.Sidebar {
background-color: burlywood;
grid-column: 2/-1;
}
.Footer {
background-color: aquamarine;
grid-column: 1/-1;
}
<div class="container">
<div class="Header">Header</div>
<div class="Menu">Menu</div>
<div class="Sidebar">Sidebar</div>
<div class="Footer">Footer</div>
</div>

Image (img) tag in html causing container grid-area to extend

I'm starting out in HTML/CSS and I'm looking at using grids (grid-template-areas). I have the layout how I like it, and the top left grid-area is for my site logo. The issue I'm having is that when I add an tag to the html, it causes the container to grow. I've attached images to show what I mean. The strange thing is it isn't growing by the same width as the image, so there seems to be some kind of offset going on that I don't know how to stop.
UPDATE: I realised this isn't an issue with the img tag, as even adding text into the .logo grid area causes the same issue.
Note how the width of the container seems to grow by about 50% of the image width. I don't know why this is happening. I've tried adding different properties to the img{} in the stylesheet, as well as the container, but nothing seems to resolve it.
Any ideas or suggestions on where to look would be great. I've spent some time searching but all the results are teaching you how to grow/shrink/align your image vs stopping it messing with the container.
Here is my HTML:
<div class="grid-container">
<div class="logo">
<img src="media/images/centrecircle.jpg" />
</div>
<div class="header">
<h1>KickBallLife</h1>
</div>
<div class="leftNav">Left Nav</div>
<div class="content">
<asp:ContentPlaceHolder id="ContentPlaceHolder1" runat="server"></asp:ContentPlaceHolder>
</div>
<div class="rightWidget">Widget</div>
<div class="footer">Footer</div>
</div>
Here is my CSS:
{
box-sizing: border-box;
}
img {
}
/* The grid container */
.grid-container {
display: grid;
grid-template-areas: 'logo header header header header header'
'left middle middle middle middle right'
'footer footer footer footer footer footer';
/* grid-column-gap: 10px; - if you want gap between the columns */
}
.leftNav,
.content,
.rightWidget {
padding: 10px;
}
.header {
grid-area: header;
background-color: cadetblue;
height: 100px;
}
.logo {
grid-area: logo;
background-color: cornflowerblue;
height: 100px;
}
.leftNav {
grid-area: left;
background-color:lightblue;
}
.content {
grid-area: middle;
background-color:darkblue;
}
.rightWidget {
grid-area: right;
background-color:aquamarine;
}
.footer {
grid-area: footer;
background-color:coral;
padding: 10px;
text-align: center;
}
#media (max-width: 1200px) {
.grid-container {
grid-template-areas: 'logo logo logo logo logo logo'
'header header header header header header'
'left left left left left left'
'middle middle middle middle middle middle'
'right right right right right right'
'footer footer footer footer footer footer';
}
I don't know if this is relevant, but the actual html is within an .aspx master page.
Thanks in advance,
Terry
Set a width on the .logo in your css.
{
box-sizing: border-box;
}
img {
}
/* The grid container */
.grid-container {
display: grid;
grid-template-areas: 'logo header header header header header'
'left middle middle middle middle right'
'footer footer footer footer footer footer';
/* grid-column-gap: 10px; - if you want gap between the columns */
}
.leftNav,
.content,
.rightWidget {
padding: 10px;
}
.header {
grid-area: header;
background-color: cadetblue;
height: 100px;
}
.logo {
grid-area: logo;
background-color: cornflowerblue;
height: 100px;
width: 100px; /* Change to whatever width works with your image*/
}
.leftNav {
grid-area: left;
background-color:lightblue;
}
.content {
grid-area: middle;
background-color:darkblue;
}
.rightWidget {
grid-area: right;
background-color:aquamarine;
}
.footer {
grid-area: footer;
background-color:coral;
padding: 10px;
text-align: center;
}
#media (max-width: 1200px) {
.grid-container {
grid-template-areas: 'logo logo logo logo logo logo'
'header header header header header header'
'left left left left left left'
'middle middle middle middle middle middle'
'right right right right right right'
'footer footer footer footer footer footer';
}
First things first, comment-out or remove the first 3 lines of your CSS code. Either that or figure out which element selector you are trying to set the border-sizing attribute on. Without a selector on line 1 the rest of your CSS will be buggy.
Second, you need a width set on the parent container to prevent the logo, or any other content, from blowing up your grid.
I’ll also have to admit, CSS Grids was a tricky concept to learn myself. I mean, understanding FlexBox was tough but CSS Grids is a whole another step more complex. Further, there are still issues with current browsers regarding your ability to get them to render CSS Grids consistently.
Good luck!
OK I figured it out. I needed to use the grid-template-columns property to set the widths of each column. What threw me was I'd tried it previously but had comma separated the values, when it should just be space separated like so:
grid-template-columns: 15% 17.5% 17.5% 17.5% 17.5% 15%;
So the container would be:
.grid-container {
display: grid;
grid-template-columns: 15% 17.5% 17.5% 17.5% 17.5% 15%;
grid-template-areas: 'logo header header header header header' 'left middle middle middle middle right' 'footer footer footer footer footer footer';
}
Thanks for the suggestions and starting points all!
Terry

Filling content background till it reaches footer

I have similar problem which can be found here. But i couldn't make it work or i didnt understand it fully.
My problem which im trying to resolve is - I want my content background to reach footer even if there isnt enough content to be displayed. I created a simple fiddle which can be found here. As you can see there isnt enough content to reach footer and there is this "blue" space between content and footer. I would like to make that space grey.
HTML :
<div class=blue>header here</div>
<p>LOGO here</p>
<div class="blue">navigation bar here</div>
<div class="content">
No content.
</div>
<div class="footer">footer is here</div>
CSS:
.blue {
color: #ffffff;
background-color: #294a70;
display: block;
float: none;
width: 400px;
margin: 0 auto;
text-align: center;
}
p {
text-align: center;
color: #ffffff;
}
.content {
background-color: #e6e6e6;
display: block;
float: none;
margin: 0 auto;
overflow:hidden;
width:400px;
margin-bottom:30px;
}
.footer {
color: #ffffff;
background-color: #294a70;
display: block;
float: none;
width: 400px;
margin: 0 auto;
text-align: center;
position: absolute;
bottom: 0;
left: 0;
right: 0;
height:30px;
}
body {
margin:0;
padding:0;
font-family: 'Open Sans', sans-serif;
line-height: 1.5;
font-size: 14px;
overflow-x:hidden;
background-image:url('http://www.planwallpaper.com/static/images/Alien_Ink_2560X1600_Abstract_Background_1.jpg');
min-height: 100%;
}
html {
position:relative;
min-height: 100%;
}
All help will be appreciated!
Use CSS3 calc() function
the trick is, if you know the height of header & footer, you can use this function with vh units, 100vh gives you screen height, just substract the height of hearder & footer from it.
E.g.
If header is 80px & Footer is 40px, i.e. total 120px, then use
.content{
min-height: calc(100vh - 120px);
}
The purpose of using min-height is if content is not present then atleast this height is applied, but if there is more content than screen then div is expanded to fit accordingly.
Updated JSFiddle:
https://jsfiddle.net/vj07e8g1/5/
You could try a flexbox layout instead:
HTML
<body>
<header></header>
<main class="content"></main>
<footer></footer>
</body>
CSS
body {
display: flex;
min-height: 100vh;
flex-direction: column;
}
main.content {
flex: 1;
}
Check out this codepen example: http://codepen.io/StefanBobrowski/pen/zZXXWy
You can add this to your content style:
min-height:400px;
It'll push the footer a little, but it'll do the work.
Hope this is what you're looking for.
The easiest contemporary way, depending on your browser-support requirements, would be to use CSS grids, which allows you to define rows and columns and assign certain content to be in specific places (placed by grid-row and grid-column), like follows:
html,
body {
height: 100%;
}
/* to force all elements to be sized including
their padding and border-widths */
body,
::before,
::after {
box-sizing: border-content;
}
body {
/* To use CSS grid, forcing the child elements of
the <body> element to adopt 'display: grid-item': */
display: grid;
/* defining the three columns of the grid, the first and
third being equal fractions of the space left over after
the second (middle) column's width of 400px is calculated */
grid-template-columns: 1fr 400px 1fr;
/* reducing the first three rows to the minimum height needed
to fully display their content, setting the fourth row
to take up the remaining unoccupied space once the other
heights are calcuated and setting the final row's height to
30px: */
grid-template-rows: min-content min-content min-content 1fr 30px;
height: 100vh;
background-image: url(https://i.stack.imgur.com/2oC8H.jpg);
}
body>* {
/* setting all the child elements of the <body> to be placed
in grid-column 2 (the central 400px-wide column): */
grid-column: 2;
}
/* Setting the default shared styles of the .blue elements: */
.blue {
color: #ffffff;
background-color: #294a70;
}
.blue.header {
/* positioning this element in the first (one-based counting)
row: */
grid-row: 1
}
body>p {
grid-row: 2;
}
.blue.navigation {
grid-row: 3;
}
div.content {
grid-row: 4;
/* background-color purely to show that the space of the
div.content element occupies the full space available: */
background-color: #ffa;
}
div.footer {
grid-row: 5;
}
<div class="header blue">header here</div>
<p>LOGO here</p>
<div class="blue navigation">navigation bar here</div>
<div class="content">
No content.
</div>
<div class="footer">footer is here</div>
JS Fiddle.
Please note that I did add a class-name to both the .blue elements in order to more-easily distinguish them according to their roles in the document, and from each other when placing them in the document.