7

Im working an angular site and im trying to implement a sticky footer across all views but the footer stops sticking when content exceeds the size of the window and the scrollbar appears. I've tried a bunch of different things, like adding a wrapper around all my content, adding a .push div but nothing seems to work. Has anyone come across this problem and fixed it or know some kind of plugin etc. I can use to make this work?with my current css/html this is what happens on pages where content exceeds the size of the window

Here is my code:

<body ng-app="noteSnapApp">
<!--[if lt IE 7]>
  <p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
<![endif]-->

<!-- Add your site or application content here -->
  <div style="min-height: 55px;" ng-controller="NavCtrl" class="navbar navbar-default navbar-static-top ns-navbar ns-hide-nav">
      <div  class="container">
        <div class="navbar-header">
          <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
            <span class="sr-only">NoteSnap</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </button>
          <a style="padding: 0" class="navbar-brand" href="/feed"><img class="img-responsive" src="images/notesnap_logo.png" width="165"></a>
        </div>
          <div class="navbar-collapse collapse">
            <ul class="nav navbar-nav navbar-right">
              <li ng-hide="logoutBtn" class="ns-logout"><a ng-click="logOut()" href="">Logout</a></li>
            </ul>
          </div>
      </div>
    </div>

    <div ng-view></div>

    <div class="banner-footer">
        <a href="http://bit.ly/1ul3gG7"><img class="img-responsive" src="images/banner.png" width="100%"></a>
    </div>

        <div id="fb-root">
        </div>
</body>

And my css:

html, body {height: 100%;}
html{
font-family: 'museo_sans100';
color: #333333;
position: relative !important;
min-height: 100%;
}

body {
background-color: transparent;
margin-bottom: 90px;
}

 .banner-footer {
position: fixed;
bottom: 0;
width: 100% ;
height: 90px;
clear: both;
}

Any and all suggestions are welcome and appreciated, im also willing to try jQuery/javascript workarounds, basically anything that works!

AstroCB
  • 12,337
  • 20
  • 57
  • 73
Saleh
  • 200
  • 1
  • 3
  • 10
  • 3
    It's positioned relative to the viewport because of `fixed` positioning. Try using `absolute` instead, so that it would be position with the respect to the `` in this case, which is the nearest ancestor having a position of `relative`. – Hashem Qolami Oct 04 '14 at 22:25
  • None of the examples are working with angular material 1.0. I have the same problem wherein the footer sticks to the bottom on init but then scrolls along when the content is longer than screen height – Uma Maheshwaraa Sep 26 '16 at 03:14

5 Answers5

12

There is also the Bootstrap solution, which doesn't really need the Bootstrap framework installed, just the following structure:

HTML:

<!-- Begin page content -->
<div class="container">
  <div class="page-header">
    <h1>Sticky footer</h1>
  </div>
  <p class="lead">Pin a fixed-height footer to the bottom of the viewport in desktop browsers with this custom HTML and CSS.</p>

</div>

<div class="footer">
  <div class="container">
    <p class="text-muted">Place sticky footer content here.</p>

  </div>
</div>

CSS:

/* Sticky footer styles
-------------------------------------------------- */
html {
  position: relative;
  min-height: 100%;
}
body {
  /* Margin bottom by footer height */
  margin-bottom: 60px;
}
.footer {
  position: absolute;
  bottom: 0;
  width: 100%;
  /* Set the fixed height of the footer here */
  height: 60px;
  background-color: #f5f5f5;
}


/* Custom page CSS
-------------------------------------------------- */
/* Not required for template or sticky footer method. */

.container {
  width: auto;
  max-width: 680px;
  padding: 0 15px;
}
.container .text-muted {
  margin: 20px 0;
}

Heres a working Fiddle with long text to show behavior when page scrolls.

jsfrocha
  • 1,812
  • 2
  • 21
  • 32
  • thank you sir! i thought i had tried this solution but sometimes css can be a pain in da ass – Saleh Oct 06 '14 at 19:06
1

The only solution that worked for me in angular material >1.0 is below

CSS

body {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
flex-wrap: nowrap;
}


.main{
    flex-grow: 1;
    overflow: auto;
    min-height: 2em;
}

Html

<body >
<navbar></navbar>
<div class="main" ui-view=""></div> 
<footer></footer>
</body>
Uma Maheshwaraa
  • 563
  • 2
  • 9
  • 17
  • This is by far the most elegant solution, except... in my case this only works when I don't use angular. It seems that somehow angular disables the flex container? – Kokodoko Nov 28 '16 at 10:17
0

I found the solution working from Javascript with window.innerHeight and set marginTop and marginBottom too. I hope this help you.

Eisson
  • 1
  • 1
0

Here is a angular directive that builds the sticky footer for angular as taken from this page: https://github.com/incuna/angular-sticky-footer/blob/master/angular-sticky-footer.js

<body>
    <div class="wrapper">
        <!-- All other content in here. -->
    </div>

    <div class="footer" sticky-footer=".wrapper"></div>
</body>

(function (angular) {
    'use strict';

    var module = angular.module('sticky-footer', []);

    module.directive('stickyFooter', [
        '$timeout',
        function ($timeout) {
            return {
                restrict: 'A',
                link: function (scope, iElement, iAttrs) {
                    var stickyFooterWrapper = $(iAttrs.stickyFooter);

                    // Quite often you will occur a few wrapping `<div>`s in the
                    // top level of your DOM, so we need to set the height
                    // to be 100% on each of those. This will also set it on
                    // the `<html>` and `<body>`.
                    stickyFooterWrapper.parents().css('height', '100%');
                    stickyFooterWrapper.css({
                        'min-height': '100%',
                        'height': 'auto'
                    });

                    // Append a pushing div to the stickyFooterWrapper.
                    var stickyFooterPush = $('<div class="push"></div>');
                    stickyFooterWrapper.append(stickyFooterPush);

                    var setHeights = function () {
                        var height = iElement.outerHeight();
                        stickyFooterPush.height(height);
                        stickyFooterWrapper.css('margin-bottom', -(height));
                    };

                    $timeout(setHeights, 0);
                    $(window).on('resize', setHeights);
                }
            };
        }
    ]);
}(window.angular));
checkmate711
  • 3,301
  • 2
  • 35
  • 45
0
(function () {
  'use strict';

  angular.module('myApp').directive('footerStick', function () {
    return {
      restrict: "E",
      templateUrl: "app/somewhere/footer.html",
      link: function (scope, el, attrs) {
        var win = angular.element($('html'));
        scope.$watch(function () {
            return win[0].offsetHeight;
          },
          function (newValue, oldValue) {
            var newHeight = newValue + 60;
             $(el[0].firstElementChild).css('top',newHeight);
          });
      }
    };
  })
}());

This would place your footer at the bottom (with 60px for placing the element itself, if it is longer you may have to adjust it). You need to have css property "position:absolute" on the footer element. When window is resized or new elements appear at run time, it still should be on the bottom.

vvn050
  • 194
  • 2
  • 4