headroom.js
Version:
Give your page some headroom. Hide your header until you need it
182 lines (131 loc) • 6.81 kB
Markdown
# [Headroom.js](http://wicky.nillia.ms/headroom.js)
**Give your pages some headroom. Hide your header until you need it.**
## What's it all about?
Headroom.js is a lightweight, high-performance JS widget (with no dependencies!) that allows you to react to the user's scroll. The header on [this site](http://wicky.nillia.ms/headroom.js) is a living example, it slides out of view when scrolling down and slides back in when scrolling up.
### Why use it?
Fixed headers are a popular approach for keeping the primary navigation in close proximity to the user. This can reduce the effort required for a user to quickly navigate a site, but they are not without problems…
Large screens are usually landscape-oriented, meaning less vertical than horizontal space. A fixed header can therefore occupy a significant portion of the content area. Small screens are typically used in a portrait orientation. Whilst this results in more vertical space, because of the overall height of the screen a meaningfully-sized header can still be quite imposing.
Headroom.js allows you to bring elements into view when appropriate, and give focus to your content the rest of the time.
### How does it work?
At it's most basic headroom.js simply adds and removes CSS classes from an element in response to a scroll event. This means **you must supply your own CSS styles separately**. The classes that are used in headroom.js that are added and removed are:
```html
<!-- initially -->
<header class="headroom">
<!-- scrolling down -->
<header class="headroom headroom--unpinned">
<!-- scrolling up -->
<header class="headroom headroom--pinned">
```
Relying on CSS classes affords headroom.js incredible flexibility. The choice of what to do when scrolling up or down is now entirely yours - anything you can do with CSS you can do in response to the user's scroll.
## Usage
Using headroom.js is really simple. It has a pure JS API, plus an optional jQuery/Zepto plugin and AngularJS directive.
### Install with npm
```bash
npm install headroom.js --save
```
### Install with bower
```bash
bower install https://npmcdn.com/headroom.js/bower.zip --save
```
### Using Headroom.js with a CDN
A universal build (suitable for script tags, CommonJS, and AMD) is available from npmcdn.com:
[https://npmcdn.com/headroom.js](https://npmcdn.com/headroom.js)
### With pure JS
Include the `headroom.js` script in your page, and then:
```js
// grab an element
var myElement = document.querySelector("header");
// construct an instance of Headroom, passing the element
var headroom = new Headroom(myElement);
// initialise
headroom.init();
```
### With jQuery/Zepto
Include the `headroom.js` and `jQuery.headroom.js` scripts in your page, and then:
```js
// simple as this!
// NOTE: init() is implicitly called with the plugin
$("header").headroom();
```
The plugin also offers a data-* API if you prefer a declarative approach.
```html
<!-- selects $("[data-headroom]") -->
<header data-headroom>
```
Note: Zepto's additional [data module](https://github.com/madrobby/zepto#zepto-modules) is required for compatibility.
### With AngularJS
Include the `headroom.js` and `angular.headroom.js` scripts in your page, and include the Headroom module
```javascript
angular.module('app', [
// your requires
'headroom'
]);
```
And then use the directive in your markup:
```html
<header headroom></header>
<!-- or -->
<headroom></headroom>
<!-- or with options -->
<headroom tolerance='0' offset='0' scroller=".my-scroller" classes="{pinned:'headroom--pinned',unpinned:'headroom--unpinned',initial:'headroom'}"></headroom>
```
Note: in AngularJS, you cannot pass a DOM element as a directive attribute. Instead, you have to provide a selector that can be passed to [angular.element](http://docs.angularjs.org/api/ng/function/angular.element). If you use default AngularJS jQLite selector engine, [here are the compliant selectors](https://code.google.com/p/jqlite/wiki/UsingJQLite).
## Options
Headroom.js can also accept an options object to alter the way it behaves. You can see the default options by inspecting `Headroom.options`. The structure of an options object is as follows:
```js
{
// vertical offset in px before element is first unpinned
offset : 0,
// scroll tolerance in px before state changes
tolerance : 0,
// or scroll tolerance per direction
tolerance : {
down : 0,
up : 0
},
// element which is source of scroll events. Defaults to window
scroller : element,
// css classes to apply
classes : {
// when element is initialised
initial : "headroom",
// when scrolling up
pinned : "headroom--pinned",
// when scrolling down
unpinned : "headroom--unpinned",
// when above offset
top : "headroom--top",
// when below offset
notTop : "headroom--not-top",
// when at bottom of scoll area
bottom : "headroom--bottom",
// when not at bottom of scroll area
notBottom : "headroom--not-bottom"
},
// callback when pinned, `this` is headroom object
onPin : function() {},
// callback when unpinned, `this` is headroom object
onUnpin : function() {},
// callback when above offset, `this` is headroom object
onTop : function() {},
// callback when below offset, `this` is headroom object
onNotTop : function() {}
// callback at bottom of page, `this` is headroom object
onBottom : function() {},
// callback when moving away from bottom of page, `this` is headroom object
onNotBottom : function() {}
}
```
## Examples
Head over to the [headroom.js playroom](http://wicky.nillia.ms/headroom.js/playroom/) if you want see some example usages. There you can tweak all of headroom's options and apply different CSS effects in an interactive demo.
## Browser support
Headroom.js is dependent on the following browser APIs:
* [requestAnimationFrame](http://caniuse.com/#feat=requestanimationframe)
* [classList](http://caniuse.com/#feat=classlist)
* [Function.prototype.bind](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind#Browser_compatibility)
All of these APIs are capable of being polyfilled, so headroom.js can work with less-capable browsers if desired. Check the linked resources above to determine if you must polyfill to achieve your desired level of browser support.
## Contributions & Issues
Contributions are welcome. Please clearly explain the purpose of the PR and follow the current style.
Issues can be resolved quickest if they are descriptive and include both a reduced test case and a set of steps to reproduce.
## License
Licensed under the [MIT License](http://www.opensource.org/licenses/mit-license.php).