Coder Social home page Coder Social logo

wicg / visual-viewport Goto Github PK

View Code? Open in Web Editor NEW
175.0 17.0 28.0 195 KB

A proposal to add explicit APIs to the Web for querying and setting the visual viewport

Home Page: https://wicg.github.io/visual-viewport/

License: MIT License

HTML 82.26% JavaScript 17.74%

visual-viewport's Introduction

Visual Viewport API

tl;dr

We propose adding a visualViewport object on window that contains the properties of the visual viewport. We're incubating this idea via the WICG in order to try to make incremental progress on the long-standing problem of exposing features like pinch-zoom to web developers in a rational way. We are working with the CSSWG to eventually get these ideas into the relevant specs as first-class features of the web platform.

Update: The window.visualViewport API has shipped in Chrome M61 (Sept. 2017). Follow crbug issue 635031 for details.

Spec

Draft Spec

Draft Spec

Now merged upstream to CSSOM-View

Background

The mobile web contains two viewports, the Layout and Visual viewport. The Layout viewport is what a page lays out its elements into(*) and the Visual viewport is what is actually visible on the screen. When the user pinch-zooms into the page, the visual viewport shrinks but the layout viewport is unchanged. UI like the on-screen keyboard (OSK) can also shrink the visual viewport without affecting the layout viewport. See this demo to visualize the two viewports. This isn't specified anywhere and implementations vary greatly between browsers.

Currently, several CSSOM scroll properties are relative to the visual viewport (see this for list). Again, there is no spec governing this, but this is how browsers have it implemented today. With this implementation, the dimensions of the visual viewport can be easily determined (For example, window.innerHeight = visual viewport height). However, all other coordinates are generally relative to the layout viewport (e.g. getBoundingClientRects, elementFromPoint, event coordinates, etc.). Having these APIs be mixed is arbitrary and confusing.

This confusion has caused many desktop sites to break when pinch-zoomed or when showing the OSK (see this bug for examples). This is because mobile browsers added new semantics to existing properties, expecting they'd to be invisible to desktop browsers. This becomes a problem as the lines between mobile and desktop blur and features like on-screen keyboard and pinch-zoom make their way to desktops, or when accessing desktop pages from mobile devices.

(*) - This isn't strictly true. In Chrome, the layout viewport is actually the "viewport at minimum scale". While on most well behaving pages this is the box that the page lays out into (i.e. the initial containing block), extra-wide elements or an explicit minimum-scale can change this. More specifically, the layout viewport is what position: fixed elements attach to.

Proposed Plan

We believe the best way forward is to change those remaining CSSOM scroll properties to be relative to the layout viewport. In fact, Chrome did this in M48 but, due to developer feedback, this change was reverted in M49. There was more reliance on this than anticipated.

In order to make this transition we propose adding a new explicit API for the visual viewport. With an explicit API, we could once again change the CSSOM scroll properties to be relative to the layout viewport. This change would make sure existing desktop sites continue to function correctly as new UI features are added. At the same time, it would allow authors to use and customize those features where needed.

The new API is also easy to feature detect and polyfilling this behavior should be fairly straightforward.

Proposed API (v1)

  • Add a visualViewport object on window.
visualViewport = {
    double offsetLeft; // Relative to the layout viewport
    double offsetTop; // and read-only.

    double pageLeft;  // Relative to the document
    double pageTop;  // and read-only.

    double width;  // Read-only and excludes the scrollbars
    double height; // if present. These values give the number
                   // of CSS pixels visible in the visual viewport.
                   // i.e. they shrink as the user zooms in.

    double scale;     // Read-only. The scaling factor applied to
                      // the visual viewport relative to the `ideal
                      // viewport` (size at width=device-width). This
                      // is the same scale as used in the viewport
                      // <meta> tag.
    
    FrozenArray<DOMRect> segments; // Read-only. Returns an array of 
                                   // DOMRects that represent the dimensions 
                                   // of each existing viewport segment.

}
  • Fire a scroll event against window.visualViewport whenever the offsetLeft or offsetTop attributes change.

  • Fire a resize event against window.visualViewport whenever the width or height attributes change.

  • The viewport segments property is currently in development and experimental. Please view the segments explainer for more details.

