Wonderland
  • README.md
  • Notebook
    • Crypto
      • Solana
        • Troubleshooting
          • BPF SDK path does not exist
    • Language
      • Rust
        • Reference
          • Capturing the Environment with Closures
          • Understanding &mut &mut Reference
      • C++
        • Reference
          • Code for MS rand() and srand() in VC++ 6.0
  • Textbook
    • Serials
      • A Real-Time Cryptocurrency Ticker Dashboard
        • 0 - Some Preparation
    • Frontend
      • A Simple Progress Bar
      • A React Ribbon Component
      • An Easy to Use React DnD Sortable Component
      • Sticky Header, Sticky Footer and Fluid Content
      • How To Set Same Height As Width In CSS
  • dictionary
    • Alphabet
      • MySQL
      • FFmpeg
    • Algorithm
      • Diary
        • 2022
          • 07
            • 2022-07-02
            • 2022-07-01
          • 06
            • 2022-06-30
            • 2022-06-29
            • 2022-06-28
            • 2022-06-27
            • 2022-06-26
            • 2022-06-25
            • 2022-06-24
            • 2022-06-23
            • 2022-06-22
            • 2022-06-21
            • 2022-06-20
            • 2022-06-19
            • 2022-06-18
            • 2022-06-17
            • 2022-06-16
            • 2022-06-15
            • 2022-06-14
            • 2022-06-13
            • 2022-06-12
            • 2022-06-11
            • 2022-06-10
            • 2022-06-09
            • 2022-06-08
            • 2022-06-07
            • 2022-06-06
            • 2022-06-05
            • 2022-06-04
            • 2022-06-03
            • 2022-06-02
            • 2022-06-01
          • 05
            • 2022-05-31
            • 2022-05-30
            • 2022-05-29
            • 2022-05-28
            • 2022-05-27
            • 2022-05-26
            • 2022-05-25
            • 2022-05-24
            • 2022-05-23
            • 2022-05-22
            • 2022-05-21
            • 2022-05-20
            • 2022-05-19
            • 2022-05-18
            • 2022-05-17
            • 2022-05-16
            • 2022-05-15
    • Troubleshooting
      • A Weird Python Command Not Found Problem
Powered by GitBook
On this page
  • What do I want to create?
  • How to create?
  • Rough and Rugged Paths
  • A Magic __next Class
  • Why flex both in body and div#__next?
  • Reference
  1. Textbook
  2. Frontend

Sticky Header, Sticky Footer and Fluid Content

This title came from an ancient question on stack overflow, which is asked over 8 years ago...

Last updated 3 years ago

What do I want to create?

As is mentioned in the description, this post comes from "".

My target is really simple, the contains are as followed:

  • A sticky(maybe it is fixed) header is always at the top.

  • A sticky(it can also be fixed) footer is always at the bottom.

  • No matter header or footer, it must not overlap with the content.

So... Technically, I want it to be like the following images, they are large, so it may take a while to load:

Page with a long enough content

It seems easy, but I met several problems during coding.

How to create?

First of all, just let me show you the core code of the solution. I create these all in React using Next.js.

Here is the code in the index.tsx:

import styles from "./index.module.css";

export default function Index() {
  return (
    <div className={styles.container}>
      <header className={styles.header}>This is a header.</header>
      <div className={styles.content}>
        These are very long contents.
        <br />
      </div>
      <footer className={styles.footer}>This is a footer.</footer>
    </div>
  );
}

and now index.modul.css:

.container {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
}

.header {
  position: sticky;
  top: 0;
  width: 100%;
  background-color: red;
}

.footer {
  position: sticky;
  bottom: 0;
  width: 100%;
  background-color: blue;
}

.content {
  flex: 1;
  width: 100%;
  font-size: 48px;
}

And you also need to modify your html and body, which are in globals.css:

html,
body {
  font-family: "PingFang SC", "Hiragino Sans GB", "Heiti SC", "Microsoft YaHei",
    "WenQuanYi Micro Hei";
  min-width: 100vw;
  background-color: yellow;
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html {
  height: 100%;
}

body {
  min-height: 100%;
  display: flex;
  flex-direction: column;
}

/* We will talk about this in the next section. */
body > div:first-child,
div#__next,
div#__next > div {
  flex: 1;
  display: flex;
  flex-direction: column;
}

In this way, you can create a page just like the images above.

This sandbox is a minimal example for your reference:

If you don't want to listen to my rough and rugged paths, you don't have to read the following parts.

Rough and Rugged Paths

A Magic __next Class

This problem may only exit in Next.js.

After I changed the height of html and body, I found my custom container did not inhreit from them.

I looked into the elements, and I found these was a div with id __next between body and my custom elements. It looks like:

<html>
  <!-- snip -->
  <body data-new-gr-c-s-check-loaded="14.1057.0" data-gr-ext-installed="">
    <div id="__next">
<!-- snip -->    

The div with id __next does't have any styles, so if we want to make its child element has a height inhreited, we should also give it some styles just like the part in the globals.css with a comment:

body > div:first-child,
div#__next,
div#__next > div {
  flex: 1;
  display: flex;
  flex-direction: column;
}

Why flex both in body and div#__next?

flex helps us a lot, but it can only work when the container is big enough.

main size

main size property

Let's go back to my code, which I set height: 100% for html to make the global container has an initial height. A min-height: 100% for body, and this can help long content to grow more than the height set using the same background.

We have talked about the div#__next between body and custom elements earlier, because of the box model, if we want our custom elements to be flexible, their parents should be flexible first. So flex attributes in the body can make div#__next with flex: 1; grow to the height of the page, which is set in html and body.

Now, we just need to repeat these steps, make div#__next also flexible, and make the content grow as the main size.

These are because we have a container between body and custom elements happened in the Next.js, maybe you only need one flexible parent in your own code.

Reference

Page with content which can not fullfill all the empty place

This solution is reminded by "". Maybe I should review the basic knowledge of HTML and CSS, since this is a simple problem but bothered me for a long time.

In my code, the key to success is flex: 1; is a shorthand for flex-grow: 1;. The flex-grow CSS property sets the flex grow factor of a flex item's .

The width or height of a or , whichever is in the , is that box’s main size. Its main size property is thus either its or property, whichever is in the . Similarly, its min and max main size properties are its / or / properties, whichever is in the , and determine its min/max main size.

How to make a page full height in Next.js
main size
flex container
flex item
main dimension
width
height
main dimension
min-width
max-width
min-height
max-height
main dimension
Sticky header, sticky footer (variable height), fluid middle?
How to make a page full height in Next.js
flex
Sticky header, sticky footer (variable height), fluid middle?