Re: Maintaining the offset of content relative to its overflow box

On Wed, Sep 5, 2012 at 12:27 AM, James Ide <ide@fb.com> wrote:
> 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.

Excellent use-case description!  Thanks so much for that; most
proposals skimp on that, so it's hard to tell what improvements can be
made to their proposal.  ^_^

> 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.

I have a few problems with this proposal.  I suspect that the details
of your proposal were strongly influenced by the JS library you were
using; we can do better when we control the language.

1. It's way too specific.  You need to predict what zone of the
element you'll be inserting things in.  I think we can do this
automatically.
2. It's not general enough.  You only cover element insertion.
Element deletion, or just an element changing size, still causes
shifting in the scroll area.  We can generalize this and cover those
cases automatically.

Here's an alternate proposal:

scroll-adjust: none | stable  (not super happy with the property name,
but roll with it)

The "none" value (which is the initial value) is today's behavior.
The property does nothing special.

The "stable" value adjust the scroll position of an element in some
circumstances.  Call the element with this property set the
"stabilized element".  If the stabilized element's children change
width or height for any reason (used values), and the child's
head/start edge is outside the current visible scroll area of the
stabilized element in the head/start direction, adjust the scroll
position of the stabilized element by the amount the width/height
changed.

This will keep the visible content stable no matter what's going on
earlier in the element.

~TJ

Received on Thursday, 6 September 2012 21:04:38 UTC