sticky footer with angular directives, routes, material - html

I am trying to implement the classical sticky footer. I am using angular 1.4, ngRoute, ngMaterial etc.
I have tried css solutions (setting wrapper, footer, html, body 100%) and also jQuery functions that calculate the height of the element, but nothing works flawlessly. Note here that I don't want to set a certain height for the footer and then calculate the remaining space. I want it to be responsive to my content.
1) We most solutions, I am able to stick it to the bottom when the main content area is smaller that the height. In this case, there is an empty area between the main content and the footer (body). I can set the body's background color equal to the color of the ng-view so that it looks the same. I am not sure though if this is correct.
2) When the main content gets bigger, the footer is lost (goes behind the main content instead of scrolling down). Does this has anything to do with angular directives or routes, or am I missing something else?
You can check my plunkr to see. Click on any tab other than 'home' and you see an empty page with the footer on bottom. Click on 'home' and the footer is lost. It is actually there, behind the content.
p.s. I don't want to put all my code here it's pretty big. If you have any questions please see plunkr or ask me.
<body class="Site" ng-app="personalWebsite" ng-controller="mainController as main" style="display: flex; flex-flow: column nowrap;">
<div class="Site-content">
<tsafou-nav></tsafou-nav>
<md-content layout-padding ng-view></md-content>
</div>
<footer>
<tsafou-footer></tsafou-footer>
</footer>
</body>
*Footer
<div class="footer">
<p>Design by<span>WOW</span></p>
</div>
I just realized that the following code works on firefox but not on chrome! Can someone confirm that and suggest a fix?
<body class="Site" ng-app="personalWebsite" style="display: flex; flex-flow: column nowrap;">
<div class="Site-content">
<tsafou-nav></tsafou-nav>
<md-content layout-padding="" ng-view=""></md-content>
</div>
<footer>
<tsafou-footer></tsafou-footer>
</footer>

One option is using bootstrap sticky footer
http://getbootstrap.com/examples/sticky-footer-navbar/

It's related to the Angular Material library you are using, which relies on Flexbox. Review this site for how to add a footer using the Flexbox framework.
To easily fix your problem, you can move the footer within the div class that has the 'site-content' class. If you want to have some empty space, you can try setting a div outside that has a min height. So it would look like this:
<body class="Site" ng-app="personalWebsite" style="display: flex; flex-flow: column nowrap;">
<div class="Site-content">
<tsafou-nav></tsafou-nav>
<div style="min-height: 500px;">
<md-content layout-padding="" ng-view=""></md-content>
</div>
<footer>
<tsafou-footer></tsafou-footer>
</footer>
</div>

Related

Form with variable content and control button in fixed area

