Sticking footer to the bottom

Has anyone found (good) solutions to sticking the footer to the bottom of the page? For short pages (like empty unread list) it looks quite ugly sitting in the middle of the browser window.

1 Like

What do you mean it’s sitting in the middle of the browser window?

If the browser window is taller than the content, the footer is drawn at the end of the content (i.e. middle of the window), not at the bottom of the window.


edit. the footer also flashes sometimes while loading pages:

3 Likes

I assume you’re talking about a custom footer added in the admin>customize section. It seems that the only way to do it on a Discourse forum is with javascript. This mostly works, but it would be great if someone could correct the way I am firing the javascript function. The way it’s being done here can’t be very efficient.


Edit: this is an improved version. Unless someone suggests a more obvious way to do this, I’ll make this into a plugin.

given this as a footer:

<div id="sticky-footer">
    <div class="wrap">
        <h3>this is the custom footer</h3>  
    </div>
</div>
#sticky-footer {
    position: static;
    color: #fff;
    background: #CD5C5C;
    // In case the window with a static footer is resized downwards
    box-shadow: 0 300px 0 300px #CD5C5C;
    height: 120px;
}

This will fix it to the bottom when there isn’t enough content to push it there.

<script>
    var stickFooter = function() {
        var $footer = $('#sticky-footer'),
            footerHeight = $footer.outerHeight(),
            footerOffset = $footer.offset(),
            footerBottom;
            
            if (footerOffset) {
                footerBottom = footerHeight + footerOffset.top;

                if (footerBottom <= $(window).height()) {
                    $footer.css({
                        'position': 'fixed',
                        'left': 0,
                        'right': 0,
                        'bottom': 0
                    });
                    // In case the window is resized upwards
                    $('#main').css('padding-bottom', footerHeight + "px");
                } else {
                    $footer.css('position', 'static');
                    $('#main').css('padding-bottom', 0);
                }
            }
    };

    Discourse.ApplicationView.reopen({
        didInsertElement: function() {
            this._super();
            stickFooter();
        },
        
        pathChanged: function() {
            Ember.run.scheduleOnce('afterRender', this, function() {
                stickFooter();
            });
        }.observes('controller.currentPath', 'controller.model')
    });
    
    Discourse.DiscoveryCategorysView.reopen({
        didInsertElement: function() {
            this._super();
            stickFooter();
        },
        
        pathChanged: function() {
            Ember.run.scheduleOnce('afterRender', this, function() {
                stickFooter();
            });
        }.observes('controller.currentPath', 'controller.model')
    });
    
    Discourse.DiscoveryTopicsView.reopen({
        didInsertElement: function() {
            this._super();
            stickFooter();
        },
        
        pathChanged: function() {
            Ember.run.scheduleOnce('afterRender', this, function() {
                stickFooter();
            });
        }.observes('controller.currentPath', 'controller.model')
    });

    Discourse.CloakedView.reopen({
        didInsertElement: function() {
            this._super();
            stickFooter();
        },
        
        pathChanged: function() {
            Ember.run.scheduleOnce('afterRender', this, function() {
                stickFooter();
            });
        }.observes('controller.currentPath', 'controller.model')
    });
</script>

6 Likes

I’ve made a plugin for this: https://github.com/scossar/discourse-sticky-footer
Pull requests and suggestions for improvements are welcome.

The plugin takes care of most of the flashing by keeping the footer from jumping around the window as the view is rendered. If you reload the topic-list while you are on the topic list, the footer flashes in the middle of the screen. I think that can be fixed.

5 Likes

The worst of the flashing is caused by .list-container being hidden with display: none when the loading spinner is active. You can fix it with:

.list-container.hidden {
  display: block;
  visibility: hidden;
}
5 Likes