w3c / csswg-drafts

CSS Working Group Editor Drafts
https://drafts.csswg.org/
Other
4.48k stars 661 forks source link

[css-viewport] Help me bikeshed "layout viewport" #4819

Open smfr opened 4 years ago

smfr commented 4 years ago

CSS Position says:

Fixed positioning is similar to absolute positioning. The only difference is that for a fixed positioned box, the containing block is established by the viewport

That "established by the viewport" has to change in CSS Viewport to mean what implementors currently call the "layout viewport", but "layout viewport" is a sucky name (it's not used for most layout, and it's not really a viewport).

CSS Viewport could define something like "fixed position containing block", or say that the containing block for fixed position is established by the THING, but I need a name for THING.

smfr commented 4 years ago

Maybe @chrishtr has ideas.

Crissov commented 4 years ago

Canvas

frivoal commented 4 years ago

cc @pp-koch

smfr commented 4 years ago

Canvas

It's not the canvas; the origin of the layout viewport changes with scrolling. At some future time we'll probably spec it as the box that getBoundingClientRect is relative to, and its origin will become the scroll position.

bradkemper commented 4 years ago

Viewport scroll view, or viewport scroll text?

pp-koch commented 4 years ago

Since Florian called on me ...

I do not understand the problem. Why isn't the layout viewport a viewport? Especially combined with pinch zoom, it is (you can zoom out until the entire layout viewport fits in the visual viewport, for instance).

Also, why isn't the layout viewport used for layout? After all, it is the outermost containing block for your layout; the width: auto for the HTML element is relative to the layout viewport, and the HTML element is the basis for any CSS layout.

So I'd like to understand the problem better before commenting.

And a bit of history: back in 2010 I needed names for what we now call the layout and visual viewport, since I was the first one to systematically describe them in public articles. Anne van Kesteren told me that the internal names within Opera were layout and visual viewport, and I ran with them and stuck to them. (As far as I know I am responsible for the spread of these names.)

smfr commented 4 years ago

Since Florian called on me ...

I do not understand the problem. Why isn't the layout viewport a viewport? Especially combined with pinch zoom, it is (you can zoom out until the entire layout viewport fits in the visual viewport, for instance).

Also, why isn't the layout viewport used for layout? After all, it is the outermost containing block for your layout; the width: auto for the HTML element is relative to the layout viewport, and the HTML element is the basis for any CSS layout.

The initial containing block (which is "stuck" at the top of the document) is the one that's used for layout. The "layout viewport" moves when you scroll, and is only used for positioning fixed-position elements. It's also not really a viewport, because as soon as you zoom in, not all of the layout viewport is visible to the user.

If the page is not zoomed (zoom scale == 1) then the layout viewport is the same as the old and poorly named "client rect" used in getBoundingClientRect and friends. Actually, going forward, it's probably true that the layout viewport and the "client rect" will remain the same even under zooming.

pp-koch commented 4 years ago

Good reply; however,

1) When you rewrite a meta viewport tag, the browser resizes the initial containing block as well, and the layout is adjusted. That argues in favour of the layout viewport and the initial containing block being the same (minus scrolling).

2) You can only prove that the layout viewport scrolls by inspecting the behaviour of a fixed element. If fixed elements were placed relative to the document or the visual viewport (and both happened in the past), it is impossible to prove that the layout viewport scrolls, and therefore it doesn't scroll (sort-of, if you understand what I mean), and therefore it's exactly equal to the initial containing block.

So while it is technically possible to distinguish between the initial containing block and the layout viewports, browsers don't actually do so in case #1, and case #2 shows that the only reason we say the layout viewport 'scrolls' is because of the current implementation of position: fixed, the definition of which is exactly why you want to change the name 'layout viewport.'

And now I have managed to twirl myself into a logical loop that I can't figure my way out of. So let's leave it at stating that the two started out as one and the same.

On a different level, I am unconvinced that it is a good idea to change well-known names of things. As far as I can see, either web developers will ignore the name change and continue to call it layout viewport, which will lead to confusion, or they will follow the name change but not understand that it was called layout viewport in the past, also leading to confusion.