The main issue that is not treated in similar questions listed below is a FORM object that has a variable part and a non variable footer (submit buttons)
The aim is to display:
A header (a table (width:100%) with a logo and a text in second cell): size should be the smallest possible with all content displayed
A FORM (containing 2 parts):
Fields are in a div that will expand to all space remaining and will scroll if it lack space. (minimum size: 1 text line)
Submit / Rest buttons are in a table and should ALWAYS be visible and not resized in anyway. At worst the stick to bottom of browser window.(except if browser window becomes ridiculously small of course)
Nothing should go below bottom of browser window (except if user resize to a ridiculous size).
Hardcoded height is NOT an option (except the 100% for technical reasons - body or column parent for example). Header and footer height MUST be autocomputed by browser to use minimum space while displaying all content. If user reduce the width of the browser window increasing the header or footer text to wrap on more lines, the height must grow accordingly. Thus percentage or viewport heigh is not an option as it is arbitrary and can't take car of the user zoom, the browser width resize and such.
I've tried the following layout:
<div id="column">
<div id="header>
<table><tbody>
<tr><td>LOGO</td><td>Some intro text on a few lines</td></tr>
</tbody></table>
<!-- optionnel error line (arbitrary length) if previous form submission failed -->
</div>
<form>
<div id="variable_scrollable_content">
<!-- multiple field sets hosting some input (text, select, ...) -->
</div>
<div id="footer">
<table><tbody>
<tr><td>Save button</td><td>Reset button</td></tr>
</tbody></table>
<!-- A few lines of text -->
</div>
</form>
</div>
After I gave a careful view to similar questions (see below), I was unable to find something that could handle the FORM object that has a variable size scrollable part and a fixed footer.
I also gave a careful look at https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Basic_Concepts_of_Flexbox with no more success.
I tried the flex approach for classes header, variable_scrollable_content and footer with no success. I also tried to put the form object in flex class but that doesn't work.
As I can't separate the FORM submit/reset buttons from the fields they manage, I don't know how to solve this.
header should stick to top of browser windows
footer (containing form control buttons) should stick to bottom of browser window at worst or stick at the end of the last fields if browser windows is big enough.
fields should be in a variable size container that uses all the remaining space between header and footer and has overflow-y:scroll; so it can scroll if it can't display its whole content.
In case the above simplified code is not sufficient, the "real" code can be found here:
https://github.com/finley/SystemImager/blob/initrd-from-imageserver-and-dont-package-initrd/webgui/edit_config.php
The full css is here:
https://github.com/finley/SystemImager/blob/initrd-from-imageserver-and-dont-package-initrd/webgui/css/screen.css
Similar questions
I have checked the following similar questions, and I believe my question is different as the main problem is the FORM object interfering with the layout:
scrolling content between fixed header & footer with variable height
Content height expand between fixed header and fixed footer
Make a div fill the height of the remaining screen space
Original question was here: variable height div between header and footer
I've just found the solution.
In this situation, the problem was the FORM object that would interfere with flex column children not at the same Dom level tree.
The simple solution was to move the FORM object so it includes the flex column it its whole content.
The above code becomes:
<form>
<div id="column">
<div id="header>
<table><tbody>
<tr><td>LOGO</td><td>Some intro text on a few lines</td></tr>
</tbody></table>
<!-- optionnal error line (arbitrary length) if previous form submission failed -->
</div>
<div id="variable_scrollable_content">
<!-- multiple field sets hosting some input (text, select, ...) -->
</div>
<div id="footer">
<table><tbody>
<tr><td>Save button</td><td>Reset button</td></tr>
</tbody></table>
<!-- A few lines of text -->
</div>
</div>
</form>
But this was not sufficient because setting flex column height to 100% (when body is also set to 100%) won't work. maybe the form object doesn't propagate the height?
The solution was to set height of column with vh (viewport height) unit.
So I set it to 100vh. Unfortunately, there are some glitches due to some border size and padding from parent objects and itself. So as a fallback I put it to 96vh, but this is ugly and I'll investigate and will remove the parasite border size padding that makes the body bigger than 100vh.
<body style="height: 100%">
<form>
<div style="display: flex; flex-flow: column; height: 100vh;">
<div id="header" style="flex: 0 0 auto;">foo bar</div>
<div id="content" style="flex: 1 1 auto; overflow-y: scroll;">Input fields</div>
<div id="footer" style="flex: 0 0 auto;">Control buttons</div>
</div>
</form>
</body>
The above sump is bigger than 100vh in height.
There are 2 solution to fix that:
Remove any border padding or such from parent object.
Set the column to an absolute position (0,0)
Alternative solution to scrollable FORM in flex content with fixed footer containing control buttons is to move FORM control buttons outside the form.
The code then looks like:
<body style="height: 100%">
<div style="display: flex; flex-flow: column; height: 100%;">
<div id="header" style="flex: 0 0 auto;">foo bar</div>
<div id="content" style="flex: 1 1 auto; overflow-y: scroll;">
<form id="foobar">
Input fields
</form>
</div>
<div id="footer" style="flex: 0 0 auto;">
<button form="foobar" type="submit" formmethod="POST">Submit</button>
<button form="foobar" type="reset">Reset</button>
</div>
</div>
</body>
The advantage is that it works with height 100% as it takes account of margin borders and padding of parent (while vh is an absolute viewport size).

Angular 6: Mat-card Make Page Content Scrollable w/o using fixed prop

