MicrosoftEdge / MicrosoftEdge/WebView2Feedback

[Problem/Bug]: Hidden WPF WebView2 reports a ~70x39 page viewport on runtime 152 (was large on 151)

Open
#5,689 1 comment 0 reactions 2 assignees View on GitHub

@anuragkumar878 is already working on this.

Since Sep 3, 2026.

bug regression
Dominant language
PowerShell
Stars
526
Forks
67
PR merge metrics
No merged PRs in 30d

Description

What happened?

Our WPF application creates a new WebView2 control for each user session. The control is
constructed with Visibility = Visibility.Hidden, added to the visual tree, initialized with
EnsureCoreWebView2Async, and then navigated — all before it is ever made visible.

While the control has never been visible, the page's layout viewport does not reflect the
control's size on either runtime. What changed between 151 and 152 is the size it does
report:

Runtime 151.0.4129.107 Runtime 152.0.4191.53
While never visible innerWidth=1281 innerHeight=1392 clientWidth=1281 innerWidth=70 innerHeight=39 clientWidth=55
After first made visible innerWidth=960 innerHeight=327 clientWidth=960 innerWidth=960 innerHeight=327 clientWidth=960
Control size throughout 960 DIP wide 960 DIP wide

On 151 the reported viewport was large, so pages that measure their own layout during load
produced usable results even though the number was not the control's size. On 152 the reported
viewport is ~70 x 39, so those pages lay out for a 70 px window. Note that clientWidth is 55
on 152 — the 70 px viewport minus a 15 px scrollbar — which is the value page code actually
reads when sizing content.

Both runtimes deliver the control's real size only when the control is first made visible, at
which point the page receives a resize event.

Expected: the page's viewport reflects the control's arranged size while the control is
hidden, or at minimum does not default to a size small enough to break layout.

Actual: the page's viewport is ~70 x 39 until the control is shown for the first time.

Other things we found while narrowing this down:

  • The WPF element is sized explicitly and its ActualWidth/ActualHeight are correct
    throughout. Only the page's viewport is wrong, which suggests the control's size is not
    reaching the CoreWebView2 until the control becomes visible. The attached sample logs both
    values on the same line so the difference is visible directly.
  • UpdateLayout() on the container does not help.
  • Setting Visibility = Visible and back to Hidden within a single dispatcher operation does
    not help. The size only becomes correct if a render pass completes while the control is
    visible, which is consistent with the bounds being pushed from OnWindowPositionChanged
    an HwndHost render-time callback.
  • Once the control has been shown once, its page viewport stays correct for the remainder of
    that control's lifetime.
  • The 70 x 39 value matches what we see on affected production machines, which have different
    resolutions and display scaling from the machine used to run the attached sample.
  • Not applicable to the Edge or Chrome browser: the scenario depends on a host-embedded control
    whose visibility and bounds are assigned by the host and which has never been made visible.
    There is no direct equivalent in a standalone browser tab, so this was not tested there rather
    than tested and found working.

Impact: any page logic that reads the viewport during load is affected — CSS media queries
evaluated at load time, and JavaScript that measures layout. In our case a load-time
measurement was applied to the page's layout and never recalculated, so the page remained
sized for a 70 px viewport even after the control became visible.

Workaround: defer any viewport-dependent work until after the first resize event.

Importance

Blocking. My app's basic functions are not working due to this issue.

Runtime Channel

Stable release (WebView2 Runtime)

Runtime Version

152.0.4191.53

SDK Version

1.0.2535.41 *also reproduces w/ SDK 1.0.1210.39

Framework

WPF

Operating System

Windows 11

OS Version

26200.9106

Repro steps

The sample is five files in one folder (attachment upload was failing, so the source is inline
below). Because the control is hidden the page cannot be observed on screen, so it posts its own
viewport back to the host; the host logs that next to the control's WPF dimensions and the
runtime version actually in use.

Steps

  • Save the five files below into an empty folder.

  • Start the app, pinning the runtime under test:

    cd path\to\WebView2HiddenSizeRepro
    $env:WEBVIEW2_BROWSER_EXECUTABLE_FOLDER = "<runtime folder>\152.0.4191.53"
    dotnet run -f net8.0-windows
    
  • Read the first page reports line in the log.

  • Click Make browser visible and read the resize line that follows.

  • Repeat against 151.0.4129.107 and compare the first line.

Expected (behaviour on 151.0.4129.107): the first line reports a large viewport
(innerWidth=1281 innerHeight=1392 clientWidth=1281 in our run) while the control is 960 DIP
wide. Not the control's size, but large enough that content-measuring pages behave.

Actual (152.0.4191.53): the first line reports innerWidth=70 innerHeight=39 clientWidth=55
while the control's dimensions on that same line are correct at 960 DIP wide.

On both runtimes, clicking Make browser visible then produces a resize line reporting
innerWidth=960 innerHeight=327 clientWidth=960, confirming the control was sized correctly all
along and only the page's viewport was wrong.

Sample source

