Primary APIs:
RangeBase (Minimum, Maximum, Value, SmallChange, LargeChange)ProgressBar (IsIndeterminate, Orientation)Slider (IsSnapToTickEnabled, TickFrequency, TickPlacement)ScrollBar (ViewportSize, Orientation, Visibility, AllowAutoHide)ScrollViewer attached properties (HorizontalScrollBarVisibility, VerticalScrollBarVisibility, AllowAutoHide)Reference docs:
03-html-css-animations-transitions-and-motion-system.md19-html-css-sticky-scroll-linked-and-anchor-patterns.md57-scrollviewer-offset-anchoring-and-snap-points.md| HTML/CSS idiom | Avalonia mapping |
|---|---|
<progress value="42" max="100"> |
ProgressBar Minimum="0" Maximum="100" Value="42" |
| indeterminate loading bar | ProgressBar IsIndeterminate="True" |
<meter min max low high optimum> |
ProgressBar + threshold styles/classes |
<input type="range"> |
Slider |
| custom scrollbar styling | ScrollViewer + ScrollBar theme/style selectors |
| scroll position indicator | bind ScrollBar.Value to scroll offset model |
HTML/CSS:
<progress value="58" max="100"></progress>
<meter min="0" max="100" low="30" high="80" optimum="90" value="64"></meter>
progress,
meter {
inline-size: 260px;
block-size: 12px;
}
Avalonia:
<StackPanel Spacing="8">
<ProgressBar Minimum="0" Maximum="100" Value="58" />
<ProgressBar Minimum="0"
Maximum="100"
Value="64"
Classes="meter-warning" />
<ProgressBar IsIndeterminate="True" />
</StackPanel>
HTML/CSS:
<label for="quality">Quality</label>
<input id="quality" type="range" min="0" max="100" step="5" value="65" />
<StackPanel Spacing="6">
<TextBlock Text="Quality" />
<Slider Minimum="0"
Maximum="100"
TickFrequency="5"
IsSnapToTickEnabled="True"
Value="{CompiledBinding Quality, Mode=TwoWay}" />
</StackPanel>
Web apps often restyle scrollbars with vendor selectors and keep a separate progress indicator. In Avalonia, model scroll position explicitly and use ScrollViewer/ScrollBar properties.
<Grid RowDefinitions="Auto,*" RowSpacing="8">
<ScrollBar Grid.Row="0"
Orientation="Horizontal"
Minimum="0"
Maximum="100"
ViewportSize="15"
Value="{CompiledBinding ScrollPercent}" />
<ScrollViewer Grid.Row="1"
Height="220"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Disabled"
AllowAutoHide="True">
<StackPanel Spacing="6">
<TextBlock Text="Long content line 1" />
<TextBlock Text="Long content line 2" />
<TextBlock Text="Long content line 3" />
<TextBlock Text="Long content line 4" />
<TextBlock Text="Long content line 5" />
<TextBlock Text="Long content line 6" />
<TextBlock Text="Long content line 7" />
<TextBlock Text="Long content line 8" />
</StackPanel>
</ScrollViewer>
</Grid>
<section class="panel">
<h3>Upload</h3>
<progress value="34" max="100"></progress>
<label for="compression">Compression</label>
<input id="compression" type="range" min="0" max="100" step="1" value="72" />
</section>
.panel {
display: grid;
gap: 10px;
max-width: 420px;
}
<StackPanel Spacing="10" MaxWidth="420">
<TextBlock Text="Upload" FontWeight="SemiBold" />
<ProgressBar Minimum="0"
Maximum="100"
Value="{CompiledBinding UploadPercent}" />
<TextBlock Text="Compression" />
<Slider Minimum="0"
Maximum="100"
TickFrequency="1"
IsSnapToTickEnabled="True"
Value="{CompiledBinding Compression, Mode=TwoWay}" />
<TextBlock Text="Scroll feedback" FontWeight="SemiBold" />
<ScrollBar Orientation="Horizontal"
Minimum="0"
Maximum="100"
ViewportSize="20"
Value="{CompiledBinding ScrollPercent}" />
</StackPanel>
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
var panel = new StackPanel
{
Spacing = 10,
MaxWidth = 420
};
var uploadProgress = new ProgressBar
{
Minimum = 0,
Maximum = 100,
Value = 34
};
var compressionSlider = new Slider
{
Minimum = 0,
Maximum = 100,
TickFrequency = 1,
IsSnapToTickEnabled = true,
Value = 72
};
var scrollIndicator = new ScrollBar
{
Orientation = Avalonia.Layout.Orientation.Horizontal,
Minimum = 0,
Maximum = 100,
ViewportSize = 20,
Value = 0
};
compressionSlider.PropertyChanged += (_, e) =>
{
if (e.Property == RangeBase.ValueProperty)
uploadProgress.Value = compressionSlider.Value / 2;
};
panel.Children.Add(new TextBlock { Text = "Upload" });
panel.Children.Add(uploadProgress);
panel.Children.Add(new TextBlock { Text = "Compression" });
panel.Children.Add(compressionSlider);
panel.Children.Add(new TextBlock { Text = "Scroll feedback" });
panel.Children.Add(scrollIndicator);
Dispatcher.UIThread.Minimum/Maximum consistency and remove duplicate value coercion in VM logic.ViewportSize to a meaningful proportion of visible content.