I have a top nav, side nav and the main content of the page. On click, the tabs on the side nav should bring the div associated with the tab to the top of the page (This is a different issue i am facing as scrollTop method from JS isn't working, but I am able to use scrollIntoView() for now to get something going)
template
<mat-card class="main-card">
<mat-card-title>Some title</mat-card-title>
<mat-card-content class="main-content">
<div class="div1">Div1 content</div>
<div class="div2">Div2 content</div>
<div class="div3">Div2 content</div>
</mat-card-content>
</mat-card>
CSS
.main-card {
overflow: auto;
height: 700px;
}
.main-content {
height: 1000px;
overflow: auto;
}
sidenav items
<div class="side-nav">
<div class="mat-list-item" (click)="handleElemScroll(div1)">
<span>Div1</span>
</div>
<div class="mat-list-item" (click)="handleElemScroll(div2)">
<span>Div2</span>
</div>
<div class="mat-list-item" (click)="handleElemScroll(div1)">
<span>Div2</span>
</div>
</div>
on the main card, I am unable to add the height prop to, even if I use !important. I've run into this issue with a few other times using angular-material. I am forcing a scroll, but mid way through the scroll, the entire page begins to scroll. Even though the height of my mat-card-content is set to be larger than the mat-card itself.
A few questions if anyone can guide me
1. Why does my entire page begins to scroll mid way?
2. Without making my side and top nav stick, how can I implement a scroll? Is my idea of using overflow, and making the inner container height larger than its parent container the correct idea here?
Thanks for any help

Keeping my footer at the bottom with responsive design using bootstrap

How do i keep my footer at the bottom of the page even when I click the toggle for the sidebar? The footer I made is at the bottom but whenever i click the sidebar toggle it goes up like this
Im using bootstrap btw.
This is how I did it. I'm not entirely happy with the outcome as the height of the footer is a fixed number (I would prefer if the height could be dynamic).
<div id="wrapper">
All your contents, div, nav etc go in here
<div id="push"></div> <!--add the push div here -->
</div>
<footer>
</footer>
The CSS:
#push, footer {
height:100px; /*or whatever height you need */
}
I'm not sure what your codes look like, so I can only hope that this helps.
I think you are looking for this: http://getbootstrap.com/2.3.2/examples/sticky-footer.html
It is a plugin which makes your footer sticky. You can find the code in the examples folder of your bootstrap download.

Make a div stick to bottom of parent

I am trying to create a layout here which looks like the following: Here's the fiddle
<body>
<div class="wrapper">
<div class="header">
Header
</div>
<div class="content">
This is the content section
</div>
<div class="stream-content">
This is the stream content.
</div>
<div class="push">
</div>
</div>
<div class="footer">
</div>
<body>
I want the content section to take up the full space between the header and footer section. There is an additional section called [stream-content] which if there (will be there only on home page) has to take the position just before the footer. And in that case, the content section should take up space all the between header and stream-content section. I tried doing the same with absolute positioning but all my elements were going haywire, so wanted to understand the correct way of doing this. Thanks in advance for all help!
Add position:relative to your wraper class.
Add position:absolute;bottom:0; to the stream-content class.
Check it here.
Fiddle
If I understand correctly then one way to do it would be to put [steam content] outside the wrapper, as wrapper is the one that is keeping the footer at the bottom. If you must have the [steam content] inside wrapper than you can try something like this http://ryanfait.com/sticky-footer/ to keep it at the bottom together with the footer

Having Footer Problems (overlapping content, width issues). Can you help me?

I'm trying to make an our team page using bootstrap but I can't get the footer to act right. At first it was not filling the width of the page, now (I'm not so sure what I did) this problem is solved but it is overlapping onto the content: some thumnails, writing, and a link. The page with the problem is: http://rdtaxsavers.com/new/OurTeam.php
My css file is at rdtaxsavers.com/new/css/bootstrap.css
You'll notice that the rdtaxsavers.com site footer works fine. Thanks in advance!
EDIT: I got it back to where the footer is not overlapping but now the width issue is back. You will see in my css that my modal-footer class has width:100%; at the end of it but this does not fix the issue.
EDIT: This is driving me nuts. When I fix the width problem then it overlaps, when I fix the overlap the width is broken.
I think you are placing the footer inside the Container class, the container class has a width of 1170px. therefore the footer will not be 100% width to the body. move the footer out of container class. or you have to change the width of container class.
this is what you have:
<div class="container">
<div class="row">...</div>
<footer>...</footer>
</div>
try to do this:
<div class="container">
<div class="row">...</div>
</div>
<footer>...</footer>
Try clearing the float:left in the ul.thumbnails element.