Container Queries v11.3 Preview!
Container Queries allows styles to be activated for control based on the size of an ancestor, which acts as a container.
Avalonia's Container Queries are similar to CSS's Container Queries, with a more limited functionality to suit platforms and form factors Avalonia supports. They can also behave like media queries if the Toplevel is set as a container.
How It Works
Container queries rely on there being an ancestor control being set as a container. Changes to the size of the container activate styles based on queries. Those queries can check either the width or height of the container, or both. Any control can be a container, but a control set as a container can not be affected by styles hosted by a container query linked to it. When a query is activated, all styles hosted in the query will also be activated based on their selectors.
How To Use Queries
Declaring Container Queries
Container queries can be defined in XAML as the direct child of a control's Styles
property like this:
<StackPanel Orientation="Horizontal">
<StackPanel.Styles>
<ContainerQuery Name="container"
Query="max-width:400">
<Style Selector="Button">
<Setter Property="Background"
Value="Red"/>
</Style>
</ContainerQuery>
<StackPanel>
They can also be part of a ControlTheme
's styles:
<ControlTheme x:Key="{x:Type ListBox}" TargetType="ListBox">
...
<Setter Property="Template">
<ControlTemplate>
<Border Name="border"
Container.Name="Test"
Container.Sizing="WidthAndHeight"
>
<ScrollViewer Name="PART_ScrollViewer">
...
</ScrollViewer>
</Border>
</ControlTemplate>
</Setter>
<ContainerQuery Name="Test"
Query="max-height:400">
<Style Selector="ScrollViewer#PART_ScrollViewer">
<Setter Property="Background"
Value="Red"/>
</Style>
</ContainerQuery>
</ControlTheme>
The Name
property defines the name of the container it will attach to. This isn't a unique identifier, and multiple container queries can use the same name.
The Query
defines the rules to activate the containing size. See Queries below.
This make them quite easy to use in themes targeting difference screen sizes, or themes thathave different forms depending on the space available in its parent. This comes with a few restrictions.
- Container Queries can't be hosted in a
Style
element. The following is invalid.
<StackPanel Orientation="Horizontal">
<StackPanel.Styles>
<Style Selector="...">
<ContainerQuery Name="container"
Query="max-width:400">
<Style Selector="Button">
<Setter Property="Background"
Value="Red"/>
</Style>
</ContainerQuery>
</Style>
<StackPanel>
- Styles declared in Queries can not affect the container or its ancestors. This is different from normal
Styles
being able to affect their parent control. Because container queries rely on the actual size of the container, having the container be affected by styles activated by its queries can cause cyclic behaviors where the container's size is being updated continuously by two or more queries.
Declaring Containers
Container queries only work if a control that's a descendant of the ContainerQuery
's host is declared as container. Setting the Container.Name
and Container.Sizing
attached properties of any control will declare that control as a container, like this:
<Button
Container.Name="container-name"
Container.Sizing="container-sizing
/>