Example

Here's how an author might use this API to simulate position: device-fixed, which fixes elements to the visual viewport.

Live example from below

<meta name="viewport" content="width=device-width">
<style>
    #layoutViewport {
        position: fixed;
        width: 100%;
        height: 100%;
        visibility: hidden;
    }
    #bottombar {
        position: fixed;
        left: 0px;
        right: 0px;
        bottom: 0px;
        background-color: red;
        transform-origin: left bottom;
        transform: translate(0px, 0px) scale(1);
    }
    #forcescrolling {
        width: 100px;
        height: 2000px;
        background-color: green;
    }
</style>

<body>
    <div id="bottombar">This stays stuck to the visual viewport</div>
    <div id="forcescrolling"></div>
    <div id="layoutViewport"></div>
</body>

<script>
    var bottomBar = document.getElementById('bottombar');
    var viewport = window.visualViewport;
    function viewportHandler() {
        var layoutViewport = document.getElementById('layoutViewport');

        // Since the bar is position: fixed we need to offset it by the visual
        // viewport's offset from the layout viewport origin.
        var offsetLeft = viewport.offsetLeft;
        var offsetTop = viewport.height
                    - layoutViewport.getBoundingClientRect().height
                    + viewport.offsetTop;

        // You could also do this by setting style.left and style.top if you
        // use width: 100% instead.
        bottomBar.style.transform = 'translate(' +
                                    offsetLeft + 'px,' +
                                    offsetTop + 'px) ' +
                                    'scale(' + 1/viewport.scale + ')'
    }
    window.visualViewport.addEventListener('scroll', viewportHandler);
    window.visualViewport.addEventListener('resize', viewportHandler);
</script>

Other Examples

Here's a few other examples you can try out on Chrome Canary today. Be sure to turn on the following flags:

  • chrome://flags/#enable-experimental-web-platform-features (Enable window.visualViewport)
  • chrome://flags/#inert-visual-viewport (Makes window.scrollX|innerWidth and others refer to layout viewport)
  • chrome://flags/#enable-osk-overscroll (Makes keyboard resize visual viewport only)

Links

  • Hide on Zoom: Overlays a position: fixed box in the viewport (e.g. an ad) but hides to improve the UX when the user zooms in.
  • Fixed to keyboard: Keeps a bar (e.g. text formatting toolbar) fixed to the keyboard when it comes up.
  • Fixed to keyboard (No Zoom): Same as above but makes the bar behave like position: fixed rather than position: device-fixed. That is, the bar will stay above the keyboard, but if the user zooms in it will remain in its original position.
  • Fixed to viewport: Simulates position: device-fixed by keeping a bar fixed to the visual viewport.
  • Fixed to viewport (absolute): Uses position: absolute to accomplish a position: sticky type effect that works with pinch-zoom.

Polyfill

TODO: Doesn't work on iOS Safari yet. We've added a rudimentary polyfill that should work across browsers, albeit with worse performance properties (requires polling and ugly hacks). The polyfill itself is visualViewport.js and you can see two examples that use it in the same directory:

visual-viewport's People

Contributors

autokagami avatar bokand avatar budnix avatar darktears avatar dbaron avatar dlibby- avatar dontcallmedom avatar foolip avatar marat-tanalin avatar marcoscaceres avatar rbyers avatar staktrace avatar ststimac avatar tidoust avatar travisleithead avatar ymalik avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

visual-viewport's Issues

Add properties/mechanism to get clientWidth/Height of the visual viewport in unscaled coordinates