W3C has had plenty of time to standardize the viewports, but didn't, even though back in 2010-3 the browsers (and I) needed some firm guidance. Thus it left the de-facto standardization of the viewports to browser vendors (and, in a small way, me; I spent about a year mailing browser vendors to get them all to align on the JavaScript properties). I feel that it's a bit late to change the entire nomenclature.

But that's just my opinion, and because of my long history with the viewports I am probably a bit defensive, and certainly very happy with the status quo.

smfr commented 4 years ago

Good reply; however,

  1. When you rewrite a meta viewport tag, the browser resizes the initial containing block as well, and the layout is adjusted. That argues in favour of the layout viewport and the initial containing block being the same (minus scrolling).

This is true.

  1. You can only prove that the layout viewport scrolls by inspecting the behaviour of a fixed element. If fixed elements were placed relative to the document or the visual viewport (and both happened in the past), it is impossible to prove that the layout viewport scrolls, and therefore it doesn't scroll (sort-of, if you understand what I mean), and therefore it's exactly equal to the initial containing block.

So while it is technically possible to distinguish between the initial containing block and the layout viewports, browsers don't actually do so in case #1, and case #2 shows that the only reason we say the layout viewport 'scrolls' is because of the current implementation of position: fixed, the definition of which is exactly why you want to change the name 'layout viewport.'

And now I have managed to twirl myself into a logical loop that I can't figure my way out of. So let's leave it at stating that the two started out as one and the same.

I had problems following this argument :)

You can prove the layout viewport scrolls by comparing getBoundingClientRect() on a position:fixed vs a position:absolute element across a scroll position change.

On a different level, I am unconvinced that it is a good idea to change well-known names of things. As far as I can see, either web developers will ignore the name change and continue to call it layout viewport, which will lead to confusion, or they will follow the name change but not understand that it was called layout viewport in the past, also leading to confusion.

Do web developers really think about "layout viewport" now? They are familiar with "client" coordinates presumably, and with "initial containing block" though not necessarily with that name. But I've never seen "layout viewport" used in a non browser-implementation context.

W3C has had plenty of time to standardize the viewports, but didn't, even though back in 2010-3 the browsers (and I) needed some firm guidance. Thus it left the de-facto standardization of the viewports to browser vendors (and, in a small way, me; I spent about a year mailing browser vendors to get them all to align on the JavaScript properties). I feel that it's a bit late to change the entire nomenclature.

But that's just my opinion, and because of my long history with the viewports I am probably a bit defensive, and certainly very happy with the status quo.

Maybe the real question here is whether we should just call it the "client rect" because that's what it is, much as I hate the name.

frivoal commented 4 years ago

Do web developers really think about "layout viewport" now? They are familiar with "client" coordinates presumably, and with "initial containing block" though not necessarily with that name. But I've never seen "layout viewport" used in a non browser-implementation context.

@pp-koch has been teaching it under this name for a while now, and he has a bit of an audience.

A bit of googling suggests he's not alone using these words, with other sources including MDN or Jake archibald. Doesn't necessarily mean it is the dominant terminology, but it has some presence.

pp-koch commented 4 years ago

Thanks, Florian. I intended to do such a search, but forgot.

Let me ask another question: Are there any articles that describe the layout viewport, but call it by a different name? I don't know of any, but then I never searched for it, since I already had a name.

If there is none, I feel it would be fair to say that "layout viewport" is the only current term, and that it is in fairly wide use among those few who actually discuss these matters.

karlcow commented 4 years ago

in 5.1.2. Viewport-percentage Lengths: the vw, vh, vmin, vmax units

The viewport-percentage lengths are relative to the size of the initial containing block. When the height or width of the initial containing block is changed, they are scaled accordingly. However, any scrollbars are assumed not to exist.

in the viewport

User agents for continuous media generally offer users a viewport (a window or other viewing area on the screen) through which users consult a document. User agents may change the document’s layout when the viewport is resized (see the initial containing block).

When the viewport is smaller than the area of the canvas on which the document is rendered, the user agent should offer a scrolling mechanism.

There is at most one viewport per canvas, but user agents may render to more than one canvas (i.e., provide different views of the same document).

