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
This title came from an ancient question on stack overflow, which is asked over 8 years ago...
Last updated
As is mentioned in the description, this post comes from "Sticky header, sticky footer (variable height), fluid middle?".
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:
It seems easy, but I met several problems during coding.
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
:
and now index.modul.css
:
And you also need to modify your html
and body
, which are in globals.css
:
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.
__next
ClassThis 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:
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:
This solution is reminded by "How to make a page full height in Next.js". Maybe I should review the basic knowledge of HTML and CSS, since this is a simple problem but bothered me for a long time.
flex
both in body
and div#__next
?flex
helps us a lot, but it can only work when the container is big enough.
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 main size.
main size
main size property
The width or height of a flex container or flex item, whichever is in the main dimension, is that box’s main size. Its main size property is thus either its width or height property, whichever is in the main dimension. Similarly, its min and max main size properties are its min-width/max-width or min-height/max-height properties, whichever is in the main dimension, and determine its min/max main size.
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.