microsoft / microsoft-ui-xaml

Windows UI Library: the latest Windows 10 native controls and Fluent styles for your applications
MIT License
6.25k stars 671 forks source link

`TextBlock.LineHeight` behaves unexpectedly #9528

Open MartyIX opened 4 months ago

MartyIX commented 4 months ago

Describe the bug

TextBlock.LineHeight does not vertically center text with respect to the available line height.

Steps to reproduce the bug

Use the following snippet demonstrates to demonstrate the unexpected TextBlock.LineHeight behavior:

<Border Background="DimGray">
    <TextBlock LineHeight="50" Text="BEHAVIOR DIFFERENCE" />
</Border>

The snippet gets rendered in the following way:

image

but I would expect the result to be more like this:

image

note: I created a repository for it here: https://github.com/MartyIX/LineHeight202404/ (The important part is here: https://github.com/MartyIX/LineHeight202404/blob/main/MainWindow.xaml)

Now my expectation was that BEHAVIOR DIFFERENCE text would be vertically aligned to the center of the gray box. So my expectation was that the behavior would be the same as how HTML & CSS works: https://playcode.io/1828826 where similar code gets rendered as:

image

(HTML is <div class="label3">BEHAVIOR DIFFERENCE</div> and the corresponding CSS is .label3 { color: brown; background-color: lightgray; line-height: 40px; })

Expected behavior

I would expect the text in TextBlock to be vertically aligned to the center of the line where the text is located.

In the end, I'm not sure if it is a bug or if it works as intended.

Screenshots

No response

NuGet package version

None

Windows version

No response

Additional context

