W3C home > Mailing lists > Public > www-style@w3.org > June 2012

Re: Sticky Positioning

From: Brad Kemper <brad.kemper@gmail.com>
Date: Thu, 28 Jun 2012 10:37:08 -0700
Message-Id: <C47EA512-B6F3-4855-8990-17FDEE8F8FEE@gmail.com>
Cc: "www-style@w3.org" <www-style@w3.org>
To: Edward O'Connor <eoconnor@apple.com>

On Jun 26, 2012, at 4:50 PM, Edward O'Connor <eoconnor@apple.com> wrote:

> A feature like this has been a long time coming. It was first proposed
> (for table headers) by the OEBPS (EPUB) folks on www-style in 2002[1]:
> 
>> One of the examples of the desired layout\formatting behavior would be
>> that the header column would stay frozen if horizontal scrolling is
>> required to view additional columns of the table (similar to the
>> "Freeze Panes" option in Excel).
> 
> Mikko Rantalainen proposed generalizing such a feature to elements other
> than table headers[2]:
> 
>> Perhaps a new position value (e.g. "fixed-relative") that is a mix of
>> "relative" and "fixed": the content still reserves space in the flow
>> similar to relative but it would be displayed as fixed if the element
>> would not fit in the viewport but its containing block is visible. In
>> that case, the element would be "moved" within its containing block
>> until it would fully fit in the viewport.
> 
> Mikko's proposal is very close to what we have in mind: a new value for
> the 'position' property, similar to relpos, but with a new method of
> calculating the element's offset.
> 
> You'd use it like this:
> 
> h1 {
>  position: sticky;
>  top: 10px;
> }
> 
> This means that every <h1> in the document will "stick" 10 pixels from
> the viewport top when things scroll such that the <h1> would have been
> partially off-screen. When the viewport has scrolled such that the
> visible portion of the <h1>'s containing box is too small to fit the
> <h1>, it should stop at the containing box's edge and only be partially
> displayed.

I think this would be great. But I don't think the tbrl keywords should be only be relative to the viewport, but rather to the nearest potentially scrollable ancestor (overflow: auto | scroll). In many designs that might be the main scrollable content area with the viewport itself not scrolling at all.

I'm not sure what you mean by the containing box's edge, especially if you are talking about only the viewport being the measure of what the 'top: 10px' is relative to. Wouldn't it stop at the edge of the same box, ie the viewport?

> There are a lot of details to work out, of course. Doug raised several
> questions about such a feature in [3]; here are some preliminary
> thoughts on them.
> 
> Doug wrote:
>> * should sticky content accumulate?
> 
> No. In some future level of this feature, it might be worth
> investigating a new property or set of properties which could cause such
> accumulation. We should avoid this problem in the first level of this
> feature by having the sticky elements simply overlap, just as other
> positioned elements do.

I would prefer that other position:sticky items (or perhaps sticky items with the same z-index) could push others out of the way, rather than overlap, in the way that list section labels do in iOS scrolling navigation lists (you know authors are going to want that). Thus is there are two items with 'top:0', the bottom one would push the top one out of the visible area until it could stick at 0 without overlap. Or if there are two items with 'left:0', the rightmost one would push the leftmost one off to the left. This is something important to have in first iteration, as it would be more clumsy to add it on later through a separate property, and I strongly suspect it will be the preferred mode.

By the way, I think it is important for position:sticky to support z-index layering, so that the items can be interleaved with other position:relative and position:absolute items (since using 'position:relative' to get such z control would no longer be an option for sticky items).

> Doug wrote:
>> * what should be the behavior when a user jumps to the middle of a
>>  containing block that would otherwise have a sticky header/footer
>>  when scrolled (e.g. a row in the middle of a very long table, a
>>  paragraph under a sticky <h2> itself under a sticky <h1>)? (I think
>>  it the sticky content effect should be applied, though I suspect
>>  this will make implementation rather more difficult.)
> 
> The sticky effect should be applied, just like any other positioning
> scheme.

Yeah, I don't see the problem here.

> Doug wrote:
>> * should there be an event that is thrown when content sticks, so
>>  that the author can choose to enhance the effect via script or
>>  declarative animation?
> 
> No. A big advantage of this feature over emulations of it in JS is the
> lack of events.

I've no strong opinion on that, although it seems useful to have an event for sticking and unsticking, in case the author wants to change transparency or hide/show another element or something. You are doing away with all related events anyway, right? You still have scroll events, for instance.

Some other points:

* if top and bottom are both specified, they set the sticky limits for each; they do not change the height the way they would with absolute or fixed positioning. Same with left/right/width.

* if only z-index-same items could push each other aside, then you could still get overlap if you want, by giving the items different z-indexes.

* if top and bottom are both non-auto, and the element is taller than the scrolling container (or if left and right are both non-auto, and the element is wider than the scrolling container), then writing direction gives precedence. Thus in English lrtb, left and top would override right and bottom if both could not be satisfied simultaneously. 
Received on Thursday, 28 June 2012 17:37:42 GMT

This archive was generated by hypermail 2.3.1 : Tuesday, 26 March 2013 17:20:55 GMT