How to combine slide-in panels with sticky header?


Tags: css,twitter-bootstrap,css-position,css-transforms

Problem :

I'm currently working on a CSS-based 3-column layout that has the following requirements:

  • On the desktop…
    • …all columns are shown.
  • On mobile devices…
    • …only the middle column is shown.
    • …the left column can slide in from the left, triggered by a swipe or a tap on a button.
    • …the right column can slide in from the right, triggered by a swipe or a tap on a button.
  • Independent of the device…
    • …the middle column contains three rows: The main header, a sub header, and the actual content.
    • …the main header scrolls away when scrolling down.
    • …the subheader is sticky on the top of the screen when scrolling down.

Now I tried to implement this:

  • Creating a 3-column layout and hiding the left and right columns is easy, using Bootstrap.
  • Having three rows in the middle column is easy, too.
  • To make the subheader sticky, I have two options:
    • Use position: sticky (best solution in technical terms, but not supported by any browser).
    • Use a script, attach to the scroll event and change to position: fixed on demand. This is what Bootstrap offers OOTB with its affix plugin. Using this plugin, it's an easy task, too.
  • Creating two sidebars and sliding them in is easy as well, using something such as Snap.js.

Problems start when I want to combine the sticky subheader with the sliding sidebars: The affix plugin simply stops working, and the subheader is not sticky any more. Basically, the problem comes down to issues with CSS transform and position: fixed, see Eric Meyer's awesome blog post on this and this answer.

One option to solve this could be to put the headers above the area where the sidebars slide in, so that they are not affected, but this is not what I want: I want the sidebar to push away everything.

How can I solve this? Is this possible at all?



Solution :

Consider this post: Applying snap.js to my main content wrapper seems to break *some* of my jQuery functions

Bootstraps affix.js listens to the $(window).on('scroll'... event. Snap.js seems to change the scrollable element from the "window" element to the element where you added the "snap-content" class. I dont see any other solution as to write the sticky functionality provided by bootstrap yourself.

Use this as a reference. Based on your current scroll position (in pixels) you can add css attributes or even whole css classes to the element you want to make sticky:

jQuery(document).ready(function ($) {
$('.snap-content').scroll(function () {
    if ($(this).scrollTop() > 140) {
        if ($("#navbar").css('position') !== 'fixed') {
            $("#navbar").css("position", "fixed");
        }
    } else {
        if ($("#navbar").css('position') !== 'static') {
            $("#navbar").css("position", "static");
        }
    }
});

});


    CSS Howto..

    How to Create 3 Column Layout with CSS Only?

    How do you put