root-scroller icon indicating copy to clipboard operation
root-scroller copied to clipboard

Allow fixed header

Open jakearchibald opened this issue 8 years ago • 8 comments

From https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/COF0YKkjZVQ:

Currently we limit the scrollers developers can set to be exactly 100% viewport filling, do developers have other use cases?

Imagine a grid/flexbox layout like this which fills 100% of the viewport:

+--------------+
|    HEADER    |
|--------------|
|              |
|              |
|   SCROLLER   |
|              |
|              |
|--------------|
|    FOOTER    |
+--------------+

This is a common native app structure. Developers often use position: fixed for the header instead of grid/flexbox to address the problems this project aims to solve. As a result the scrollbar is rendered over the top of the header, and the developer has to use hacks to ensure the content has a top-padding matching the height of the header (although position: sticky helps here).

Ideally the developer should be able to transition from one scrollable div to another while the header and footer remain static.

Unfortunately the 100% viewport requirement gets in the way here.

jakearchibald avatar Jan 10 '17 14:01 jakearchibald

Thanks, that's a good case to keep in mind.

I chose to keep it restricted at first since it's much easier to loosen restrictions later than it is to make them tighter. Allowing non viewport filling boxes to become the root scroller also raises questions about how we handle the revealed content - we do some sketchy things where we don't grow the box but we do expose more content. This all happens in compositing and is special cased for the top-level scroller so it'll be quite a bit of implementation work to generalize and clean that up, though it's probably a worthwhile thing to do - explaining the platform and all.

bokand avatar Jan 10 '17 16:01 bokand

we do some sketchy things where we don't grow the box but we do expose more content

Struggling to get my head around this, can you go into more detail? Which box doesn't grow & why's that unusual?

jakearchibald avatar Jan 10 '17 16:01 jakearchibald

So your

element is normally responsible for scrolling (in Chrome). Unlike most scrolling boxes, it doesn't establish its own clip (it's actually overflow:visible IIRC), but rather gets clipped by the "viewport". All other scrollers would have a clipping layer in the compositor that prevents the user from seeing the overflowing content. The body element instead relies on the clipping layer established by the viewport. When the URL bar hides, we grow this clipping layer even though we don't change anything about the underlying content.

The way I've implemented this today is to just disable clipping on all the layers in between the rootScroller's content layer and the viewport. This essentially gives the scroller box the same behavior as

gets today. But if we want to make the rootScroller smaller than the viewport, you'd have to use the clipping layer belonging to the rootScroller (rather than the viewport). We'd then have to generalize the "make clip taller as URL bar hides" behavior to arbitrary scrolling clips so that when the URL bar hides you see more content at the bottom, rather than empty space.

This is complicated further by the recent URL bar sizing change since even at the end of the scroll, we don't resize the layout height. Meaning that the clipping layer's height for the rootScroller needs to be unlinked from the rootScroller's CSS content box, and linked to the viewport height instead. Unfortunately, this is far from trivial.

bokand avatar Jan 10 '17 17:01 bokand

Ahh, so this means the feature also won't work if the scrollable element has a border, or something else that makes the scrollable area not equal 100% of the viewport height?

jakearchibald avatar Jan 11 '17 10:01 jakearchibald

No, not today (unless there's a bug, I actually haven't tried it with a border yet). You could define what to do in that case but I think in general it would require repainting the border on each frame as the top controls hide.

bokand avatar Jan 11 '17 15:01 bokand

Ah, I was interested in trying NonDocumentRootScroller for photos.google.com but our scrollable element is not full height as we have a header so I guess this will not work for now.

jeremys avatar Jan 12 '17 07:01 jeremys

Amp also uses a header. The way they make it work is (as Jake mentioned) by making the header position: fixed and applying content padding to the scroller. (e.g. http://bokand.github.io/totese.html)

bokand avatar Jan 12 '17 14:01 bokand

Ah yeah, that's a good point. I'll see if we can do this easily and if so, we'll try it out. Thanks!

jeremys avatar Jan 12 '17 19:01 jeremys