     $viewport
 
   ###*
-  Marks this element as a scrolling container.
-  Use this e.g. if your app uses a custom panel layout with fixed positioning
-  instead of scrolling `<body>`.
+  Marks this element as a scrolling container. Apply this ttribute if your app uses
+  a custom panel layout with fixed positioning instead of scrolling `<body>`.
+
+  [`up.reveal`](/up.reveal) will always try to scroll the viewport closest
+  to the element that is being revealed. By default this is the `<body>` element.
+
+  \#\#\#\# Example
+
+  Here is an example for a layout for an e-mail client, showing a list of e-mails
+  on the left side and the e-mail text on the right side:
+
+      .side {
+        position: fixed;
+        top: 0;
+        bottom: 0;
+        left: 0;
+        width: 100px;
+        overflow-y: scroll;
+      }
+
+      .main {
+        position: fixed;
+        top: 0;
+        bottom: 0;
+        left: 100px;
+        right: 0;
+        overflow-y: scroll;
+      }
+
+  This would be the HTML (notice the `up-viewport` attribute):
+
+      <div class=".side" up-viewport>
+        <a href="/emails/5001" up-target=".main">Re: Your invoice</a>
+        <a href="/emails/2023" up-target=".main">Quote for services</a>
+        <a href="/emails/9002" up-target=".main">Fwd: Room reservation</a>
+      </div>
+
+      <div class="main" up-viewport>
+        <h1>Re: Your Invoice</h1>
+        <p>
+          Lorem ipsum dolor sit amet, consetetur sadipscing elitr.
+          Stet clita kasd gubergren, no sea takimata sanctus est.
+        </p>
+      </div>
 
   @method [up-viewport]
+  @ujs
+  ###
+
+  ###*
+  Marks this element as a navigation fixed to the top edge of the screen
+  using `position: fixed`.
+
+  [`up.reveal`](/up.reveal) is aware of fixed elements and will scroll
+  the viewport far enough so the revealed element is fully visible.
+
+  Example:
+
+      <div class="top-nav" up-fixed="top">...</div>
+
+  @method [up-fixed=top]
+  @ujs
+  ###
+
+  ###*
+  Marks this element as a navigation fixed to the bottom edge of the screen
+  using `position: fixed`.
+
+  [`up.reveal`](/up.reveal) is aware of fixed elements and will scroll
+  the viewport far enough so the revealed element is fully visible.
+
+  Example:
+
+      <div class="bottom-nav" up-fixed="bottom">...</div>
+
+  @method [up-fixed=bottom]
+  @ujs
   ###
 
   up.bus.on 'framework:reset', reset


This modules contains functions to scroll the viewport and reveal contained elements.

By default Up.js will always scroll to an element before updating it.

The container that will be scrolled is the closest parent of the element that is either:

- The currently open [modal](/up.modal)
- An element with the attribute `[up-viewport]`
- The `<body>` element
- An element matching the selector you have configured using `up.viewport.defaults({ viewSelector: 'my-custom-selector' })`.

@class up.viewport  
###
up.layout = (->

  u = up.util

  ###*
  @method up.viewport.defaults
  @param {String} [options.viewport]
  @param {String} [options.fixedTop]
  @param {String} [options.fixedBottom]

    bottom: Math.max(0, fixedBottomTops...)

  ###*
  Scroll's the given element's viewport so the element
  is visible for the user.

  By default Up.js will always reveal an element before
  updating it with Javascript functions like [`up.replace`](/up.flow#up.replace)
  or UJS behavior like [`[up-target]`](/up.link#up-target).

  \#\#\#\# How Up.js finds the viewport

  The viewport (the container that is going to be scrolled)
  is the closest parent of the element that is either:

  - the currently open [modal](/up.modal)
  - an element with the attribute `[up-viewport]`
  - the `<body>` element
  - an element matching the selector you have configured using `up.viewport.defaults({ viewSelector: 'my-custom-selector' })`

  \#\#\#\# Fixed elements obstruction the viewport

  Many applications have a navigation bar fixed to the top or bottom,
  obstructing the view on an element.

  To make `up.aware` of these fixed elements you can either:

  - give the element an attribute [`up-fixed="top"`](#up-fixed-top) or [`up-fixed="bottom"`](up-fixed-bottom)
  - [configure default options](#up.layout.defaults) for `fixedTop` or `fixedBottom`

  @method up.reveal
  @param {String|Element|jQuery} element
  @param {String|Element|jQuery} [options.viewport]
  @param {Number} [options.duration]
  @param {String} [options.easing]
  @return {Deferred}
    A promise that will be resolved when the element is revealed.
  ###
  reveal = (elementOrSelector, options) ->
    options = u.options(options)
    $element = $(elementOrSelector)
    $viewport = findViewport($element, options.viewport)

    viewportIsBody = $viewport.is('body')
    viewportHeight = if viewportIsBody then u.clientSize().height else $viewport.height()
    originalScrollPos = $viewport.scrollTop()
    newScrollPos = originalScrollPos