I believe the intent of the spec currently is to return lengths/offsets in the layout viewport's coordinate space -- e.g. as I zoom in, the visual viewport's clientWidth and clientHeight properties "shrink".

However, pending the addition of real device-fixed positioning, it's interesting to additionally receive these properties in the coordinate space of the visual viewport (basically just unaffected by pageScale). Since these elements are laid out in the visual viewport's coordinate space, it's more convenient to receive the measurements in the visual viewport's coordinate space directly rather than multiplying by pageScale (and introducing risk of floating point error).

I imagine other scenarios could also benefit from this, but that's the one that immediately pops into my mind for now :)

Should pageScale be a property of the visualViewport, or something else?

pageScale represents a scale ratio between two viewports (visual and layout), and conceptually isn't wholly owned by either.

Similar concepts would include the ratio between layout viewport and physical resolution (in Edge this is represented by devicePixelRatio). Or ideal viewport and physical resolution (devicePixelRatio in Safari). Or layout viewport and ideal viewport (@Viewport {width: 200%}).

My main concern is that as we find and develop interest in these other ratios we'll need to add more and more member properties to the viewport object. Issue #8 talks about the naming of this property which would become more confusing as well if/when these additional ratios are added.

I think this could be more generally solved by a coordinate space conversion API accepting two objects each defining a coordinate space and return a transformation matrix. A partial solution might just return a scale ratio, and maybe a translation.

visualviewportchanged event will be async

The proposal suggests firing a visualviewportchanged event to content. With async panning/zooming, this event will necessarily be async and laggy, just like the scroll event. I don't really have any better ideas at the moment but I wanted to raise an issue for it as I think it merits further discussion. If authors start relying on this event to implement scroll-linked effects then it can result in bad-looking behaviour if the main thread is busy or under load.

changing visual viewport dynamically

As in stackoverflow, I think of changing visual viewport dynamicly. This will be useful in routings, when user changes its position in a SPA.
As I searched a lot, I found out these parameters are read only (visual viewport height and width) but there are changing according to focus or user behavior. So, changing it by code is necessary.
Thanks for any help, or information.

Avaibality of the Visual Viewport API in non-secure contexts

The spec does not mention if the Visual Viewport API is restricted to secure contexts only. Currently, in Chrome the Visual Viewport API is available in non-secure contexts. The W3C spec for secure contexts https://w3c.github.io/webappsec-secure-contexts/#new recommends all new features to be restricted to secure contexts. For existing features which are not widely used but widely implemented, the spec suggests applying this restriction and modifying the specs of the existing feature. What do you think about restricting the Visual Viewport API to secure contexts?

Polyfill calculation of clientWidth/Height uses magic number 15