WebView2HiddenSizeRepro.csproj
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <!-- net8.0-windows is the quickest to run; net48 matches the framework our production host uses. -->
    <TargetFrameworks>net8.0-windows;net48</TargetFrameworks>
    <UseWPF>true</UseWPF>
    <RootNamespace>WebView2HiddenSizeRepro</RootNamespace>
    <AssemblyName>WebView2HiddenSizeRepro</AssemblyName>
    <Nullable>disable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Web.WebView2" Version="1.0.2535.41" />
  </ItemGroup>

</Project>
App.xaml
<Application x:Class="WebView2HiddenSizeRepro.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             StartupUri="MainWindow.xaml" />
App.xaml.cs
using System.Windows;

namespace WebView2HiddenSizeRepro
{
      public partial class App : Application
      {
      }
}
MainWindow.xaml
<Window x:Class="WebView2HiddenSizeRepro.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="WebView2 hidden-size repro" Width="1000" Height="700">
      <Grid Margin="12">
              <Grid.RowDefinitions>
                      <RowDefinition Height="Auto" />
                      <RowDefinition Height="Auto" />
                      <RowDefinition Height="Auto" />
                      <RowDefinition Height="*" />
              </Grid.RowDefinitions>

              <StackPanel Grid.Row="0" Orientation="Horizontal">
                      <Button x:Name="ShowButton" Content="Make browser visible" Padding="8,4" Click="ShowButton_C
                      <TextBlock x:Name="HostSize" Margin="12,6,0,0" />
              </StackPanel>

              <TextBlock Grid.Row="1" Margin="0,10,0,0" TextWrapping="Wrap" Foreground="DimGray"
                         Text="The browser is created with Visibility=Hidden, initialized, and navigated before itshown. Because it is hidden, the page reports its own viewport back to this window instead of being observed on screen." />

              <ListBox x:Name="Log" Grid.Row="2" Height="220" Margin="0,10,0,0" FontFamily="Consolas" FontSize="12

              <!-- The browser is added here in code-behind. -->
              <StackPanel x:Name="BrowserHost" Grid.Row="3" Margin="0,12,0,0" />
      </Grid>
</Window>
MainWindow.xaml.cs
using System;
using System.Windows;
using Microsoft.Web.WebView2.Wpf;

namespace WebView2HiddenSizeRepro
{
      public partial class MainWindow : Window
      {
              private WebView2 _browser;

              /// <summary>
              /// The page reports its own viewport, because a hidden browser cannot be observed on screen.
              /// </summary>
              private const string Page = @"
<!DOCTYPE html>
<html><body style='font: 14px sans-serif'>
<p>If you can read this, the browser is visible.</p>
<script>
  function report(reason) {
    window.chrome.webview.postMessage(
      reason +
      ': innerWidth=' + window.innerWidth +
      ' innerHeight=' + window.innerHeight +
      ' clientWidth=' + document.documentElement.clientWidth +
      ' dpr=' + window.devicePixelRatio);
  }
  window.addEventListener('resize', function () { report('resize'); });
  report('initial');
</script>
</body></html>";

              public MainWindow()
              {
                      InitializeComponent();
                      Loaded += MainWindow_Loaded;
              }

              private async void MainWindow_Loaded(object sender, RoutedEventArgs e)
              {
                      // The host panel is already laid out, so its size is known and correct before the browser i
                      HostSize.Text = $"Host panel: {BrowserHost.ActualWidth} x {BrowserHost.ActualHeight} DIP";

                      _browser = new WebView2
                      {
                              Visibility = Visibility.Hidden,   // never visible before navigation - this is what
                              Width = BrowserHost.ActualWidth,
                              Height = BrowserHost.ActualHeight,

                              // Our production host also pins these. They are not required to reproduce.
                              MinWidth = BrowserHost.ActualWidth,
                              MaxWidth = BrowserHost.ActualWidth,
                      };

                      BrowserHost.Children.Add(_browser);

                      await _browser.EnsureCoreWebView2Async();

                      Write($"runtime {_browser.CoreWebView2.Environment.BrowserVersionString}");

                      _browser.WebMessageReceived += (_, args) => Write(
                              $"page reports {args.TryGetWebMessageAsString()} " +
                              $"| control {_browser.ActualWidth} x {_browser.ActualHeight} DIP, " +
                              $"Visibility={_browser.Visibility}, IsVisible={_browser.IsVisible}");

                      _browser.NavigateToString(Page);
              }

              private void ShowButton_Click(object sender, RoutedEventArgs e)
              {
                      _browser.Visibility = Visibility.Visible;
                      Write("set Visibility=Visible");
              }

              private void Write(string message)
              {
                      Log.Items.Insert(0, $"{DateTime.Now:HH:mm:ss.fff}  {message}");
              }
      }
}
Repros in Edge Browser

No, issue does not reproduce in the corresponding Edge version

Regression

Regression in newer Runtime

Last working version (if regression)

Runtime 151.0.4129.107, SDK 1.0.2535.41 (also SDK 1.0.1210.39)

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.