How to use CSS position to keep sidebar visible with Bootstrap 4
I have an arrangement of two columns:
<div class="row"> <div class="col-xs-8 content"> </div> <div class="col-xs-4"> </div> </div> If I set position:sticky to a sidebar column, I get sticky sidebar behavior: https://codepen.io/marcanuy/pen/YWYZEp
CSS
.sticky { position: sticky; top: 10px; } HTML:
<div class="row"> <div class="col-xs-8 content"> </div> <div class="col-xs-4 sticky"> </div> </div> But when I set the sticky property only in the menu located on the sidebar, so the related articles section scrolls fine and gets sticky behavior with the div menu, it doesn't work:
<div class="row"> <div class="col-xs-8 content"> </div> <div class="col-xs-4"> <div class="menu sticky"> </div> </div> </div> This is the screencast of the first example, scrolling the entire sidebar with sticky behavior, and then changing the sticky property in a menu that doesn't work:
Bootstrap 4 recommends the sticky property as lost support for the Affix jQuery plugin:
Discarded the Affix jQuery plugin. We recommend using the position: sticky polyfill.
I tested it in:
Firefox 47.0 with
css.sticky.enabled="true"underabout:configChrome 50.0.2661.94 (64-bit) with
experimental Web Platform featuresincluded inchrome://flags
(This is not a duplicate. How to make a sticky sidebar in Bootstrap? Because it uses BS affix)
I decided to enable flexbox . After raising the issue in Bootstrap Github, the repository received a response from the Bootstrap member :
The.col-xs-4 is not as tall as .col-xs-8, so basically there is no space for the menu to βfloatβ inside when the stickiness is triggered. Increase .col-xs-4 and everything will work fine: https://codepen.io/anon/pen/OXzoNJ If you enable the Flexbox version of our grid (via $ enable-flex: true;), you get automatic columns of equal height for free which is very convenient in your case.
In the stable version of Bootstrap 4.0.0, this is done using the sticky-top class ...
<div class="container"> <nav class="navbar navbar-light bg-light navbar-expand"> <a class="navbar-brand" href="#">Header</a> ... </nav> <div class="row"> <div class="col-8 content"> Content </div> <div class="col-4"> <div class="sticky-top"> <h4>Sticky menu</h4> ... </div> </div> </div> <div class="footer"> ... </div> </div> This works even at the height of the header / navigation, content and footer dynamically / unknown.
You need to enable JS polyfill in order to use it. The polyfins recommended by the link on the Bootstrap page are
Here is the updated code: https://codepen.io/anon/pen/zBpNRk
I included the required polyfill (I used stickyfill) and named it
var stickyElements = document.getElementsByClassName('sticky'); for (var i = stickyElements.length - 1; i >= 0; i--) { Stickyfill.add(stickyElements[i]); } The library suggested using this for your css
.sticky { position: -webkit-sticky; position: sticky; top: 0; } .sticky:before, .sticky:after { content: ''; display: table; } and finally you had a div order. You need to put the div with the sticky class outside of the whole line so that I fill the rest of the line with another <div class="col-xs-6"></div> which is empty.
