Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement the classic "sticky footer" with angular-material?

I recognize that the Angular Material implementation is a work in progress, but I've spent some time this morning trying to get familiar with it. However, I'm really struggling to get the concepts shown in the demos to work in a stand alone site.

It seems that when the directives like <md-toolbar> and <md-content> are used in containers with fixed heights, then they work great. I'm struggling with how to throw them inside a <body tag and be able to have a sticky footer layout like in this example.

I've tried many variations, but here's one example that doesn't work when the content is removed from the DOM. When the content is there it grows beyond the viewport and the footer is placed afterwards like you'd expect. In the latest versions of Chrome and Firefox this example keeps the footer at the bottom when the content is removed, but in IE this just doesn't work at all. In IE the footer floats just below the header regardless of whether the main content is shown or not.

DEMO: http://codepen.io/sstorie/pen/xbGgqb

<body ng-app="materialApp" layou-fill layout='column'>
    <div ng-controller="AppCtrl" layout='column' flex>
      <md-toolbar class='md-medium-tall'>
        <div class="md-toolbar-tools">
          <span>Fixed to Top</span>
          <span flex></span>
          <md-button class="md-raised" ng-click="toggleContent(!displayContent)">toggle content</md-button>
        </div>
      </md-toolbar>
      <main class='md-padding' layout="row" flex>
        <div flex>
        <md-card ng-if="displayContent" ng-repeat = "card in cards">
          {{$index}}
          {{card.title}}
          {{card.text}}
        </md-card>
        </div>
               <div flex>
        <md-card ng-if="displayContent" ng-repeat = "card in cards">
          {{$index}}
          {{card.title}}
          {{card.text}}
        </md-card>
        </div>
      </main>
      <md-toolbar class="md-medium-tall">
        <div layout="row" layout-align="center center" flex>
          <span>FOOTER</span>
        </div>
      </md-toolbar>
    </div>
  </body>

Javascript:

angular.module('materialApp', ['ngMaterial'])

.controller('AppCtrl', function($scope) {
    $scope.cards = [
    {text: 'Bla bla bla bla bla bla bla ',
     title: 'Bla' },
    ...repeat 10 times...
  ];

    $scope.displayContent = true;

    $scope.toggleContent = function(showContent) { $scope.displayContent = showContent; };
});

CSS:

body {
    min-height: 100%;
    height: auto !important;
    height: 100%;
}

I'm definitely not a CSS guru, but it feels like this should be easy to do with the layout options in angular-material, so I'm hoping I'm really missing something obvious here.

like image 534
Sam Storie Avatar asked Nov 23 '14 14:11

Sam Storie


People also ask

What is a sticky footer in CSS?

A sticky footer pattern is one where the footer of your page "sticks" to the bottom of the viewport in cases where the content is shorter than the viewport height.

Why is the footer sticky?

The purpose of a sticky footer is that it “sticks” to the bottom of the browser window. But not always, if there is enough content on the page to push the footer lower, it still does that. But if the content on the page is short, a sticky footer will still hang to the bottom of the browser window.

How do I make a sticky footer in bootstrap?

Make Footer Sticky To make your footer stick to the bottom of the viewport, add classes d-flex , flex-column , and h-100 to the body tag. Also add class h-100 to <html> tag.


4 Answers

There's no need for a bottom-sheet or something like it. Leverage the flexbox behavior and you are good to go:

  1. Use layout="column" and layout-fill attributes on your main wrapper (can be your body tag).
  2. Create your sections: header, main and footer.
  3. Use flex attribute on your main.

Check my example, based on @kuhnroyal pen.

Code | Full Page

like image 92
Ravan Scafi Avatar answered Oct 18 '22 03:10

Ravan Scafi


You can get this to work with a small workaround.

  • use min-height: calc(100vh - 176px) on your main element, (176px = 2*88px for the md-toolbars)
  • remove the layout='column' from the root div
  • remove the layout-fill layout='column' from the body

I replaced the material css/js with CDN version 0.8.3 since my IE10 would crash with that amount of CSS/JS in a Codepen.

I tested this on Chrome, Firefox and IE10 - seems to work.

http://codepen.io/anon/pen/azgdOZ

like image 28
kuhnroyal Avatar answered Oct 18 '22 04:10

kuhnroyal


So I am just experiementing with angular-material but what I did for this was

<div layout="column" layout-fill>
   <md-toolbar class="md-default-theme">
   <!-- your stuff -->
   </md-toolbar>
   <md-content layout-fill role="main">
      <!-- your main areas -->
   </md-content>
   <md-bottom-sheet>
      <div>I am a sticky footer</div>
   </md-bottom-sheet>
</div>

I have not experimented enough to know for sure whether this does everything they way I want, but is so far looks promising. Note if you content is not constrained, it would likely continually push the bottom-sheet down. if you used a overflow-y: auto on the md-content it might work (I don't have enough of my app built yet to test)

like image 21
jadrake Avatar answered Oct 18 '22 03:10

jadrake


I didn't find any of the answers work reliably across browsers without one flaw or the other.

As pointed out in this SO answer, this works:

<md-toolbar></md-toolbar>
<md-content flex layout="column">
    <div layout="column" flex>
        <main flex="none"></main>
        <div flex></div>
        <footer flex="none"></footer>
    </div>
<md-content>

Here's a codepen for the example.

like image 5
creimers Avatar answered Oct 18 '22 03:10

creimers