ok let's see what is said about canvas.

the canvas

For all media, the term canvas describes "the space where the formatting structure is rendered." The canvas is infinite for each dimension of the space, but rendering generally occurs within a finite region of the canvas, established by the user agent according to the target medium. For instance, user agents rendering to a screen generally impose a minimum width and choose an initial width based on the dimensions of the viewport. User agents rendering to a page generally impose width and height constraints. Aural user agents may impose limits in audio space, but not in time.

And initial containing block

The containing block in which the root element lives is a rectangle called the initial containing block . For continuous media, it has the dimensions of the viewport and is anchored at the canvas origin;

and

If the element has 'position: fixed', the containing block is established by the viewport in the case of continuous media or the page area in the case of paged media.

and in 10.3.7. Absolutely positioned, non-replaced elements.

For the purposes of calculating the static position, the containing block of fixed positioned elements is the initial containing block instead of the viewport, and all scrollable boxes should be assumed to be scrolled to their origin.

There is also the Visual Viewport API by @bokand The intro says:

Some user agents have split their viewport into two conceptual viewports, colloquially known as the visual and layout viewports. This separation is useful in enabling a user agent (UA) with a small screen to allow the user to zoom in on parts of the page without causing the page to respond, for example, by obscuring the user's view with position: fixed elements. As another example, mobile UAs often provide an on-screen keyboard (OSK) for user input. Without the visual/layout split, a position: fixed element would be pushed up when the OSK is shown, obscuring the user's view. Informally, the layout viewport is what the web page uses when laying out its UI while the visual viewport is the box on the page that the user can currently see, accounting for transient UI features like pinch-zoom and the OSK.

The existing APIs provided by UAs are ambiguous about which viewport they're relative to. For example, document.scrollingElement.scrollLeft returns the scroll position of the visual viewport while document.scrollingElement.clientWidth returns the width of the layout viewport. getBoundingClientRect returns the rect relative to the layout viewport while positioning non-fixed elements relative to the layout viewport is difficult. This makes building UI that responds to scrolls across mobile and desktop UAs difficult. Worse still, there's no way for the developer to be notified when the visual viewport changes. For example, the only way to know when the user has zoomed is to poll or listen to touch events and continually check window.innerWidth.

The Visual Viewport API is designed to provide an explicit mechanism for developers to query and potentially modify the properties of the visual viewport. It also introduces events that allow the page to listen for changes in the visual viewport, allowing UX that explicitly wants to react to these changes to do so. For example, the page could keep a small text-formatting bar above the OSK.

in 3.2 The VisualViewport interface

A VisualViewport object represents the visual viewport for a window's browsing context. Each window on a page will have a unique VisualViewport object. This object represents the properties of the window's associated Document's browsing context when that Document is fully active.

bokand commented 4 years ago

FWIW, when I wrote up a viewports explainer I also used "fixed viewport" rather than layout.

"Layout viewport" doesn't match the initial containing block size - at least not in Blink. The behavior (I believe this varies between browsers though, at least when I last checked years ago) is that position: fixed elements attach to "the box that is the visual viewport at minimum scale". This ensures:

The latter point in particular makes the scrolling model clearer, the "layout" viewport is a scroller inside the visual viewport scroller.

Given that, consider a case like this:

<meta name="viewport" content="width=1000; minimum-scale=2">
<div style="position: fixed; width:100%"></div>

In this case, the layout size is 1000px but it'd be a poor choice to make the fixed div 1000px because the user will never be able to see the whole thing in the viewport. Thus the box that contains fixed elements is the minimum-scale box rather than layout.

Note also, (again, maybe Blink specific) the minimum-scale can be affected outside of the viewport meta:

<meta name="viewport" content="width=1000">
<div style="width:2000px"></div>

The minimum scale in this case will be 0.5 and fixed elements will be pushed out to attach to the larger box. Whether that's the right behavior, I'm not sure.

smfr commented 4 years ago

I don't think "fixed viewport" is a good name to use, because it's very easily interpreted as "a viewport that does not change".

karlcow commented 4 years ago

It is somehow a kind of "computed viewport", aka the results of things once everything has been computed in the remaining visible rendered space