Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

+ add another resource

JavaScript

Babel includes JSX processing.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Packages

Add Packages

Search for and use JavaScript packages from npm here. By selecting a package, an import statement will be added to the top of the JavaScript editor for this package.

Behavior

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML

              
                <header><h1 id="top">Responsive navbar using flexbox in a page with a sticky footer using grid</h1></header>
<nav role="navigation">
  <a class="active" href="#top">Home</a>
  <a href="#flex-footer">Flexbox Footer</a>
  <a href="#grid-footer">Grid Footer</a>
  <a href="#tldr-footer">Footer (TL;DR)</a>
  <a href="#navbar">Navbar</a>
  <div class="middle"></div>
  <a class="codepen" href="https://codepen.io/gavinsykesuk" target="_blank"><i class="fab fa-codepen"></i><span> Codepen</span></a>
  <a class="github" href="https://github.com/gavinsykes" target="_blank"><i class="fab fa-github"></i><span> Github</span></a>
  <a class="linkedin" href="https://www.linkedin.com/in/gavinsykes/" target="_blank"><i class="fab fa-linkedin"></i><span> LinkedIn</span></a>
  <a class="stackoverflow" href="https://stackoverflow.com/users/8640133/gavin" target="_blank"><i class="fab fa-stack-overflow"></i><span> Stack Overflow</span></a>
  <a class="twitter" href="https://www.twitter.com/gavinsykes_uk" target="_blank"><i class="fab fa-twitter"></i><span> Twitter</span></a>
  <div id="nav-open" class="open-icon">≡</div>
