WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
NEW
313802
WKWebView element fullscreen collapses to zero-size viewport when the web view is hosted via SwiftUI `NSViewRepresentable` (or any AutoLayout setup that constrains the WKWebView from above its immediate superview)
https://bugs.webkit.org/show_bug.cgi?id=313802
Summary
WKWebView element fullscreen collapses to zero-size viewport when the web vie...
mitsuru.nakada
Reported
2026-04-30 21:59:55 PDT
Created
attachment 479410
[details]
Screen recording: Direct hosting (broken). The <video> stays at its inline size in the top-left of the fullscreen window. Reproduced on macOS 26.4.1 (build 25E253) with the system WKWebView. The faulty code path in `Source/WebKit/UIProcess/mac/WKFullScreenWindowController.mm` predates this release, so older macOS versions are likely affected as well. ## Description When `WKPreferences.isElementFullscreenEnabled = true` and a `WKWebView` is returned directly from `NSViewRepresentable.makeNSView(context:)` in a SwiftUI app, entering element fullscreen on a `<video>` (or any element) collapses the page viewport to `0×0`. The fullscreen `NSWindow` shown by `WKFullScreenWindowController` is correctly sized to the screen, but the hosted `WKWebView` itself ends up with `bounds = (0, 0, 0, 0)` after the reparenting in `-[WKFullScreenWindowController _continueEnteringFullscreenAfterPostingNotification:]`. Because the page viewport is `0×0`, the user-agent stylesheet rule for `:fullscreen` (`Source/WebCore/css/fullscreen.css`): ```css *|*:not(:root):fullscreen { position: fixed !important; inset: 0 !important; width: 100% !important; height: 100% !important; ... } ``` evaluates `100%` against the zero viewport and produces a zero-sized fullscreen element. The `<video>` retains its previous inline render box, which leaves it anchored to the top-left of the otherwise empty fullscreen window. If the video was paused before fullscreen entry, no frame is drawn at all and only the audio track plays. The system console emits messages of the form:
> Attempting to update all DD element frames, but the bounds or contentsRect > are invalid. Bounds: X: 0.00 Y: 0.00, W: 0.00 H: 0.00, contentsRect: ...
The same content works correctly in Safari, and works correctly in WKWebView when the WKWebView is **not** directly governed by AutoLayout from an ancestor (see Workaround below). ## Steps to reproduce 1. Clone
https://github.com/mnkd/wkwebview-element-fullscreen-repro
2. `swift run` (or open `Package.swift` in Xcode and Run) 3. Wait for the Big Buck Bunny clip to load 4. Right-click the video → **Enter Full Screen** 5. Observe: the video stays at its inline (720px) size in the top-left of an otherwise black fullscreen window 6. Toggle the segmented control to **Container NSView (workaround)** at the top of the window and repeat step 4 → the video now fills the screen as expected ## Expected behavior The `<video>` element fills the fullscreen window, identical to Safari and to the workaround mode. ## Actual behavior The `WKWebView` viewport is `0×0` while in element fullscreen, so UA-stylesheet sizing yields a `0×0` `:fullscreen` element. The `<video>` element draws at its previous inline size from the top-left corner of the fullscreen window. ## Analysis `Source/WebKit/UIProcess/mac/WKFullScreenWindowController.mm` (revision `4b9916df`, 2026-04-30 main HEAD): - `_continueEnteringFullscreenAfterPostingNotification:` (L368) reparents the `WKWebView` from its host hierarchy into the fullscreen window's `_clipView` and resizes it via `[webView setFrame:NSInsetRect(contentView.bounds, ...)]` (L427). - Before reparenting, `_saveConstraintsOf:` (L944) is called on `webView.superview`, but only captures constraints stored in `superview.constraints`, filtering out `NSAutoresizingMaskLayoutConstraint`. - `_replaceView:with:` (L932) installs a placeholder using `frame` and `autoresizingMask` only. If the original WKWebView was governed by AutoLayout from a higher ancestor (which is what SwiftUI's `_NSHostingView` does), the relevant constraints are not captured by `_saveConstraintsOf:` and the placeholder does not satisfy them either. The result is that AppKit collapses the WKWebView's bounds when it is removed from its original position in the hierarchy. ## Workaround Wrap the `WKWebView` in a plain container `NSView`, set `translatesAutoresizingMaskIntoConstraints = true` and `autoresizingMask = [.width, .height]` on the `WKWebView`, and have SwiftUI size the container instead of the `WKWebView` directly. The `WKWebView` then uses frame-based layout and survives the reparenting unchanged. The repro project demonstrates both the broken and working configurations side by side. ## Suggested fix (in priority order) 1. **Internal wrapper view inside `WKWebView`.** Have the public `WKWebView` `NSView` keep a single inner content view that owns the rendering surface, and reparent the inner view into the fullscreen window instead of the public `WKWebView`. The public view stays in the host's AutoLayout hierarchy, so client constraints are never disturbed. This is what the workaround does manually. 2. **Walk the ancestor chain in `_saveConstraintsOf:`.** Capture every active `NSLayoutConstraint` whose `firstItem` or `secondItem` reaches the `WKWebView` (or any of its descendants) from any ancestor up to the host window's content view, and reactivate them on exit. Higher-fidelity than today's single-level capture. 3. **Document the requirement.** Update the doc comments on `WKWebView.fullscreenState` and `WKPreferences.elementFullscreenEnabled` to say that the WKWebView must not be the direct AutoLayout-managed view and must be hostable in a way that tolerates reparenting (i.e. inside a container with autoresizing). Lowest cost; useful even alongside a later code fix. ## Related - Apple Developer Forums, "WkWebView breaks with isElementEnabled": <
https://developer.apple.com/forums/thread/768688
> (Same symptom, OP found the autoresizing-wrapper workaround. Marked "Solved" by the OP's workaround, not by an Apple-side fix.) - Apple Developer Forums, "WKWebView: Fullscreen API very unreliable": <
https://developer.apple.com/forums/thread/766736
> (Different but adjacent fullscreen bug, fixed in iOS 18.3 / macOS 15.3 as FB15553776.) ## Attachments - Repro repository:
https://github.com/mnkd/wkwebview-element-fullscreen-repro
- Broken behavior recording:
https://github.com/mnkd/wkwebview-element-fullscreen-repro/blob/main/media/broken.mov
- Workaround recording:
https://github.com/mnkd/wkwebview-element-fullscreen-repro/blob/main/media/workaround.mov
Attachments
Screen recording: Direct hosting (broken). The <video> stays at its inline size in the top-left of the fullscreen window.
(16.86 MB, video/quicktime)
2026-04-30 21:59 PDT
,
mitsuru.nakada
no flags
Details
Screen recording: Container NSView wrapper (workaround). The <video> fills the fullscreen window as expected.
(27.07 MB, video/quicktime)
2026-04-30 22:00 PDT
,
mitsuru.nakada
no flags
Details
View All
Add attachment
proposed patch, testcase, etc.
mitsuru.nakada
Comment 1
2026-04-30 22:00:29 PDT
Created
attachment 479411
[details]
Screen recording: Container NSView wrapper (workaround). The <video> fills the fullscreen window as expected.
Radar WebKit Bug Importer
Comment 2
2026-05-01 19:58:56 PDT
<
rdar://problem/176069723
>
Frédéric Wang Nélar
Comment 3
2026-10-15 09:41:40 PDT
From the description, I understand this does not happen in Safari, only for apps using WKWebView.
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug