MAUI Styling and Theming

Learn how to style and theme your .NET MAUI applications to create visually appealing and consistent user interfaces across all target platforms.

Introduction to Styling in .NET MAUI

.NET MAUI provides a powerful and flexible styling system that allows you to define the visual appearance of your application's UI elements. This system is based on Cascading Style Sheets (CSS) principles, making it familiar to web developers and easy to adopt.

You can apply styles at different levels:

  • Inline Styles: Directly on a specific element.
  • Element Styles: Targeting all instances of a particular control type.
  • Class Styles: Applying styles to elements with a specific StyleClass.
  • Resource Dictionaries: Centralizing styles for reusability.

CSS Styling

.NET MAUI supports a subset of CSS for styling your UI. You can create a .razor file (or a custom CSS file) and link it to your application. Common CSS properties like color, background-color, font-size, margin, padding, and border are supported.

Example: Basic CSS Styling

Create a Resources/Styles/Styles.css file and add the following:

/* Resources/Styles/Styles.css */
.main-label {
    color: #0078d4;
    font-size: 24px;
    font-weight: bold;
    text-align: center;
    margin-top: 20px;
}

Button {
    background-color: #107c10;
    color: white;
    border-radius: 5px;
    padding: 10px 20px;
    margin: 5px;
}

Button:hover {
    background-color: #138a13;
}

To use these styles, apply them to your XAML elements:

<!-- MainPage.xaml -->
<ContentPage ...
             xmlns:resources="clr-namespace:YourAppName.Resources.Styles">
    <VerticalStackLayout>
        <Label Text="Hello, MAUI!" StyleClass="main-label" />
        <Button Text="Click Me" />
    </VerticalStackLayout>
</ContentPage>

Visual States

Visual states allow you to define how controls change their appearance based on user interaction or application state (e.g., pressed, disabled, focused). This is often managed through the VisualStateManager in XAML.

Example: Button Visual States

<Button Text="Interactive Button">
    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup x:Name="CommonStates">
            <VisualState x:Name="Normal" />
            <VisualState x:Name="Disabled">
                <State visualState="Disabled">
                    <VisualState.Setters>
                        <Setter Property="BackgroundColor" Value="LightGray" />
                        <Setter Property="TextColor" Value="DarkGray" />
                    </VisualState.Setters>
                </State>
            </VisualState>
            <VisualState x:Name="Pressed">
                <State visualState="Pressed">
                    <VisualState.Setters>
                        <Setter Property="BackgroundColor" Value="DarkBlue" />
                        <Setter Property="TextColor" Value="LightGray" />
                    </VisualState.Setters>
                </State>
            </VisualState>
        </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>
</Button>

Theming with Resources

For more complex theming, you can leverage ResourceDictionary to define styles, colors, and other resources that can be applied globally or to specific sections of your application. This promotes consistency and makes it easier to manage your app's look and feel.

Define themes in separate XAML files (e.g., DarkTheme.xaml, LightTheme.xaml) and merge them into your app's ResourceDictionary.

Example: Defining Theme Resources

Resources/Styles/Colors.xaml:

<?xml version="1.0" encoding="utf-8" ?>
<ResourceDictionary xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
                    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">
    <Color x:Key="PrimaryColor">#0078D4</Color>
    <Color x:Key="TextColor">#333333</Color>
    <Color x:Key="BackgroundColor">#FFFFFF</Color>
</ResourceDictionary>

Resources/Styles/Styles.xaml:

<?xml version="1.0" encoding="utf-8" ?>
<ResourceDictionary xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
                    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">
    <Style TargetType="Label">
        <Setter Property="TextColor" Value="{DynamicResource TextColor}" />
        <Setter Property="FontSize" Value="16" />
    </Style>

    <Style TargetType="Button">
        <Setter Property="BackgroundColor" Value="{DynamicResource PrimaryColor}" />
        <Setter Property="TextColor" Value="White" />
        <Setter Property="CornerRadius" Value="5" />
    </Style>
</ResourceDictionary>

Merge these dictionaries in App.xaml:

<Application ...>
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Resources/Styles/Colors.xaml" />
                <ResourceDictionary Source="Resources/Styles/Styles.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

Notice the use of DynamicResource, which allows theme colors to be updated at runtime.

Custom Controls and Styles

You can create custom controls and apply styles to them, either by defining styles for the custom control type or by assigning StyleClass properties.

Platform-Specific Styling

.NET MAUI allows you to apply styles conditionally based on the target platform using the OnPlatform markup extension.

Example: Platform-Specific Background

<ContentPage BackgroundColor="{OnPlatform iOS=LightGray, Android=DarkGray, WinUI=AliceBlue}">
    <!-- Content -->
</ContentPage>

Note:

When using CSS files, ensure they are correctly linked in your MauiProgram.cs file using ConfigureMauiApp().ConfigureFonts(...) and referencing the CSS file.

Tip:

Start with global styles and gradually apply more specific styles. Use DynamicResource for colors and other theme-related properties to enable runtime theme switching.