Maintaining the offset of content relative to its overflow box

Web pages with live-updating functionality often insert content into
scrollable containers (or their descendants). For example, real-time
newsfeeds/streams may display new posts and comments. It is often the case
that the new content is inserted above the content that the user is currently
reading; for example, after a user scrolls partway through a newsfeed, the
browser may receive a real-time comment on a post higher up in the feed. When
the new comment is inserted into the DOM (assuming normal flow), all of the
content below it is subsequently shifted down causing the user to lose their
position in the newsfeed.

One currently feasible solution is to use JavaScript to measure the dimensions
of an inserted node and scroll its overflow ancestor's contents by the same
amount to compensate as necessary. Deciding when to compensate for the
inserted node sometimes requires a heuristic since the intent is to maintain
the position of the content that the user is reading.

I'd like to propose a CSS property, "pinning", that tells the layout engine to
maintain the position of visible content relative to its overflow box. I
imagine the most common use cases will be for scrollable boxes, but this
behavior seems desirable for any box with clipped overflow and a positive
scrollTop.

The "pinning" property takes up to two values for vertical and horizontal
pinning, respectively: [<length>|<percentage>]{1,2}. Each determines a
threshold from the top and left of the element's content box; nodes that are
laid out before these thresholds do not cause their siblings to be shifted.
For example:

  .elem {
    height: 400px;
    overflow: auto;
    pinning: 25% 500px;
  }

In the vertical case, when the bottom margin edge of an inserted node is above
100px into the element's content box, the scrollTop value of the element will
increase by the added height of the node. Similarly, the element's scrollLeft
value will be adjusted if the inserted node's right margin edge is to the left
of 500px into the element's content box.

The benefits of a CSS-based solution include:
 * Improved performance. The JS-based solution synchronously queries for
   dimensions and positions
 * Improved UX. Arguably this should be the default behavior given a good
   heuristic since it seems rarely desirable to jarringly move content that a
   user is reading.
 * Ease of use. One line of CSS per scrollable element is simpler than
   maintaining a JS utility and ensuring that each DOM node insertion is
   monitored.

Aside from the added complexity to the CSS spec and implementations required
from browser vendors, one downside is a lack of flexibility. A JS-based
solution has more control over the heuristic that determines when to apply the
compensating scroll; e.g., it could use input events to infer what content the
user is currently reading.

Some details need to be worked out, like how "pinning" would interact with
"clip", but I'd appreciate feedback on whether the WG would be interested in
pursuing this feature, if not the property I've proposed.

Thanks,
James

Received on Thursday, 6 September 2012 07:35:40 UTC