I think this is maybe supposed to represent the scrollbar width? If so then it will be incorrect at scale values other than 1.0 (since the scrollbar doesn't scale as the user zooms) and also incorrect for any UAs with scrollbars of differing widths.

Feature detection of inert-visual-viewport

As far as I know, the inert-visual-viewport flag just changes the behavior of properties like window.innerWidth and body.scrollX. Is there any preferable/standard way to feature detect which version of the API is present? Possibly, it is the idea to simultaneously release this API change and the viewport API, in which case one could simply check for the presents of window.viewport; or is the idea to first release the viewport API and later on the inert-visual-viewport stuff?

scale shouldn't be spec'd as relative to the ideal viewport

If the developer has modified the layout viewport size (e.g. meta viewport with width=1024 on a device where device-width would have been 384), pageScale should probably reflect the ratio against that adjusted viewport rather than the ideal viewport.

So I think this should instead use "layout viewport", though I'd be interested to make sure we're on the same page with the nastier cases you called out with wide elements and min-scale.

Should scrollTop/Left be relative to document origin rather than layout viewport?

And similarly, visualviewportchanged fire when the position changes relative to the document origin rather than just the layout viewport.

Arguments for document origin:

  1. Better matches the current behavior of pageXOffset/YOffset which these APIs are intended to supplant.
  2. Better matches scenarios involving triggers at particular scroll offsets -- e.g. load in more content when the visual viewport is at 95% of the scrollHeight.
  3. Better matches scenarios involving positioning of non-fixed content, e.g. absolute-positioned modal dialogs that should be centered in the visible region.
  4. Better matches scenarios of scrolling a particular part of the document into view by setting visualViewport.scrollTop
  5. visualviewportchanged is sufficient to detect visual viewport motion relative to the document -- the developer doesn't need to additionally register for the scroll event

Arguments for layout viewport origin:

  1. Better matches scenarios involving positioning of fixed content, e.g. pseudo-device-fixed as your code sample demonstrates.
  2. Better matches "is in view" checks since the offsets can be directly compared against the getBoundingClientRect() of the target, which is also measured relative to the layout viewport origin.
  3. visualviewportchanged can fire more rarely, particularly in usage scenarios with prolonged panning against the edge of the layout viewport.

I lean towards document origin but can see the pros for each side. I'm guessing you may have had additional reasoning for selecting layout viewport origin in your draft -- anything I'm missing above?

Rename `window.view` to `window.visualViewport`

We originally changed this the other way in the context of #35 but this has compatibility issues. There's a non-trivial number of pages using a global view which could cause them to break if we add this. Last I checked visualViewport was unused in the HTTPArchive and so has much less risk.

The original complaint was that it's cumbersome and "java-like". IMO, it actually fits in well with other window properties like sessionStorage, localStorage, and devicePixelRatio. Worst-case, authors can always alias it to something more convenient.

@hexalys, @dbaron, any concerns?

How to get the size of the visual viewport + scrollbars?

The size returned by the Visual Viewport API excludes any space taken up by scrollbars.

What if a web page wants to know the size including the scrollbars? In Firefox, it can currently use window.innerWidth. However, if we switch window.innerWidth to report the size of the layout viewport instead as Chrome has done, that will no longer work; is there a replacement?

cc @mstange @bokand

Please don't call it "viewport"

Everywhere else on the web platform, viewport means (or will soon mean) the layout viewport. For example:

  • meta viewport
  • CSS @Viewport
  • CSS vw,vh units
  • throughout the CSSOM View module

So it would be very confusing for document.viewport to mean something different. People will try to use document.viewport.clientWidth to get the layout viewport width, etc.

Whilst the Chrome team internally uses terminology like layout viewport and visual viewport, and understands the difference, many web developers don't know there are two viewports.

Instead how about:

  • document.visibleArea
  • document.visibleRect
  • document.visualViewport
  • document.zoomRect
  • document.zoomViewport
  • document.zoomArea

Is visualViewport useful for iframes?

We're looking at implementing the Visual Viewport API in Firefox. One thing we noticed was that the spec seems to define visualViewport for iframes as well. Is that useful? My understanding is that iframes don't have distinct notions of visual and layout viewports, since they cannot be zoomed.

Should specify the order of scroll event with respect to other pending scroll event targets

This specification doesn't specify when resize event on visual viewport is dispatched before or after other pending scroll event targets. Because document itself is a pending scroll event target, even specifying the order relative to document's resize event itself is insufficient; there could be more pending scroll event targets such as other scrollable elements in the same document.

Parallel API for layout viewport?

Should there be a parallel API for layout viewport?

A couple reasons this might be interesting:

  1. Enables developers to move away from the ambiguous APIs altogether. Those that do will be explicitly thinking about which viewport they're interested in when consuming the API.
  2. If a developer is really only interested in responding to changes to the layout viewport and not the visual viewport, the "scroll" event is noisier than needed today. It fires when the user has zoomed and is moving the visual viewport around within the layout viewport but not touching the edges of the layout viewport.

Alignment opportunity with foldable and multi-screen proposal

@bokand I wonder if there's an opportunity to align some active proposals with the Visual Viewport API, particularly the Window Segments Enumeration JS API (see also the proposed CSS MQ). +CC @zouhir & @dlibby- Perhaps folds or screen edges within the content area could be exposed as visual viewport information, or general insights from this work could inform that proposal.

Please consider joining our TPAC breakout session to discuss the foldables and multi-screen problem space and alignment opportunities between some active proposals. That will continue discussion from the Second Screen CG meeting; minutes. Thanks!

Should window.visualViewport be null if there's no associated browsing context?

Several Window APIs currently return null when there's no associated browsing context (e.g., this happens when we have a window object corresponding to an iframe element that has been removed from the DOM). See calls to "IsCurrentlyDisplayedInFrame" in LocalDOMWindow.cpp in Blink for examples.

Should window.visualViewport behave the same way? Currently in Blink, it's non-null even when there's no associated browsing context, but the question of whether it should really be null came up in a WebKit code review: https://bugs.webkit.org/show_bug.cgi?id=179385#c7

Definition of scale is not clear

The definition provided for the scale property is not fully clear to me. That's probably because terms like "device pixel" are not well-defined specially when dealing with things like retina displays and automatic OS-level pixel doubling. An example scenario with both pinch-zoom and browser zoom applied would also help clarify the "note".

Code sample is calculating offsetX/Y incorrectly

Currently:

var offsetX = viewport.scrollLeft;
var offsetY = viewport.clientHeight - document.documentElement.clientHeight + viewport.scrollTop;

Should instead be this I think:

var offsetX = viewport.scrollLeft - document.scrollingElement.scrollLeft;
var offsetY = document.documentElement.clientHeight - (viewport.scrollTop - document.scrollingElement.scrollTop) - viewport.clientHeight;

scrollTop and scrollLeft should be clearer about their sign

The definition of scrollTop and scrollLeft could be interpreted as requiring a negative sign in the normal case, although probably not, given that it says "distance" rather than "location" or "offset", since it's described as from the visual viewport to the layout viewport (rather than the other way around).

However, I'm not 100% sure that we can promise that it always should be a nonnegative number, e.g., with touch overscrolling.

This makes me think that it should be described as an offset or location, but with the "from" and the "to" swapped from the way they currently are.

Noticed while reviewing the spec for w3ctag/design-reviews#128 .

Difficult to react to changes in visualViewport

Let's say I wanted to style an element so it appeared "attached" to the visual viewport:

visualViewport.addEventListener('scroll', visualViewportUpdate);
// But it's possible for the viewport to update without scrolling, so
// we need to track resize too:
visualViewport.addEventListener('resize', visualViewportUpdate);
// Neither of those events fire when just pageLeft/pageTop changes
// so we have to listen to something that represents the layout
// viewport too:
window.addEventListener('scroll', visualViewportUpdate);

// Problem: it's now possible for visualViewportUpdate to be called
// three times for a single update, so we need to work around that:

let pendingUpdateHandler = false;

function visualViewportUpdate() {
  // Avoid additional calls within the same frame.
  if (pendingUpdateHandler) return;
  pendingUpdateHandler = true;
  
  // Flip the boolean after we've processed all the events.
  requestAnimationFrame(() => {
    pendingUpdateHandler = false;
  });

  // Handle visual viewport change…
}

This seems pretty tough going, and requires a pretty detailed understanding of the event loop to get right.

Initially I was worried that the events may fire across different visual updates, but I stumbled across #25 which cleared that up.

It feels like we need a single event that fires when any of the properties update, including pageLeft/pageTop, that would turn the above example into:

visualViewport.addEventListener('update', () => {
  // Handle visual viewport change…
});

Use `zoom` instead of `scale`

This terminology is more in line with what web devs use. Scale is what we've used internally to distinguish browser and pinch zooms and it leaked out here. Perhaps having it on the visual viewport is distinguishing enough?

Should we allow setting pageScale?

My initial draft has scrollLeft and scrollTop as writable but pageScale as read-only. On reflection, a writable scroll offset seems pointless without a writable pageScale. We should either make them all read-only or all writable.

How will this interact with non-layout-affecting URL bars?

The proposal in https://github.com/bokand/URLBarSizing is something that Safari already does and we're likely to switch to shortly. We should be explicit about how the two interact.

In short, I think the real problem here is that when we say "layout viewport" we're actually referring to the "position: fixed viewport". We've often said that the visual viewport is bounded by the layout viewport but in that many cases, the layout viewport doesn't have much to do with layout. In the case of the static-layout URL bar, hiding the URL bar will increase the height of the visual viewport and the position: fixed viewport (what we currently call the layout viewport), but not the initial containing block (the "real" layout viewport"). Perhaps we need a shift in terminology...

resize/scroll events on visualviewport are underspecified

The draft spec says e.g. "The user agent must fire an Event named resize on the window.visualViewport object" - but it doesn't provide any details about this event. Does it bubble up to the window? Is it cancelable? Does it have any relatedTarget elements or anything of that nature? Does it extend from UIEvent or Event?

Interaction with window.scrollTo/scrollBy

I think the interaction of the visual viewport with the window.scrollTo/scrollBy is also worth specifying as part of this proposal. The intuitive (to me, anyway) behaviour from the author's point of view would be that calling window.scrollTo also resets the visual viewport to the top-left of the layout viewport, and that calling window.scrollBy leaves the visual viewport as-is relative to the layout viewport.

Polyfill calculation of scale is incorrect

outerWidth is not a safe property to use in polyfills since its value varies per each UA's browser chrome. This calculation is wrong on all non-maximized desktop browsers as a result.

scale not changing with browser zoom on desktop

Preface: I am looking into new ways to detect the Desktop browser zoom with visualViewport. Used to do that efficiently with svg.currentScale but it's no longer working on Chrome. So I wanted to experiment:

As I am testing in Chrome 59 atm. If I zoom in or out, the current visualViewport scale remains at 1. It seems like it shouldn't be the case, and give the proper Browser zoom scale instead.

Per your formula:
physicalWidth = cssWidth / (visualViewport.scale * window.devicePixelRatio)

However with view.scale at 1 while zoomed, I do not get a good equivalent of physicalWidth (outerWidth).

Use Case: Scaling of Bitmap Data

I am experimenting with visualViewport.scale to detect the best resolution needed for bitmap elements (e.g. image or canvas). Currently I multiply the CSS pixel size of an HTML canvas by the factor (visualViewport.scale*window.devicePixelRatio). This accounts for pinch zoom, browser zoom, and physical device pixel ratio. window.devicePixelRatio already contains the physical device pixel ratio multiplied by the browser zoom factor and visualViewport.scale accounts for the pinch zoom. This part works fine on Chrome Canary Win 8.1.

I also use window.innerWidth in order to limit the size of a WebGL canvas (which is an important performance optimization) to the part of the canvas that is actually visible. I tried to replace window.innerWidth by visualViewport.clientWidth, however it turns out that visualViewport.clientWidth is a bit smaller than window.innerWidth (according to the old semantics, i.e. with disabled inert-visual-viewport), which probably accounts for the space of the scroll bar. When pinch zooming-in this difference seems to stay constant and does not scale with the pinch zoom. (Tested emulating a laptop with touch in developer tools on windows 8.1, 54.0.2820.0 canary, enabled enable-experimental-web-platform-features and disabled inert-visual-viewport).

The fixed-to-keyboard.html seems to experience this problem as well: Add a horizontal scroll bar below the red box, (e.g. by increasing the width of the text area in the elements panel of developer tools). Then pinch zooming-in makes the red box move up and no longer stay directly on top of the scroll bar. (Tested emulating a laptop with touch in developer tools on windows 8.1, 54.0.2821.0 canary, enabled enable-experimental-web-platform-features and enabled inert-visual-viewport).

Is emulating `position:device-fixed` really the best use case for this API?

We are about to ship this API in Firefox, and I'm working on coordinating some MDN documentation.

I notice that in this repo, the headline example is emulating position: device-fixed. I wonder, though -- is this the best use case for this API?

In browsers with asynchronous scrolling, which includes both Chrome and Firefox on Android, updating a position property from script in response to scrolling is going to cause flickering during scrolling. (And indeed, if I open the headline example on Android with either Chrome or Firefox, the red box flickers as you scroll.)

It feels strange to me to be encouraging web developers to author websites with flickering elements. I would feel better about promoting examples that don't involve such artifacts.

(On a related note: if we want users to be able to have position: device-fixed behaviour, perhaos a better approach would be to actually implement position: device-fixed, which then doesn't need to cause such a flickering artifact?)

Split visualviewportchanged into scroll/resize?

Currently a visualviewportchanged listener will trigger on every scroll. If a developer is really only interested in observing the size of the visual viewport, this would be more noisy than intended.

definition of scroll event should be clearer about what constitutes a scroll

The definition of the scroll and resize events should be clearer about when, exactly, the scroll event is fired.

In particular, a resize, by definition, changes some edges of the visual viewport. Does the scroll event fire at the same time as a resize event if the resize involves a change to certain edges (the top or left, or something dependent on directionality?) of the viewport, does a scroll event always also fire along with a resize event, or does a scroll event never fire at the same time as a resize event since a resize event implicitly changes some of the edges of the visual viewport?

visual viewport behavior underdefined for detached windows and non-active documents

https://wicg.github.io/visual-viewport/#extensions-to-the-window-interface says:

If the window has a Browsing Context set, return the VisualViewport object associated with it. Otherwise, return null.

But in the spec windows don't have a browsing context set at all. There's a concept of "document's browsing context" which is affected by discarding, and there's a browsing context stored in the settings object which apparently is not affected by discarding (but maybe should be? I just filed whatwg/html#3846 on that). but nothing on Window.

Even apart from this, though, what happens if a script takes a reference to a VisualViewport and then the browsing context involved gets discarded?

And separately, what happens if there is no browsing context discarding, but the document of the Window the VisualViewport comes from stops being active? Concretely, say I grab a VisualViewport from site A, then navigate that browsing context to a different-origin site B. Can I use the VisualViewport I am holding to examine the user's interaction with site B? That would be quite undesirable.

Should window.scrollTo() preserve visualViewport.offset{Left,Top}?

This is less a question about the Visual Viewport API per se, and more about the underlying behaviour of the visual viewport itself, but it came up while investigating a Visual Viewport API web platform test so I thought I'd ask it here.

The test in question sets up a scenario where visualViewport.offsetLeft and offsetTop are nonzero, then performs window.scrollTo() (which has room to perform layout scrolling and does so), and then asserts that offsetLeft and offsetTop are unchanged.

The accompanying comment says:

// The visual viewport should be fully scrolled so even if
// scrollTo does normally "push" the layout viewport with the
// visual, there should be no change to either offsetValue

I'm not fully clear on the intended underlying conceptual model. Under what circumstances is window.scrollTo() expected to preserve the offset of the visual viewport relative to the layout viewport? (The comment suggests to me that it's not "always", though perhaps I'm misreading it.)

In the current Firefox implementation, window.scrollTo() sets both the layout and visual viewport offsets to the specified location (in other words, collapses the relative offset to zero). We chose this because we figured that a page performing window.scrollTo() may be trying to bring the user's attention to an element / section header etc. at the specified location, and so keeping that location out of view by preserving a potentially-large relative offset may be unexpected (kind of like how Element.scrollIntoView() should scroll an element into the visual viewport, which I note is a behaviour Chrome fixed recently).

Before considering a change to the Firefox behaviour, I'd like to understand the underlying conceptual model and the motivation for it better.

cc @bokand

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.