Tested using: <PackageReference Include="Microsoft.WindowsAppSDK" Version="1.4.230913002" /> (see https://github.com/MartyIX/LineHeight202404/blob/c6a2ed2b0a0c6acdeebcfa09550b7bb5e5270b79/LineHeight202404.csproj#L26)

I have filed the https://github.com/dotnet/maui/issues/21705 issue but then I decided to try in a vanilla WinUI app to understand who is responsible for the behavior.

github-actions[bot] commented 4 months ago

Hi I'm an AI powered bot that finds similar issues based off the issue title.

Please view the issues below to see if they solve your problem, and if the issue describes your problem please consider closing this one. Thank you!

Open similar issues:

Closed similar issues:

Note: You can give me feedback by thumbs upping or thumbs downing this comment.

MartyIX commented 4 months ago

@codendone Do i understand right that this is a bug?

codendone commented 4 months ago

@MartyIX I expect this is by design, at least for the current design. The WPF documentation has more information about LineHeight behavior, including this important line:

In addition to this property, the layout of lines in a TextBlock is affected by its LineStackingStrategy property.

The LineStackingStrategy does have an impact here. I don't know if there are additional properties currently to manage this or if this would be a feature request.

MartyIX commented 4 months ago

I tried various variants:

<?xml version="1.0" encoding="utf-8"?>
<Window
    x:Class="LineHeight202404.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:LineHeight202404"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <ScrollView>
        <StackPanel Orientation="Vertical" HorizontalAlignment="Center" VerticalAlignment="Center">

            <Border Background="DimGray" Height="Auto">
                <TextBlock Text="Test text #1: TextLineBounds=Tight" LineHeight="50" TextLineBounds="Tight" SelectionHighlightColor="AliceBlue" 
                           IsTextSelectionEnabled="True" Padding="0" Foreground="Black" />
            </Border>

            <Border Background="LightBlue" Height="Auto">
                <TextBlock Text="Test text #2: TextLineBounds=Full" LineHeight="50" TextLineBounds="Full" SelectionHighlightColor="AliceBlue" 
                           IsTextSelectionEnabled="True" Padding="0" Foreground="Black" />
            </Border>

            <Border Background="DimGray" Height="Auto">
                <TextBlock Text="Test text #3: TextLineBounds=TrimToBaseline" LineHeight="50" TextLineBounds="TrimToBaseline" SelectionHighlightColor="AliceBlue" 
                           IsTextSelectionEnabled="True" Padding="0" Foreground="Black" />
            </Border>

            <Border Background="LightBlue" Height="Auto">
                <TextBlock Text="Test text #4: TextLineBounds=TrimToCapHeight" LineHeight="50" TextLineBounds="TrimToCapHeight" SelectionHighlightColor="AliceBlue" 
                           IsTextSelectionEnabled="True" Padding="0" Foreground="Black" />
            </Border>

            <Border Background="DimGray" Height="Auto">
                <TextBlock Text="Test text #5: LineStackingStrategy=BaselineToBaseline" LineHeight="50" LineStackingStrategy="BaselineToBaseline" SelectionHighlightColor="AliceBlue"
                           IsTextSelectionEnabled="True" Padding="0" Foreground="Black" />
            </Border>

            <Border Background="Firebrick" Height="Auto">
                <TextBlock Text="Test text #5b: LineStackingStrategy=BaselineToBaseline, Padding=0,5" Padding="0,5" LineHeight="50" LineStackingStrategy="BaselineToBaseline" 
                           SelectionHighlightColor="AliceBlue" IsTextSelectionEnabled="True" Foreground="Black" />
            </Border>

            <Border Background="Aquamarine" Height="Auto">
                <TextBlock Padding="0,5" LineHeight="50" LineStackingStrategy="BaselineToBaseline" 
                           SelectionHighlightColor="AliceBlue" IsTextSelectionEnabled="True" Foreground="Black">
                    Test text #5c: LineStackingStrategy=BaselineToBaseline, Padding=0,5, multiline
                     <LineBreak/>
                    Second line
                </TextBlock>
            </Border>

            <Border Background="LightBlue" Height="Auto">
                <TextBlock Text="Test text #6: LineStackingStrategy=BlockLineHeight" LineHeight="50" LineStackingStrategy="BlockLineHeight" SelectionHighlightColor="AliceBlue" 
                           IsTextSelectionEnabled="True" Padding="0" Foreground="Black" />
            </Border>

            <Border Background="LightPink" Height="Auto">
                <TextBlock Text="Test text #7: LineStackingStrategy=MaxHeight" LineHeight="50" LineStackingStrategy="MaxHeight" SelectionHighlightColor="AliceBlue" 
                           IsTextSelectionEnabled="True" Padding="0" Foreground="Black" />
            </Border>

            <Border Background="LightGray" Height="Auto">
                <TextBlock TextWrapping="Wrap" LineHeight="50" LineStackingStrategy="MaxHeight" SelectionHighlightColor="AliceBlue" 
                           IsTextSelectionEnabled="True" Padding="0" Foreground="Black">
                    Test text #8: TextWrapping=Wrap
                     <LineBreak/>
                    Second line
                </TextBlock>
            </Border>

            <Border Background="LightBlue" Height="Auto">
                <TextBlock TextWrapping="Wrap" LineHeight="50" LineStackingStrategy="MaxHeight" SelectionHighlightColor="AliceBlue" 
                           IsTextSelectionEnabled="True" Padding="0" Foreground="Black">
                    Test text #9: TextWrapping=Wrap, LineStackingStrategy=MaxHeight 
                     <LineBreak/>
                    Second line
                </TextBlock>
            </Border>

            <Border Background="LightGray" Height="Auto">
                <TextBlock TextWrapping="Wrap" LineHeight="50" LineStackingStrategy="MaxHeight" TextLineBounds="Tight" 
                           SelectionHighlightColor="AliceBlue"  IsTextSelectionEnabled="True" Padding="0" Foreground="Black">
                    Test text #9b: TextWrapping=Wrap, LineStackingStrategy=MaxHeight, TextLineBounds=Tight
                     <LineBreak/>
                    Second line
                </TextBlock>
            </Border>

            <Border Background="LightSkyBlue" Height="Auto">
                <TextBlock TextWrapping="Wrap" LineHeight="50" LineStackingStrategy="MaxHeight" TextLineBounds="Full" 
                           SelectionHighlightColor="AliceBlue"  IsTextSelectionEnabled="True" Padding="0" Foreground="Black">
                    Test text #9c: TextWrapping=Wrap, LineStackingStrategy=MaxHeight, TextLineBounds=Full
                     <LineBreak/>
                    Second line
                </TextBlock>
            </Border>

            <Border Background="LightSteelBlue" Height="Auto">
                <TextBlock TextWrapping="Wrap" LineHeight="50" LineStackingStrategy="MaxHeight" TextLineBounds="TrimToCapHeight" 
                           SelectionHighlightColor="AliceBlue"  IsTextSelectionEnabled="True" Padding="0" Foreground="Black">
                    Test text #9d: TextWrapping=Wrap, LineStackingStrategy=MaxHeight, TextLineBounds=TrimToCapHeight
                     <LineBreak/>
                    Second line
                </TextBlock>
            </Border>

            <Border Background="LightCoral" Height="Auto">
                <TextBlock TextWrapping="Wrap" LineHeight="50" LineStackingStrategy="BlockLineHeight" SelectionHighlightColor="AliceBlue" 
                           IsTextSelectionEnabled="True" Padding="0" Foreground="Black">
                    Test text #10: TextWrapping=Wrap, LineStackingStrategy=BlockLineHeight 
                     <LineBreak/>
                    Second line
                </TextBlock>
            </Border>

            <Border Background="LightGoldenrodYellow" Height="Auto">
                <TextBlock TextWrapping="Wrap" LineHeight="50" LineStackingStrategy="BlockLineHeight" SelectionHighlightColor="AliceBlue" 
                           IsTextSelectionEnabled="True" Padding="0" Foreground="Black" TextLineBounds="Full" >
                    Test text #10b: TextWrapping=Wrap, LineStackingStrategy=BlockLineHeight, TextLineBounds=Full 
                     <LineBreak/>
                    Second line
                </TextBlock>
            </Border>

            <Border Background="LightGray" Height="Auto">
                <TextBlock TextWrapping="Wrap" LineHeight="50" LineStackingStrategy="BlockLineHeight" SelectionHighlightColor="AliceBlue" 
                           IsTextSelectionEnabled="True" Padding="0" Foreground="Black" TextLineBounds="Tight" >
                    Test text #10c: TextWrapping=Wrap, LineStackingStrategy=BlockLineHeight, TextLineBounds=Tight
                     <LineBreak/>
                    Second line
                </TextBlock>
            </Border>

            <Border Background="LightPink" Height="Auto">
                <TextBlock TextWrapping="Wrap" LineHeight="50" LineStackingStrategy="BlockLineHeight" SelectionHighlightColor="AliceBlue" 
                           IsTextSelectionEnabled="True" Padding="0" Foreground="Black" TextLineBounds="TrimToBaseline" >
                    Test text #10d: TextWrapping=Wrap, LineStackingStrategy=BlockLineHeight, TextLineBounds=TrimToBaseline
                     <LineBreak/>
                    Second line
                </TextBlock>
            </Border>

            <Border Background="LightSeaGreen" Height="Auto">
                <TextBlock TextWrapping="Wrap" LineHeight="50" LineStackingStrategy="BlockLineHeight" SelectionHighlightColor="AliceBlue" 
                           IsTextSelectionEnabled="True" Padding="0" Foreground="Black" TextLineBounds="TrimToCapHeight" >
                    Test text #10e: TextWrapping=Wrap, LineStackingStrategy=BlockLineHeight, TextLineBounds=TrimToCapHeight
                     <LineBreak/>
                    Second line
                </TextBlock>
            </Border>

            <Border Background="LightGreen" Height="Auto">
                <TextBlock TextWrapping="Wrap" LineHeight="50" LineStackingStrategy="BaselineToBaseline" SelectionHighlightColor="AliceBlue" 
                           IsTextSelectionEnabled="True" Padding="0" Foreground="Black">
                    Test text #11: TextWrapping=Wrap, LineStackingStrategy=BaselineToBaseline
                     <LineBreak/>
                    Second line
                </TextBlock>
            </Border>

            <Border Background="LightGray" Height="Auto">
                <TextBlock TextWrapping="Wrap" LineHeight="50" LineStackingStrategy="BaselineToBaseline" TextLineBounds="Full" 
                           SelectionHighlightColor="AliceBlue"  IsTextSelectionEnabled="True" Padding="0" Foreground="Black">
                    Test text #12: TextWrapping=Wrap, LineStackingStrategy=BaselineToBaseline, TextLineBounds=Full
                     <LineBreak/>
                    Second line
                </TextBlock>
            </Border>

            <Border Background="LightSalmon" Height="Auto">
                <TextBlock TextWrapping="Wrap" LineHeight="50" LineStackingStrategy="BaselineToBaseline" TextLineBounds="Tight" 
                           SelectionHighlightColor="AliceBlue" IsTextSelectionEnabled="True" Padding="0" Foreground="Black">
                    Test text #13: TextWrapping=Wrap, LineStackingStrategy=BaselineToBaseline, TextLineBounds=Tight
                     <LineBreak/>
                    Second line
                </TextBlock>
            </Border>
        </StackPanel>
    </ScrollView>
</Window>

renders as

image image image

Unfortunately, none seems to do what I would like.