unoplatform / uno

Build Mobile, Desktop and WebAssembly apps with C# and XAML. Today. Open source and professionally supported.
https://platform.uno
Apache License 2.0
8.6k stars 693 forks source link

[WASM] Element with bottom or right margin in `ScrollViewer` cannot be scrolled to the end #7000

Open dr1rrb opened 2 years ago

dr1rrb commented 2 years ago

Current behavior

If you put an element with a bottom or right margin as Content of a ScrollViewer, then the element won't be fully scrollable.

Expected behavior

🙃

How to reproduce it (as minimally and precisely as possible)

<ScrollViewer Width="1024" Height="1024">
    <Border Width="2048" Height="2048" Margin="50, 256" BorderBrush="Red" BorderThickness="5"/>
</ScrollViewer>

We cannot see the bottom and right borders.

Workaround

Surround the element with a Border without margin:

<ScrollViewer Width="1024" Height="1024">
    <Border>
        <Border Width="2048" Height="2048" Margin="50, 256" BorderBrush="Red" BorderThickness="5"/>
    </Border>
</ScrollViewer>

Works on UWP/WinUI

Yes

Environment

Uno.UI / Uno.UI.WebAssembly / Uno.UI.Skia

NuGet package version(s)

3.10.0-dev.632

Affected platforms

WebAssembly Skia (WPF), Skia (GTK on Linux/macOS/Windows), Skia (Tizen)

IDE

No response

IDE version

No response

Relevant plugins

No response

Anything else we need to know?

Most probably also affects macOS

Work on Android

Not validated on iOS

hawkerm commented 2 years ago

Yeah, just ran into this as well on WASM, think it's the same as #6443. It can be reproduced in the Uno Playground Textblock example too. Just add Margin="0,0,0,512" to the StackPanel at the top.

I can confirm the same workaround of putting a blank border around the StackPanel in the Uno Playground also shows the correct expected behavior.

dr1rrb commented 2 years ago

Investigated the issue today with @agneszitte-nventive ... this is actually an expected behavior of browser: neither the padding of the scrolling parent element nor margin of the child is taken in consideration by the browser when it computes extents (https://stackoverflow.com/questions/11695354/css-right-margin-does-not-work-inside-a-div-with-overflow-scroll).

To fix this issue we do have to insert a wrapping element.

This could be a "managed element" injected dynamically by the SV like the NativeScrollContentPresenter on iOS and Android. It would then require to re-route a lot of properties computed in the SV.UpdateDimensions method (like on iOS and Android).

Another solution would be to inject a "DOM only" div which act as a wrapper on which we would have to set the Extent<Width|Height> as <Width|Height>. This might cause also some issue when we are enumerating the DOM (e.g. here) as we are most probably always assuming that we have only one HTMLElement for one UIElement.

Note: This bug will be fixed by https://github.com/unoplatform/uno/pull/8210 for top and left margin. The issue remain valid only for right and bottom margins on WASM! For those cases, the workaround remains valid.

Stack Overflow
CSS Right Margin Does Not Work Inside a Div With Overflow Scroll
I am trying to make two divs, one inside the other. The inner div is larger than the outer div, the outer div has overflow:scroll, and the inner div has margin:25px. So I do this: #outer { wid...
agneszitte commented 2 years ago

8210 related PR in order for the content margin to be taken into consideration for Skia entirely and top|left margin for WASM.

(Note for WASM: bottom or right margin in ScrollViewer cannot be scrolled to the end still need to be fixed for this issue. Referring to @dr1rrb details above. You can use the easy workaround of surrounding the element with a Border without margin inside the SrollViewer until then.)

agneszitte commented 2 years ago

Note for contributors

These changes will need to be updated when this bottom/right margin issue is fixed for WASM (comments with details left in the code).

(cc @jeromelaban / @dr1rrb )