</nav>
<main>
  <section>
  <h2>Starting with the footer positioning</h2>
  <p>A common issue with placing footers can be a page looking unneat when its content does not reach to the bottom of a user's viewport. This was not so complicated in earlier times, when the web was still on computers and there were limited different screen sizes.</p>
  <div class="showcase"><iframe src="https://giphy.com/embed/xT5LMEIXe6RgCUuDcI" width="480" height="366" frameBorder="0" class="giphy-embed" allowFullScreen></iframe><p><a href="https://giphy.com/gifs/season-9-the-simpsons-9x14-xT5LMEIXe6RgCUuDcI">via GIPHY</a></p></div>
  <p>Nowadays though, with all sorts of different screen sizes available, and in the mobile age, it is more important than ever to make your content adapt to any screen size.</p>
  <p>There are all sorts of ways to do this, mostly involving JavaScript, that have all sorts of dependencies such as fixed-height footers, which considering how dynamic content can be, simply isn't practical.</p>
  <p>Now with recent CSS features though, it is very simple to achieve, in one of 2 ways:</p>
  </section>
  <section id="flex-footer">
  <h3>Flexbox</h3>
  <p>As the name might suggest, flexbox allows its child items to be displayed in a flexible manner, manipulating their positioning and sizing along an axis, and you as the developer get to decide if this axis is the horizontal or the vertical. To achieve a sticky footer we use flexbox vertically.</p>
  <p>Imagine a simple page layout, with a <span  class="code">&lt;header&gt;</span>, <span class="code">&lt;nav&gt;</span> (which we'll come to sorting later), <span class="code">&lt;main&gt;</span> and <span  class="code">&lt;footer&gt;</span>:</p>
  <div class="codeblock">&lt;header&gt;&lt;/header&gt;<br/>&lt;nav&gt;&lt;/nav&gt;<br/>&lt;main&gt;&lt;/main&gt;<br/>&lt;footer&gt;&lt;/footer&gt;<br/>
  </div>
  <p>We set our surrounding body tag as a flex container. This in itself doesn't do anything to its child elements, but it does tell them that they are in a flex container and can use certain properties as a result.</p>
  <p>The next important piece of code is telling our <span class="code">&lt;body&gt;</span> what to do with its flex children, we want it to arrange them in a column (because we're stacking everything on top of each other rather than to the side) and not wrap them, we can do this in one line of CSS with <span class="code">flex-flow: column nowrap;</span>. I haven't seen what would happen if it did wrap, and given how we will set up our child elements I doubt it would try to wrap anyway, but if it ever did the results would be bad, so that <span class="code">nowrap</span> acts as a safety feature more than anything.</p>
  <p>In order to get our header and footer right to the edge of the viewport, it is often useful to set the margins on our <span class="code">&lt;body&gt;</span>, and even our <span class="code">&lt;html&gt;</span>, to 0, and their minimum heights to 100vh;</p>
  <p>One additional thing we can do is set <span class="code">align-items</span> to stretch, this stretches all of our elements across its axis, removing the need to set their widths individually.</p>
  <div class="codeblock">html {<br/>&nbsp;margin: 0;<br/>&nbsp;min-height: 100vh;<br/>}<br/>&nbsp;<br/>body {<br/>&nbsp;margin: 0;<br/>&nbsp;min-height: 100vh;<br/>&nbsp;display: flex;<br/>&nbsp;flex-flow: column nowrap;<br/>&nbsp;align-items: stretch;<br/>}<br/>&nbsp;<br/>footer {<br/>}<br/>&nbsp;<br/>header {<br/>}<br/>&nbsp;<br/>main {<br/>}<br/>&nbsp;<br/>nav {<br/>}<br/>
    </div>
  <p>Now that the container is taken care of, we need to look at the children. The beauty of flex children is that they can stretch and shrink to acommodate any environment, but they can also be set to do the exact opposite of that, which is what we want to do here. We do this by utilising the <span class="code">flex-grow</span> and <span class="code">flex-shrink</span> properties.</p>
  <p><span class="code">flex-grow</span> is set to a number and behaves according to that number in relation to its siblings, if two flex children each have a <span class="code">flex-grow</span> value of 1 then they will grow at the same rate, if you change one of them to 2 however then that one will grow at twice the rate of the other one. <span class="code">flex-shrink</span> works much the same way only it does the opposite, it shrinks items rather than growing them.</p>
  <p>If you set <span class="code">flex-grow</span> to 0 it will not grow at all, and the same applies with shrinking when <span class="code">flex-shrink</span> is set to 0.</p>
  <p>With this in mind we want our <span class="code">&lt;header&gt;</span>, <span class="code">&lt;nav&gt;</span> and <span class="code">&lt;footer&gt;</span> to keep their height i.e. not grow or shrink, and our <span class="code">&lt;main&gt;</span> to take up the rest of the available room.</p>
  <p>In order to have our <span class="code">&lt;main&gt;</span> take up the rest of the available space, simply set its <span class="code">flex-grow</span> to 1, this has the added bonus effect of not needing to set it to 0 on our other elements, as if only 1 element is expanding to take up all available room, no others will.</p>
  <p>We should, however, make sure that none of our elements shrink, by setting their <span class="code">flex-shrink</span> property to 0. On our <span class="code">&lt;main&gt;</span> this can be done by the shorthand property <span class="code">flex</span>, which sets <span class="code">flex-grow</span> and <span class="code">flex-shrink</span> in a single line, so we can set it to 1 0. It can also set <span class="code">flex-basis</span> which you may want to play around with but isn't really necessary here.</p>
  <p>Strangely, although we don't need to set <span class="code">flex-grow</span> on our other elements to 0, if we use this shorthand property to do it our CSS will end up shorter! Plus it provides a safety mechanism much like setting the <span class="code">nowrap</span> on our flex container.</p>
  <div class="codeblock">html {<br/>&nbsp;margin: 0;<br/>&nbsp;min-height: 100vh;<br/>}<br/>&nbsp;<br/>body {<br/>&nbsp;margin: 0;<br/>&nbsp;min-height: 100vh;<br/>&nbsp;display: flex;<br/>&nbsp;flex-flow: column nowrap;<br/>&nbsp;align-items: stretch;<br/>}<br/>&nbsp;<br/>footer {<br/>&nbsp;flex: 0 0;<br/>}<br/>&nbsp;<br/>header {<br/>&nbsp;flex: 0 0;<br/>}<br/>&nbsp;<br/>main {<br/>&nbsp;flex: 1 0;<br/>}<br/>&nbsp;<br/>nav {<br/>&nbsp;flex: 0 0;<br/>}
    </div>
  <p>The one (and so far only that I've found) drawback to this is that all of your content must be in a line for it to work, you cannot have an <span class="code">&lt;aside&gt;</span>, for example, or any other <span class="code">&lt;div&gt;</span>s, unless they are directly above or below something else, rather than to the side. This is where grid comes in.</p>
  </section>
  <section id="grid-footer">
  <h3>Grid</h3>
  <p>Just as the name of Flexbox suggests you can treat its children flexibly, the name of Grid allows you to lay that grid's children out in a grid fashion.</p>
  <p>This now allows us to add additional items to our layout, so rather than just our <span class="code">&lt;header&gt;</span>, <span class="code">&lt;nav&gt;</span>, <span class="code">&lt;main&gt;</span> and <span class="code">&lt;footer&gt;</span>, we can now have an <span class="code">&lt;aside&gt;</span>.</p>
  <p>To get started with our grid we need to set the display of the body to grid, and then define that grid.</p>
  <div class="codeblock">html {<br/>&nbsp;margin: 0;<br/>&nbsp;min-height: 100vh;<br/>}<br/>&nbsp;<br/>body {<br/>&nbsp;margin: 0;<br/>&nbsp;min-height: 100vh;<br/>&nbsp;display: grid;<br/>&nbsp;grid-template-columns: 2fr 1fr;<br/>&nbsp;grid-template-rows: auto auto 1fr auto auto;<br/>&nbsp;grid-template-areas:<br/>&nbsp;&nbsp;"header header"<br/>&nbsp;&nbsp;"nav nav"<br/>&nbsp;&nbsp;"main main"<br/>&nbsp;&nbsp;"aside aside"<br/>&nbsp;&nbsp;"footer footer";<br/>}</div>
  <p>So what exactly have we done here? Without going too in depth into grid (because grid is insanely powerful and doing that would take us well away from what we're focussing on here) we have defined 2 columns and 5 rows for a total of 10 cells. The columns have been defined as 2fr wide and 1fr wide, what this means is the left column is 2 portions wide of whatever space is left after any other columns that have rigidly-defined sizes (50px, 30% and so on) and 1fr means 1 portion wide. Essentially our left column in this case takes up 2 thirds and our right column takes up the remaning third.</p>
  <p>Looking at our rows, the browser will first look at the columns defined as auto (which means "look at my content and set my height appropriately") before portioning out the remaining space to the row set to 1fr - in theory as that's our only fr-defined row, we could have that as any positive number!</p>
  <p>Using <span class="code">grid-template-areas</span>, in conjunction with the <span class="code">grid-area</span> property on our child elements allows us to define where things will go on our page.</p>
  <div class="codeblock">html {<br/>&nbsp;margin: 0;<br/>&nbsp;min-height: 100vh;<br/>}<br/>&nbsp;<br/>body {<br/>&nbsp;margin: 0;<br/>&nbsp;min-height: 100vh;<br/>&nbsp;display: grid;<br/>&nbsp;grid-template-columns: 2fr 1fr;<br/>&nbsp;grid-template-rows: auto auto 1fr auto auto;<br/>&nbsp;grid-template-areas:<br/>&nbsp;&nbsp;"header header"<br/>&nbsp;&nbsp;"nav nav"<br/>&nbsp;&nbsp;"main main"<br/>&nbsp;&nbsp;"aside aside"<br/>&nbsp;&nbsp;"footer footer";<br/>}<br/>&nbsp;<br/>aside {<br/>&nbsp;grid-area: aside;<br/>}<br/>&nbsp;<br/>footer {<br/>&nbsp;grid-area: footer;<br/>}<br/>&nbsp;<br/>header {<br/>&nbsp;grid-area: header;<br/>}<br/>&nbsp;<br/>main {<br/>&nbsp;grid-area: main;<br/>}<br/>&nbsp;<br/>nav {<br/>&nbsp;grid-area: nav;<br/>}
  </div>
  <p>We have told our <span class="code">&lt;header&gt;</span> to fill up all areas where the grid displays header and so on, it is important to note that you cannot set items to be L-shaped or any other shape than a rectangle.</p>
  <p>The reason I haven't just defined one column is because we need our page/application to look good on different screen sizes, so lining all our elements up on top of one another means we can read everything on a small screen then use media queries to rearrange the items on larger screens.</p>
  <p>You can define these media queries however you like, but the way I have done it is to go mobile-first (which I always recommend you do as well) and rearrange things as you go up the screen sizes. Borrowing a breakpoint from <a href="https://getbootstrap.com/">Bootstrap</a> I have set the breakpoint to be at 768px wide. If our screen is narrower than that we keep our <span class="code">&lt;aside&gt;</span> underneath our <span class="code">&lt;main&gt;</span>, and once it hits 768px we move it to the side.</p>
  <div class="codeblock">@media (min-width: 768px) {<br/>&nbsp;body {<br/>&nbsp;&nbsp;grid-template-rows: auto auto 1fr auto;<br/>&nbsp;&nbsp;grid-template-areas:<br/>&nbsp;&nbsp;&nbsp;"header header"<br>&nbsp;&nbsp;&nbsp;"nav nav"<br/>&nbsp;&nbsp;&nbsp;"main aside"<br/>&nbsp;&nbsp;&nbsp;"footer footer";<br/>&nbsp;}<br/>}
  </div>
  <p>Notice how we now only have 4 rows, and that <span class="code">main</span> and <span class="code">aside</span> share a row? This is also why the columns earlier were 2fr and 1fr wide, to keep the main content bigger, although you could set this how you want, 3fr and 1fr, 3fr and 2fr, 10fr and 1fr, even 1fr and 1fr!</p>
  <p>When doing media queries, if one of them evaluates to true then the browser will overwrite <strong>only</strong> the rules that are part of that media query, so in our media query we can set only the <span class="code">grid-template-rows</span> and <span class="code">grid-template-areas</span> property, without having to set <span class="code">display: grid</span> or anything else, as it simply keeps the already-defined rule.</p>
  <p>By naming our grid areas and setting each element to take up the space defined by those areas, this also means we needn't do a single thing to our child elements in media queries, simply rearranging the grid layout will move them.</p>
  <p>And here we have it! A layout grid that adjusts to your screen size and always keeps the footer at the bottom of the page.</p>
  <div class="codeblock">html {<br/>&nbsp;margin: 0;<br/>&nbsp;min-height: 100vh;<br/>}<br/>&nbsp;<br/>body {<br/>&nbsp;margin: 0;<br/>&nbsp;min-height: 100vh;<br/>&nbsp;display: grid;<br/>&nbsp;grid-template-columns: 2fr 1fr;<br/>&nbsp;grid-template-rows: auto auto 1fr auto auto;<br/>&nbsp;grid-template-areas:<br/>&nbsp;&nbsp;"header header"<br/>&nbsp;&nbsp;"nav nav"<br/>&nbsp;&nbsp;"main main"<br/>&nbsp;&nbsp;"aside aside"<br/>&nbsp;&nbsp;"footer footer";<br/>}<br/>&nbsp;<br/>footer {<br/>&nbsp;grid-area: footer;<br/>}<br/>&nbsp;<br/>header {<br/>&nbsp;grid-area: header;<br/>}<br/>&nbsp;<br/>main {<br/>&nbsp;grid-area: main;<br/>}<br/>&nbsp;<br/>nav {<br/>&nbsp;grid-area: nav;<br/>}<br/>&nbsp;<br/>@media (min-width: 768px) {<br/>&nbsp;body {<br/>&nbsp;&nbsp;grid-template-rows: auto auto 1fr auto;<br/>&nbsp;&nbsp;grid-template-areas:<br/>&nbsp;&nbsp;&nbsp;"header header"<br>&nbsp;&nbsp;&nbsp;"nav nav"<br/>&nbsp;&nbsp;&nbsp;"main aside"<br/>&nbsp;&nbsp;&nbsp;"footer footer";<br/>&nbsp;}<br/>}
    </div>
  </section>
  <section id="tldr-footer">
  <h3>TL;DR</h3>
  <h4>Flexbox</h4>
  <div class="codeblock"><br/>html {<br/>&nbsp;margin: 0;<br/>&nbsp;min-height: 100vh;<br/>}<br/>&nbsp;<br/>body {<br/>&nbsp;margin: 0;<br/>&nbsp;min-height: 100vh;<br/>&nbsp;display: flex;<br/>&nbsp;flex-flow: column nowrap;<br/>&nbsp;align-items: stretch;<br/>}<br/>&nbsp;<br/>footer {<br/>&nbsp;flex: 0 0;<br/>}<br/>&nbsp;<br/>header {<br/>&nbsp;flex: 0 0;<br/>}<br/>&nbsp;<br/>main {<br/>&nbsp;flex: 1 0;<br/>}<br/>&nbsp;<br/>nav {<br/>&nbsp;flex: 0 0;<br/>}
    </div>
  <h4>Grid</h4>
  <div class="codeblock">html {<br/>&nbsp;margin: 0;<br/>&nbsp;min-height: 100vh;<br/>}<br/>&nbsp;<br/>body {<br/>&nbsp;margin: 0;<br/>&nbsp;min-height: 100vh;<br/>&nbsp;display: grid;<br/>&nbsp;grid-template-columns: 2fr 1fr;<br/>&nbsp;grid-template-rows: auto auto 1fr auto auto;<br/>&nbsp;grid-template-areas:<br/>&nbsp;&nbsp;"header header"<br/>&nbsp;&nbsp;"nav nav"<br/>&nbsp;&nbsp;"main main"<br/>&nbsp;&nbsp;"aside aside"<br/>&nbsp;&nbsp;"footer footer";<br/>}<br/>&nbsp;<br/>footer {<br/>&nbsp;grid-area: footer;<br/>}<br/>&nbsp;<br/>header {<br/>&nbsp;grid-area: header;<br/>}<br/>&nbsp;<br/>main {<br/>&nbsp;grid-area: main;<br/>}<br/>&nbsp;<br/>nav {<br/>&nbsp;grid-area: nav;<br/>}<br/>&nbsp;<br/>@media (min-width: 768px) {<br/>&nbsp;body {<br/>&nbsp;&nbsp;grid-template-rows: auto auto 1fr auto;<br/>&nbsp;&nbsp;grid-template-areas:<br/>&nbsp;&nbsp;&nbsp;"header header"<br>&nbsp;&nbsp;&nbsp;"nav nav"<br/>&nbsp;&nbsp;&nbsp;"main aside"<br/>&nbsp;&nbsp;&nbsp;"footer footer";<br/>&nbsp;}<br/>}
    </div>
  </section>
  <section id="navbar">
    <h2>And now the navbar</h2>
    <p>First of all we need to lay out our navbar's links inside a <span class="code">&lt;nav&gt;</span> tag:</p>
    <div class="codeblock">&lt;nav&gt;<br/>&nbsp;&lt;a class="active" href="#top"&gt;Home&lt;/a&gt;<br/>&nbsp;&lt;a href="#flex-footer"&gt;Flexbox Footer&lt;/a&gt;<br/>&nbsp;&lt;a href="#grid-footer"&gt;Grid Footer&lt;/a&gt;<br/>&nbsp;&lt;a href="#tldr-footer"&gt;Footer (TL;DR)&lt;/a&gt;<br/>&nbsp;&lt;a href="#navbar"&gt;Navbar&lt;/a&gt;<br/>&nbsp;&lt;div class="middle"&gt;&lt;/div&gt;<br/>&nbsp;&lt;a class="codepen" href="https://codepen.io/gavinsykesuk" target="_blank"&gt;&lt;i class="fab fa-codepen"&gt;&lt;/i&gt;&lt;span&gt; Codepen&lt;/span&gt;&lt;/a&gt;<br/>&nbsp;&lt;a class="github" href="https://github.com/gavinsykes" target="_blank">&lt;i class="fab fa-github"&gt;&lt;/i&gt;&lt;span&gt; Github&lt;/span&gt;&lt;/a&gt;<br/>&nbsp;&lt;a class="linkedin" href="https://www.linkedin.com/in/gavinsykes/" target="_blank"&gt;&lt;i class="fab fa-linkedin"&gt;&lt;/i&gt;&lt;span&gt; LinkedIn&lt;/span&gt;&lt;/a&gt;<br/>&nbsp;&lt;a class="stackoverflow" href="https://stackoverflow.com/users/8640133/gavin" target="_blank"&gt;&lt;i class="fab fa-stack-overflow"&gt;&lt;/i&gt;&lt;span&gt; Stack Overflow&lt;/span&gt;&lt;/a&gt;<br/>&nbsp;&lt;a class="twitter" href="https://www.twitter.com/gavinsykes_uk" target="_blank"&gt;&lt;i class="fab fa-twitter"&gt;&lt;/i&gt;&lt;span&gt; Twitter&lt;/span&gt;&lt;/a&gt;<br/>&nbsp;&lt;div id="nav-open" class="open-icon"&gt;≡&lt;/div&gt;<br/>
&lt;/nav&gt;</div>
    <p>As with our grid, we want to lay it out differently based on the width of the screen we are viewing it on, but also we now want to introduce a bit of JavaScript to prevent the navbar taking up too much space when not needed, and show us all our navigation options when needed. I have used the jQuery library to make our code more concise.</p>
    <div class="codeblock">
    $(() => {<br/>&nbsp;$('#nav-open').click(() => {<br/>&nbsp;&nbsp;$('nav').toggleClass('open');<br/>&nbsp;});<br/>});
  </div>
    <p>If you prefer to use raw JavaScript then you can, but all I'll say is there is a reason I've used jQuery!:</p>
    <div class="codeblock"> document.addEventListener('DOMContentLoaded',() => {<br/>
&nbsp;document.querySelector('#nav-open').onclick = e => {<br/>&nbsp;&nbsp;document.querySelector('nav').classList.toggle('open');<br/>&nbsp;}<br/>});
  </div>
    <p>It looks complicated, but basically what this code does is add a function to an item called nav-open (which we'll come to later), so that when the user clicks it it either adds or removes the open class as necessary to (or from) the navbar.</p>
    <p>We will use flexbox for our navbar, as it is linear i.e. everything will be in a line rather than some bits being to the side of each other.</p>
    <div class="codeblock">nav {<br/>&nbsp;grid-area: nav;<br/>&nbsp;display: flex;<br/>&nbsp;flex-flow: column nowrap;<br/>&nbsp;align-items: stretch;<br/>&nbsp;position: sticky;<br/>&nbsp;top: 0;<br/>}</div>
    <p>The <span class="code">position: sticky</span> and <span class="code">top: 0</span> properties tell the navbar that when we scroll away from it on the page, it is to stick to the top of our screen.</p>
    <p>I have added far more rules to do with colours in this piece, but for just showing the layout I will strip it back.</p>
    <p>As we are mobile-first, we want to set everything inside our navbar to not display, then only pick the items we do want to show.</p>
    <div class="codeblock">nav {<br/>&nbsp;grid-area: nav;<br/>&nbsp;display: flex;<br/>&nbsp;flex-flow: column nowrap;<br/>&nbsp;align-items: stretch;<br/>&nbsp;position: sticky;<br/>&nbsp;top: 0;<br/>}<br/>&nbsp;<br/>nav * {<br/>&nbsp;display: none;<br/>&nbsp;text-align: center;<br/>}<br/>&nbsp;<br/>nav a.active {<br/>&nbsp;display: block;<br/>}<br/>&nbsp;<br/>nav div.open-icon {<br/>&nbsp;display: block;<br/>&nbsp;font-weight: bold;<br/>}</div>
    <p>Depending what you have as your open icon you may not need to set <span class="code">font-weight: bold</span>, but in this case I have. What we have done here is set everything within our navbar to not display, and then overridden that in our active link and the opening icon.</p>
    <p>Next we need to worry about what our navbar looks like when it is open, meaning that we want to show everything when it has the open class, and hide it when we click the icon again.</p>
    <div class="codeblock">nav {<br/>&nbsp;grid-area: nav;<br/>&nbsp;display: flex;<br/>&nbsp;flex-flow: column nowrap;<br/>&nbsp;align-items: stretch;<br/>&nbsp;position: sticky;<br/>&nbsp;top: 0;<br/>}<br/>&nbsp;<br/>nav * {<br/>&nbsp;display: none;<br/>&nbsp;text-align: center;<br/>}<br/>&nbsp;<br/>nav a.active {<br/>&nbsp;display: block;<br/>}<br/>&nbsp;<br/>nav div.open-icon {<br/>&nbsp;display: block;<br/>&nbsp;font-weight: bold;<br/>}<br/>&nbsp;<br/>nav.open a {<br/>&nbsp;display: block;<br/>}</div>
    <p>Now we need to turn to what our navbar looks like on bigger screens, one thing we can do straightaway is set our middle div to <span class="code">flex-grow: 1</span> to make it push everything to its left all the way to the left, and everything to its right all the way to the right, but as we're doing it outside the media query we need to also set it to <span class="code">display: none</span> so that it doesn't appear on mobile and take up the whole screen!</p>
    <div class="codeblock">nav {<br/>&nbsp;grid-area: nav;<br/>&nbsp;display: flex;<br/>&nbsp;flex-flow: column nowrap;<br/>&nbsp;align-items: stretch;<br/>&nbsp;position: sticky;<br/>&nbsp;top: 0;<br/>}<br/>&nbsp;<br/>nav * {<br/>&nbsp;display: none;<br/>&nbsp;text-align: center;<br/>}<br/>&nbsp;<br/>nav a.active {<br/>&nbsp;display: block;<br/>}<br/>&nbsp;<br/>nav div.open-icon {<br/>&nbsp;display: block;<br/>&nbsp;font-weight: bold;<br/>}<br/>&nbsp;<br/>nav.open a {<br/>&nbsp;display: block;<br/>}<br/>&nbsp;<br/>nav div.middle {<br/>&nbsp;flex-grow: 1;<br/>&nbsp;display: none;<br/>}<br/>&nbsp;<br/>@media (min-width: 768px) {<br/>&nbsp;nav {<br/>&nbsp;&nbsp;flex-flow: row nowrap;<br/>&nbsp;}<br/>&nbsp;nav a:not(.active),<br/>&nbsp;nav div.middle {<br/>&nbsp;&nbsp;display: block;<br/>&nbsp;}<br/>&nbsp;nav div.open-icon {<br/>&nbsp;&nbsp;display: none;<br/>&nbsp;}<br/>}</div>
    <p>So what have we done in our media query? Firstly we have set our navbar to display as a row rather than as a column, set all the links within the navbar to display given that we now don't need to save any space, and set our middle <span class="code">div</span> to display (although it's empty) to push everything else to the relevant edges as above. Finally as we no longer need our opening button, set it to <span class="code">display: none</span>.</p>
  </section>
</main>
<aside>
  <p>This is what I originally put in the main bit to test the footer positioning, give it a go!</p>
  <p>Because I'm a language nerd I've put a button below to add the explanation of Lorem Ipsum below in different alphabets, courtesy of <a href="https://www.lipsum.com/">Lipsum.com</a>:</p>
  <button id="add">Add Item</button>
  <ul id="demo">
  </ul>
</aside>
<footer>
  Gavin Sykes - 2019
</footer>
              
            
!

CSS

              
                html {
  margin: 0;
  font-family: sans-serif;
  padding: 0;
}
aside {
  padding: 1rem;
  grid-area: aside;
  background-color: black;
  color: white;
}
body {
  margin: 0;
  padding: 0;
  min-height: 100vh;
  display: grid;
  grid-template-columns: 2fr 1fr;
  grid-template-rows: auto auto 1fr auto auto;
  grid-template-areas:
    "header header"
    "nav nav"
    "main main"
    "aside aside"
    "footer footer";
}
footer {
  padding: 1rem;
  grid-area: footer;
  background-color: #ddd;
}
header {
  padding: 1rem;
  grid-area: header;
}
main {
  padding: 1rem;
  grid-area: main;
}
nav {
  grid-area: nav;
  display: flex;
  flex-flow: column nowrap;
  align-items: stretch;
  position: sticky;
  top: 0;
  background-color: #ddd;
  max-height: 100vh;
}
nav * {
  margin: 0;
  padding: 0.3rem;
  text-align: center;
  text-decoration: none;
}
nav a {
  display: flex;
  align-items: center;
  transition: 250ms ease-in-out;
  transition-property: color, background-color;
}
nav a:not(.active),
nav a:not(.open-icon) {display: none;}
nav span {display: inline;}
nav.open a {display: block;}
nav a.active {display: block}
nav div.middle {
  display: none;
  flex-grow: 1;
}
nav div.open-icon {display: block; font-weight: bold;}
nav a:hover {
  text-decoration: underline;
}

.code {font-family: monospace;}
.codeblock {
  padding: 1rem;
  background-color: #eee;
  font-family: monospace;
}

.showcase {
  display: flex;
  flex-flow: column nowrap;
  justify-content: flex-start;
  align-items: center;
  max-width: 100%;
}
.showcase * {
  max-width: 100%;
}

.codepen,
.codepen:link,
.codepen:visited,
.codepen:active {color: black;}
.codepen:hover,
.codepen:focus {
    color: white;
    background-color: black;
}
.github,
.github:link,
.github:visited,
.github:active {color: #161312;}
.github:hover,
.github:focus {
    background-color: #161312;
    color: white;
}
.linkedin,
.linkedin:link,
.linkedin:visited,
.linkedin:active {color: #0077B5;}
.linkedin:hover,
.linkedin:focus {
    background-color: #0077B5;
    color: white;
}
.stackoverflow,
.stackoverflow:link,
.stackoverflow:visited,
.stackoverflow:active {color: #f48024;}
.stackoverflow:hover,
.stackoverflow:focus {
    background-color: #bbb;
    color: #f48024;
}
.twitter,
.twitter:link,
.twitter:visited,
.twitter:active {color: #1da1f3;}
.twitter:hover,
.twitter:focus {
    background-color: #1da1f3;
    color: white;
}
/* Based on Bootstrap, extra-small to small */
@media (min-width: 576px) {
  
}
/* Based on Bootstrap, small to medium */
@media (min-width: 768px) {
  body {
    grid-template-rows: auto auto 1fr auto;
    grid-template-areas:
      "header header"
      "nav nav"
      "main aside"
      "footer footer";
  }
  nav { flex-flow: row nowrap; }
  nav * {padding: 0.5rem;}
  nav a:not(.active),
  nav div.middle {display: block;}
  nav div.open-icon,
  nav span {display: none;}
}
/* Based on Bootstrap, medium to large */
@media (min-width: 992px) {
  
}
/* Based on Bootstrap, large to extra-large */
@media (min-width: 1200px) {
  
}
              
            
!

JS

              
                $(() => {
  $('#nav-open').click(() => {
    $('nav').toggleClass('open');
  });
  $('#add').click(() => {
    $('#demo').append(appendRand());
  });
  const appendRand = () => $('<li>' + items[Math.floor(Math.random()*items.length)] + '</li>');
  const items = [
    '🇦🇲: Lorem Ipsum-ը տպագրության և տպագրական արդյունաբերության համար նախատեսված մոդելային տեքստ է: Սկսած 1500-ականներից` Lorem Ipsum-ը հանդիսացել է տպագրական արդյունաբերության ստանդարտ մոդելային տեքստ, ինչը մի անհայտ տպագրիչի կողմից տարբեր տառատեսակների օրինակների գիրք ստեղծելու ջանքերի արդյունք է: Այս տեքստը ոչ միայն կարողացել է գոյատևել հինգ դարաշրջան, այլև ներառվել է էլեկտրոնային տպագրության մեջ` մնալով էապես անփոփոխ: Այն հայտնի է դարձել 1960-ականներին Lorem Ipsum բովանդակող Letraset էջերի թողարկման արդյունքում, իսկ ավելի ուշ համակարգչային տպագրության այնպիսի ծրագրերի թողարկման հետևանքով, ինչպիսին է Aldus PageMaker-ը, որը ներառում է Lorem Ipsum-ի տարատեսակներ:',
    '🇸🇦:هناك حقيقة مثبتة منذ زمن طويل وهي أن المحتوى المقروء لصفحة ما سيلهي القارئ عن التركيز على الشكل الخارجي للنص أو شكل توضع الفقرات في الصفحة التي يقرأها. ولذلك يتم استخدام طريقة لوريم إيبسوم لأنها تعطي توزيعاَ طبيعياَ -إلى حد ما- للأحرف عوضاً عن استخدام "هنا يوجد محتوى نصي، هنا يوجد محتوى نصي" فتجعلها تبدو (أي الأحرف) وكأنها نص مقروء. العديد من برامح النشر المكتبي وبرامح تحرير صفحات الويب تستخدم لوريم إيبسوم بشكل إفتراضي كنموذج عن النص، وإذا قمت بإدخال "lorem ipsum" في أي محرك بحث ستظهر العديد من المواقع الحديثة العهد في نتائج البحث. على مدى السنين ظهرت نسخ جديدة ومختلفة من نص لوريم إيبسوم، أحياناً عن طريق الصدفة، وأحياناً عن عمد كإدخال بعض العبارات الفكاهية إليها. ',
    '🇧🇬 : Lorem Ipsum е елементарен примерен текст, използван в печатарската и типографската индустрия. Lorem Ipsum е индустриален стандарт от около 1500 година, когато неизвестен печатар взема няколко печатарски букви и ги разбърква, за да напечата с тях книга с примерни шрифтове. Този начин не само е оцелял повече от 5 века, но е навлязъл и в публикуването на електронни издания като е запазен почти без промяна. Популяризиран е през 60те години на 20ти век със издаването на Letraset листи, съдържащи Lorem Ipsum пасажи, популярен е и в наши дни във софтуер за печатни издания като Aldus PageMaker, който включва различни версии на Lorem Ipsum.',
    '🇨🇳: Lorem Ipsum,也称乱数假文或者哑元文本, 是印刷及排版领域所常用的虚拟文字。由于曾经一台匿名的打印机刻意打乱了一盒印刷字体从而造出一本字体样品书,Lorem Ipsum从西元15世纪起就被作为此领域的标准文本使用。它不仅延续了五个世纪,还通过了电子排版的挑战,其雏形却依然保存至今。在1960年代,”Leatraset”公司发布了印刷着Lorem Ipsum段落的纸张,从而广泛普及了它的使用。最近,计算机桌面出版软件”Aldus PageMaker”也通过同样的方式使Lorem Ipsum落入大众的视野。',
    '🇬🇪: Lorem Ipsum საბეჭდი და ტიპოგრაფიული ინდუსტრიის უშინაარსო ტექსტია. იგი სტანდარტად 1500-იანი წლებიდან იქცა, როდესაც უცნობმა მბეჭდავმა ამწყობ დაზგაზე წიგნის საცდელი ეგზემპლარი დაბეჭდა. მისი ტექსტი არამარტო 5 საუკუნის მანძილზე შემორჩა, არამედ მან დღემდე, ელექტრონული ტიპოგრაფიის დრომდეც უცვლელად მოაღწია. განსაკუთრებული პოპულარობა მას 1960-იან წლებში გამოსულმა Letraset-ის ცნობილმა ტრაფარეტებმა მოუტანა, უფრო მოგვიანებით კი — Aldus PageMaker-ის ტიპის საგამომცემლო პროგრამებმა, რომლებშიც Lorem Ipsum-ის სხვადასხვა ვერსიები იყო ჩაშენებული.',
    "🇬🇷: Το Lorem Ipsum είναι απλά ένα κείμενο χωρίς νόημα για τους επαγγελματίες της τυπογραφίας και στοιχειοθεσίας. Το Lorem Ipsum είναι το επαγγελματικό πρότυπο όσον αφορά το κείμενο χωρίς νόημα, από τον 15ο αιώνα, όταν ένας ανώνυμος τυπογράφος πήρε ένα δοκίμιο και ανακάτεψε τις λέξεις για να δημιουργήσει ένα δείγμα βιβλίου. Όχι μόνο επιβίωσε πέντε αιώνες, αλλά κυριάρχησε στην ηλεκτρονική στοιχειοθεσία, παραμένοντας με κάθε τρόπο αναλλοίωτο. Έγινε δημοφιλές τη δεκαετία του '60 με την έκδοση των δειγμάτων της Letraset όπου περιελάμβαναν αποσπάσματα του Lorem Ipsum, και πιο πρόσφατα με το λογισμικό ηλεκτρονικής σελιδοποίησης όπως το Aldus PageMaker που περιείχαν εκδοχές του Lorem Ipsum",
    '🇮🇳: Lorem Ipsum छपाई और अक्षर योजन उद्योग का एक साधारण डमी पाठ है. Lorem Ipsum सन १५०० के बाद से अभी तक इस उद्योग का मानक डमी पाठ मन गया, जब एक अज्ञात मुद्रक ने नमूना लेकर एक नमूना किताब बनाई. यह न केवल पाँच सदियों से जीवित रहा बल्कि इसने इलेक्ट्रॉनिक मीडिया में छलांग लगाने के बाद भी मूलतः अपरिवर्तित रहा. यह 1960 के दशक में Letraset Lorem Ipsum अंश युक्त पत्र के रिलीज के साथ लोकप्रिय हुआ, और हाल ही में Aldus PageMaker Lorem Ipsum के संस्करणों सहित तरह डेस्कटॉप प्रकाशन सॉफ्टवेयर के साथ अधिक प्रचलित हुआ.',
"🇮🇱: זוהי עובדה מבוססת שדעתו של הקוראהיה מוסחת על ידי טקטס קריא כאשר הוא יביט בפריסתו. המטרה בשימוש ב-Lorem Ipsum הוא שיש לו פחות או יותר תפוצה של אותיות, בניגוד למלל יסוי', ונותן חזות קריאה יותר.הרבה הוצאות מחשבים ועורכי דפי אינטרנט משתמשים כיום ב-Lorem Ipsum כטקסט ברירת המחדל שלהם, וחיפוש של 'lorem ipsum' יחשוף אתרים רבים בראשית דרכם.גרסאות רבות נוצרו במהלך השנים, לעתים בשגגה לעיתים במכוון (זריקת בדיחות וכדומה).",
    '🇲🇰: Lorem Ipsum е едноставен модел на текст кој се користел во печатарската индустрија. Lorem ipsum бил индустриски стандард кој се користел како модел уште пред 1500 години, кога непознат печатар зел кутија со букви и ги сложил на таков начин за да направи примерок на книга. И не само што овој модел опстанал пет векови туку почнал да се користи и во електронските медиуми, кој се уште не е променет. Се популаризирал во 60-тите години на дваесеттиот век со издавањето на збирка од страни во кои се наоѓале Lorem Ipsum пасуси, а денес во софтверскиот пакет како што е Aldus PageMaker во кој се наоѓа верзија на Lorem Ipsum.',
    '🇷🇺: Lorem Ipsum - это текст-"рыба", часто используемый в печати и вэб-дизайне. Lorem Ipsum является стандартной "рыбой" для текстов на латинице с начала XVI века. В то время некий безымянный печатник создал большую коллекцию размеров и форм шрифтов, используя Lorem Ipsum для распечатки образцов. Lorem Ipsum не только успешно пережил без заметных изменений пять веков, но и перешагнул в электронный дизайн. Его популяризации в новое время послужили публикация листов Letraset с образцами Lorem Ipsum в 60-х годах и, в более недавнее время, программы электронной вёрстки типа Aldus PageMaker, в шаблонах которых используется Lorem Ipsum.',
    '🇷🇸: Lorem Ipsum је једноставно модел текста који се користи у штампарској и словослагачкој индустрији. Lorem ipsum је био стандард за модел текста још од 1500. године, када је непознати штампар узео кутију са словима и сложио их како би направио узорак књиге. Не само што је овај модел опстао пет векова, него је чак почео да се користи и у електронским медијима, непроменивши се. Популаризован је шездесетих година двадесетог века заједно са листовима летерсета који су садржали Lorem Ipsum пасусе, а данас са софтверским пакетом за прелом као што је Aldus PageMaker који је садржао Lorem Ipsum верзије.',
    '🇹🇭: Lorem Ipsum คือ เนื้อหาจำลองแบบเรียบๆ ที่ใช้กันในธุรกิจงานพิมพ์หรืองานเรียงพิมพ์ มันได้กลายมาเป็นเนื้อหาจำลองมาตรฐานของธุรกิจดังกล่าวมาตั้งแต่ศตวรรษที่ 16 เมื่อเครื่องพิมพ์โนเนมเครื่องหนึ่งนำรางตัวพิมพ์มาสลับสับตำแหน่งตัวอักษรเพื่อทำหนังสือตัวอย่าง Lorem Ipsum อยู่ยงคงกระพันมาไม่ใช่แค่เพียงห้าศตวรรษ แต่อยู่มาจนถึงยุคที่พลิกโฉมเข้าสู่งานเรียงพิมพ์ด้วยวิธีทางอิเล็กทรอนิกส์ และยังคงสภาพเดิมไว้อย่างไม่มีการเปลี่ยนแปลง มันได้รับความนิยมมากขึ้นในยุค ค.ศ. 1960 เมื่อแผ่น Letraset วางจำหน่ายโดยมีข้อความบนนั้นเป็น Lorem Ipsum และล่าสุดกว่านั้น คือเมื่อซอฟท์แวร์การทำสื่อสิ่งพิมพ์ (Desktop Publishing) อย่าง Aldus PageMaker ได้รวมเอา Lorem Ipsum เวอร์ชั่นต่างๆ เข้าไว้ในซอฟท์แวร์ด้วย',
    '🇺🇦: Lorem Ipsum - це текст-"риба", що використовується в друкарстві та дизайні. Lorem Ipsum є, фактично, стандартною "рибою" аж з XVI сторіччя, коли невідомий друкар взяв шрифтову гранку та склав на ній підбірку зразків шрифтів. "Риба" не тільки успішно пережила п\'ять століть, але й прижилася в електронному верстуванні, залишаючись по суті незмінною. Вона популяризувалась в 60-их роках минулого сторіччя завдяки виданню зразків шрифтів Letraset, які містили уривки з Lorem Ipsum, і вдруге - нещодавно завдяки програмам комп\'ютерного верстування на кшталт Aldus Pagemaker, які використовували різні версії Lorem Ipsum.'
  ];
});
              
            
!
999px

Console