Footer Position Fixed overlapping page content - html

I am having issues trying to make my footer at the bottom, but it overlaps the content on the page if there are too much content.
this is my footer css
footer {
position:fixed;
bottom: 0;
}
this is how the page looks without any content
this is how the page looks with overlap content with the footer

You could structure your HTML as follows:
<body>
<header class="Header"></header>
<main class="Main"></main>
<footer class="Footer"></footer>
</body>
Then, use flex box to render the footer at the bottom of your page using the following code:
body {
display: flex;
flex-direction: column;
min-height: 100vh;
}
main {
flex: 1;
}
footer,
header {
flex: 0;
}
See a fully working demo code below and learn more about flex box here:
header::after,
main::after,
footer::after {
content: attr(class);
}
body {
display: flex;
flex-direction: column;
min-height: 100vh;
margin: 0;
}
main {
flex: 1;
}
footer,
header {
flex: 0;
}
<header class="Header"></header>
<main class="Main"></main>
<footer class="Footer"></footer>

Related

Footer stuck in middle only when there is little content

I know the title is a known 'issue'. However, I have tried many solutions, but none seem to work.
My footer is stuck on the bottom (phew) on almost all cases (when there is a lot of content, when I can scroll,..). Sadly, when there is barely any content, it just goes straight to the middle. I really have no clue why this is happening :( I am using Gatsbyjs for my website.
This is the global.css
html {
height: 100%;
}
main {
flex: 1 0 auto;
}
body {
display: flex;
flex-direction: column;
position: relative;
height: 100%;
margin: 0;
font-family: "Roboto", sans-serif;
color: whitesmoke;
background: radial-gradient(circle at center, #2b2b2b, #414141);
}
My footer.js component and it's css is:
css:
footer {
background-color: #2b2b2b;
position: relative;
font-size: smaller;
opacity: 0.98;
padding: 1rem;
width: 100%;
margin-top: auto;
}
html for footer:
const Footer = () => {
return (
<div>
<footer>
<p>©Copyright {currentYear} Humital - Made with ❤️</p>
</footer>
</div>
)
}
export default Footer
the main html comes from layout.js:
<div className={styles.flex}>
<NavBar />
<div className={styles.container}>
<main>{children}</main>
</div>
<Footer />
</div>
Which holds some css for the container:
.container {
display: flex;
flex-direction: column;
padding-top: 5rem;
padding-bottom: 1rem;
margin-left: 1rem;
line-height: 1rem;
flex: 1 0 auto;
position: relative;
}
.flex {
flex: 1;
}
Not sure why the footer won't go down when there is no content :( Any help is welcome! :)
I think you just need to add min-height: 100vh rule (and a flex-direction) to your .flex class:
.flex {
flex: 1;
min-height: 100vh;
flex-direction: column;
}
Because your .container has the flex: 1 0 auto will push the footer to the bottom.
Summarizing, you only need this rules to stick your footer to the bottom:
.flex {
display: flex;
flex-direction: column;
min-height: 100vh;
}
.container {
flex: 1 0 auto;
}
.flex applies to the outer wrapper, which contains the Footer, the <main> and the <NavBar />.
.container applies to the <main> or the <main>'s wrapper. I think it's not needed to wrap the <main> with another <div>, you can apply the styles directly to the <main> tag, yet the approach to push the footer to the bottom is exactly the same.

html body scrollbar position

I am working on a page with a menu bar.
the height of the menu bar is 40px
and I set the top of the body tag to 40px too.
However, the scrollbar of the body tag is still at top=0px.
To do this approach you can use flex display. you should wrap your main content in another section and scroll the wrapper inside itself.
here an example :
<body>
<nav class="nav">
<!-- *********** your nav items ******************* -->
</nav>
<main class="content">
<!-- your content should be placed here ****************-->
</main>
</body>
and the CSS code :
body {
display: flex;
height: 100vh;
width: 100vw;
flex-direction: column;
overflow: hidden;
}
.nav {
height: 40px;
background: red;
}
.content {
flex: 1;
overflow-y: auto;
overflow-x: hidden;
background: blue;
}

Converting JSON object to HTML template

I am using Angular 6 and my templates are as below.
Header, Left panel, Body part, footer
Header,Left panel, Body part, right panel, footer
Header, body part, footer
Since, I have so many templates, I wanted to make it JSON driven instead of just hardcoding html part.
The JSON file will look like,
{
   "horizontal" : [
     {
      width : 20%,
      height: 100%
     },
{
      width : 80%,
      height: 100%,
{
       "vertical" : [
         {
           width : 80%,
           height: 60%
         },
         {
           width : 80%,
           height: 40%
         }
       ]
      }
     }
   ],
}
Here, the page gets divided into left panel(20% width) and body(80%) and then body gets divided into vertically like 60% top and 20% bottom.
Is there any way to make this JSON into HTML?
While this question is too broad, I were/am a back end guy too, and wen't through many ideas before landing, so I decided to post an answer and share my experience.
My intention with this is to show how simple, and with how little code, one can create something reusable and easy to maintain.
Instead of convert styles from a JSON to HTML, use what is meant for that, CSS, and here is a few samples how to manage many templates with a small style guide, and get one of the best features of all, performance.
With one CSS, making using Flexbox, and the given logic for your different templates, it could look like this.
Sample 1 (with CSS notes)
html, body, .container {
height: 100%;
margin: 0;
}
.container, main {
display: flex; /* make children flex items */
flex-direction: column; /* default flow is row */
}
header, footer { /* flex column item will by default fill parent's width */
/* height is controlled by content */
}
.wrapper {
flex: 1; /* fill remaining height (flex column item) */
display: flex;
}
aside { /* flex row item will by default fill parent's height */
flex-basis: 20%; /* set width (flex column item) */
}
main {
flex: 1; /* fill remaining width (flex row item) */
}
section {
flex-basis: 60%; /* set height (flex column item) */
}
section + section { /* target the 2nd section */
flex-basis: 40%;
}
/* for demo purpose */
header, footer, aside, section {
border: 1px dotted gray;
}
<div class="container">
<header>Header</header>
<div class="wrapper">
<aside>Aside</aside>
<main>
<section>Section</section>
<section>Section</section>
</main>
</div>
<footer>Footer</footer>
</div>
Sample 2
html, body, .container {
height: 100%;
margin: 0;
}
.container, main {
display: flex;
flex-direction: column;
}
header, footer {
}
.wrapper {
flex: 1;
display: flex;
}
aside {
flex-basis: 20%;
}
main {
flex: 1;
}
section {
flex-basis: 60%;
}
section + section {
flex-basis: 40%;
}
header, footer, aside, section {
border: 1px dotted gray;
}
<div class="container">
<header>Header</header>
<div class="wrapper">
<aside>Aside</aside>
<main>
<section>Section</section>
<section>Section</section>
</main>
<aside>Aside</aside>
</div>
<footer>Footer</footer>
</div>
Sample 3
html, body, .container {
height: 100%;
margin: 0;
}
.container, main {
display: flex;
flex-direction: column;
}
header, footer {
}
.wrapper {
flex: 1;
display: flex;
}
aside {
flex-basis: 20%;
}
main {
flex: 1;
}
section {
flex-basis: 60%;
}
section + section {
flex-basis: 40%;
}
header, footer, aside, section {
border: 1px dotted gray;
}
<div class="container">
<header>Header</header>
<main>
<section>Section</section>
<section>Section</section>
</main>
<footer>Footer</footer>
</div>
Or for a given template, using different CSS (only show 1 and 3 here, as 2 will be the same as the above)
Sample 1
html, body, .container {
height: 100%;
margin: 0;
}
.container, main {
display: flex;
flex-direction: column;
}
header, footer {
}
.wrapper {
flex: 1;
display: flex;
}
aside {
flex-basis: 20%;
}
main + aside { /* target the 2nd/right aside */
display: none;
}
main {
flex: 1;
}
section {
flex-basis: 60%;
}
section + section {
flex-basis: 40%;
}
/* for demo purpose */
header, footer, aside, section {
border: 1px dotted gray;
}
<div class="container">
<header>Header</header>
<div class="wrapper">
<aside>Aside</aside>
<main>
<section>Section</section>
<section>Section</section>
</main>
<aside>Aside</aside>
</div>
<footer>Footer</footer>
</div>
Sample 3
html, body, .container {
height: 100%;
margin: 0;
}
.container, main {
display: flex;
flex-direction: column;
}
header, footer {
}
.wrapper {
flex: 1;
display: flex;
}
aside {
display: none;
}
main {
flex: 1;
}
section {
flex-basis: 60%;
}
section + section {
flex-basis: 40%;
}
/* for demo purpose */
header, footer, aside, section {
border: 1px dotted gray;
}
<div class="container">
<header>Header</header>
<div class="wrapper">
<aside>Aside</aside>
<main>
<section>Section</section>
<section>Section</section>
</main>
<aside>Aside</aside>
</div>
<footer>Footer</footer>
</div>

3 rows, 100% height layout, with flexbox

I'd like to know: is it possible to build a 3 rows layout, 100% height, with flexbox?
<header> The header content goes here. </header>
<div class="content"> The main content goes here. </div>
<footer> The footer content goes here. </footer>
fixed-height header and footer, while content the liquid part.
I mean, something like this but without absolute positioning:
* {
margin: 0;
}
header {
position: absolute;
width: 100%;
height: 64px;
top: 0;
background: red;
}
footer {
position: absolute;
width: 100%;
height: 64px;
bottom: 0;
background: green;
}
.content {
position: absolute;
width: 100%;
top: 64px;
bottom: 64px;
background: blue;
}
<header>The header content goes here.</header>
<div class="content">The main content goes here.</div>
<footer>The footer content goes here.</footer>
http://jsfiddle.net/BMxzn/
body {
display: flex;
flex-direction: column;
height: 100vh;
}
.content {
flex: 1; /* this is the key; consumes all available height */
background: blue;
}
header {
height: 64px;
background: red;
}
footer {
height: 64px;
background: green;
}
* {
margin: 0;
}
<header>The header content goes here.</header>
<div class="content">The main content goes here.</div>
<footer>The footer content goes here.</footer>
I add my own accepted answer here, because it addresses other issues as well.
I noted that the usually suggested code has a problem with Android prior to 4.4.4. By better indagating > this and > this I found out that the problem is > this, even if Android is not mentioned on the affected browsers list. So, my solution was to add flex-shrink: 0 to the content:
body{
display: flex;
flex-direction: column;
height: 100%;
}
.main-content{
flex: 1 0 auto; // flex-shrink:0 > android 4.4.2 fix (and some other browsers too)
}
It's also good to assign some kind of flex property to header and footer. I noticed on Android 442 that otherwise the bg color was gone:
.main-header,
.main-footer{
flex: none; // or flex something.
}
Also please note that I'm using Autoprefixer. Otherwise, you should not use the shortcut on main-content (IE shit-fix):
.main-content{
flex-grow: 1;
flex-shrink:0;
flex-basis:auto;
}
Very similar to these question : this & this
You need only 3 lines of code:
display:flex;
flex-flow:column;
height:/* whatever height needed */
and then flex:1; to the container that needs to fill remaining space
* {
margin: 0;
}
body {
display: flex;
flex-flow: column;
height: 100vh;/* if you relay on flex, then vh is also understood */
}
body>* {
padding: 1em;
}
header {
background: red;
}
footer {
background: green;
}
.content {
flex: 1;
background: blue;
color: white;
/* optionnal if you want to keep footer at screen
overflow:auto; */
}
<header>The header <b>of any height</b> content goes here.</header>
<div class="content">The main content goes here.</div>
<footer>The footer <b>of any height</b> content goes here.</footer>
there is no need to set heights to footer or header , but you might add overflow:auto to the main container.

Need help to make a responsive footer?

Is there a way for the footer to be positioned at the bottom no matter how much content is on the page and the content does not overlap with the footer?
Thank You for all your help
Flexbox might be a solution which is pretty flexible. The footer will always be at the bottom of the page unless there is too much content, then it will just be at the end of the page (thus no "overlapping").
document.getElementById("expand").addEventListener("click", function() { document.getElementById("long").style.display = "block"; });
* {
box-sizing: border-box;
}
#container {
display: flex;
flex-direction: column;
align-content: stretch;
height: 100vh;
}
header, footer {
flex-basis: auto;
flex-grow: 0;
padding: 20px;
background: #ccc;
}
div#content {
flex-grow: 1;
padding: 20px;
}
div#long {
display: none;
}
<div id="container">
<header>This is the header with auto-height.</header>
<div id="content">Short Content. <span id="expand"><strong><u>Click here more content!</u></strong></span>
<div id="long"><img src="http://placehold.it/350x1000"></div></div>
<footer>This is the footer, and always at the bottom of the window unless there's too much content.</footer>
</div>
A better idea can be utilizing a css framework like twitter-bootstrap. but if you want to achieve that with css only, something like this in your css file will give you what you need:
footer {
width: 100%;
bottom: 0;
position: fixed;
}
In order to make sure, any content and footer will not overlap you can either set a padding-bottom in your body:
body {
padding-bottom: 60px;
}
or have a content div which you set its 'margin-bottom':
.content {
margin-bottom: 60px;
}
jsfiddle