Partager via


Applications de style à l’aide de feuilles de style en cascade

Les applications .NET Multiplateforme App UI (.NET MAUI) peuvent être mises en forme à l’aide de feuilles de style en cascade (CSS). Une feuille de style se compose d’une liste de règles, avec chaque règle composée d’un ou plusieurs sélecteurs et d’un bloc de déclaration. Un bloc de déclaration se compose d’une liste de déclarations entre accolades, avec chaque déclaration composée d’une propriété, d’un signe deux-points et d’une valeur. Lorsqu’il existe plusieurs déclarations dans un bloc, un point-virgule est inséré en tant que séparateur.

L'exemple suivant montre des CSS compatibles avec .NET MAUI :

navigationpage {
    -maui-bar-background-color: lightgray;
}

^contentpage {
    background-color: lightgray;
}

#listView {
    background-color: lightgray;
}

stacklayout {
    margin: 20;
    -maui-spacing: 6;
}

grid {
    row-gap: 6;
    column-gap: 6;
}
.mainPageTitle {
    font-style: bold;
    font-size: 14;
}

.mainPageSubtitle {
    margin-top: 15;
}

.detailPageTitle {
    font-style: bold;
    font-size: 14;
    text-align: center;
}

.detailPageSubtitle {
    text-align: center;
    font-style: italic;
}

listview image {
    height: 60;
    width: 60;
}

stacklayout>image {
    height: 200;
    width: 200;
}

Dans .NET MAUI, les feuilles de style CSS sont analysées et évaluées au moment de l’exécution, plutôt que le temps de compilation, et les feuilles de style sont réexécurées lors de l’utilisation.

Important

Il n’est pas possible de mettre entièrement en forme une application .NET MAUI à l’aide de CSS. Toutefois, les styles XAML peuvent être utilisés pour compléter CSS. Pour plus d’informations sur les styles XAML, consultez Styliser les applications à l'aide deXAML.

Consommer une feuille de style

Le processus d’ajout d’une feuille de style à une application .NET MAUI est le suivant :

  1. Ajoutez un fichier CSS vide à votre projet d’application .NET MAUI. Le fichier CSS peut être placé dans n’importe quel dossier, avec le Resources dossier étant l’emplacement recommandé.
  2. Définissez l'action de construction du fichier CSS sur MauiCss.

Chargement d’une feuille de style

Il existe plusieurs approches qui peuvent être utilisées pour charger une feuille de style.

Note

Il n’est pas possible de modifier une feuille de style au moment de l’exécution et d’appliquer la nouvelle feuille de style.

Charger une feuille de style en XAML

Une feuille de style peut être chargée et analysée avec la classe StyleSheet avant d’être ajoutée à un ResourceDictionary:

<Application ...>
    <Application.Resources>
        <StyleSheet Source="/Resources/styles.css" />
    </Application.Resources>
</Application>

La propriété StyleSheet.Source spécifie la feuille de style en tant qu’URI par rapport à l’emplacement du fichier XAML englobant ou par rapport à la racine du projet si l’URI commence par un /.

Avertissement

Le fichier CSS ne peut pas être chargé si son action de génération n’est pas définie sur MauiCss.

Vous pouvez également charger et analyser une feuille de style avec la classe StyleSheet, avant de l'ajouter à un ResourceDictionary, en l'incluant dans une section CDATA :

<ContentPage ...>
    <ContentPage.Resources>
        <StyleSheet>
            <![CDATA[
            ^contentpage {
                background-color: lightgray;
            }
            ]]>
        </StyleSheet>
    </ContentPage.Resources>
    ...
</ContentPage>

Pour plus d’informations sur les dictionnaires de ressources, consultez dictionnaires de ressources.

Charger une feuille de style en C#

En C#, une feuille de style peut être chargée à partir d’un StringReader et ajoutée à un ResourceDictionary:

using Microsoft.Maui.Controls.StyleSheets;

public partial class MyPage : ContentPage
{
    public MyPage()
    {
        InitializeComponent();

        using (var reader = new StringReader("^contentpage { background-color: lightgray; }"))
        {
            this.Resources.Add(StyleSheet.FromReader(reader));
        }
    }
}

L'argument de la méthode StyleSheet.FromReader est celui de TextReader qui a lu la feuille de style.

Sélectionner des éléments et appliquer des propriétés

CSS utilise des sélecteurs pour déterminer les éléments à cibler. Les styles avec sélecteurs correspondants sont appliqués consécutivement, dans l’ordre de définition. Les styles définis sur un élément spécifique sont toujours appliqués en dernier. Pour plus d’informations sur les sélecteurs pris en charge, consultez référence du sélecteur.

CSS utilise des propriétés pour styler un élément sélectionné. Chaque propriété a un ensemble de valeurs possibles et certaines propriétés peuvent affecter n’importe quel type d’élément, tandis que d’autres s’appliquent aux groupes d’éléments. Pour plus d’informations sur les propriétés prises en charge, consultez référence de propriété.

Les feuilles de style enfants remplacent toujours les feuilles de style parentes si elles définissent les mêmes propriétés. Par conséquent, les règles de précédence suivantes sont suivies lors de l’application de styles qui définissent les mêmes propriétés :

  • Un style défini dans les ressources de l’application est remplacé par un style défini dans les ressources de page, s’ils définissent les mêmes propriétés.
  • Un style défini dans les ressources de page est remplacé par un style défini dans les ressources de contrôle, s’ils définissent les mêmes propriétés.
  • Un style défini dans les ressources d’application est remplacé par un style défini dans les ressources de contrôle, s’ils définissent les mêmes propriétés.

Note

Les variables CSS ne sont pas prises en charge.

Sélectionner des éléments par type

Les éléments de l’arborescence visuelle peuvent être sélectionnés par type avec le sélecteur insensible à la casse element :

stacklayout {
    margin: 20;
}

Ce sélecteur identifie tous les éléments StackLayout sur les pages qui consomment la feuille de style et définit leurs marges sur une épaisseur uniforme de 20.

Note

Le sélecteur element n’identifie pas les sous-classes du type spécifié.

Sélection d’éléments par classe de base

Les éléments de l’arborescence visuelle peuvent être sélectionnés par classe de base avec le sélecteur insensible à la casse ^base.

^contentpage {
    background-color: lightgray;
}

Ce sélecteur identifie les éléments ContentPage qui consomment la feuille de style et définissent leur couleur d’arrière-plan sur lightgray.

Note

Le sélecteur ^base est spécifique à .NET MAUI et ne fait pas partie de la spécification CSS.

Sélection d’un élément par nom

Les éléments individuels de l’arborescence visuelle peuvent être sélectionnés avec le sélecteur #id sensible à la casse :

#listView {
    background-color: lightgray;
}

Ce sélecteur identifie l’élément dont la propriété StyleId est définie sur listView. Toutefois, si la propriété StyleId n’est pas définie, le sélecteur revient à utiliser la x:Name de l’élément. Par conséquent, dans l’exemple suivant, le sélecteur de #listView identifie l'ListView dont l’attribut x:Name est défini sur listViewet définit sa couleur d’arrière-plan sur lightgray.

<ContentPage ...>
    <ContentPage.Resources>
        <StyleSheet Source="/Resources/styles.css" />
    </ContentPage.Resources>
    <StackLayout>
        <ListView x:Name="listView">
            ...
        </ListView>
    </StackLayout>
</ContentPage>

Sélectionner des éléments avec un attribut de classe spécifique

Les éléments avec un attribut de classe spécifique peuvent être sélectionnés avec le sélecteur .class sensible à la casse :

.detailPageTitle {
    font-style: bold;
    font-size: 14;
    text-align: center;
}

.detailPageSubtitle {
    text-align: center;
    font-style: italic;
}

Une classe CSS peut être affectée à un élément XAML en définissant la propriété StyleClass de l’élément sur le nom de la classe CSS. Par conséquent, dans l’exemple suivant, les styles définis par la classe .detailPageTitle sont affectés au premier Label, tandis que les styles définis par la classe .detailPageSubtitle sont affectés au deuxième Label.

<ContentPage ...>
    <ContentPage.Resources>
        <StyleSheet Source="/Resources/styles.css" />
    </ContentPage.Resources>
    <ScrollView>
        <StackLayout>
            <Label ... StyleClass="detailPageTitle" />
            <Label ... StyleClass="detailPageSubtitle"/>
        </StackLayout>
    </ScrollView>
</ContentPage>

Sélectionner des éléments enfants

Les éléments enfants de l’arborescence visuelle peuvent être sélectionnés avec le sélecteur ne respectant pas la casse element element :

listview image {
    height: 60;
    width: 60;
}

Ce sélecteur identifie tout élément Image qui est un enfant direct d'un élément ListView et définit sa hauteur et sa largeur à 60. Par conséquent, dans l’exemple XAML suivant, le sélecteur listview image identifie l'Image enfant du ListViewet définit sa hauteur et sa largeur sur 60.

<ContentPage ...>
    <ContentPage.Resources>
        <StyleSheet Source="/Resources/styles.css" />
    </ContentPage.Resources>
    <StackLayout>
        <ListView ...>
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <Grid>
                            ...
                            <Image ... />
                            ...
                        </Grid>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackLayout>
</ContentPage>

Note

Le sélecteur element element ne nécessite pas que l’élément enfant soit un enfant direct du parent . L’élément enfant peut avoir un parent différent. La sélection se produit à condition qu’un ancêtre soit le premier élément spécifié.

Sélectionner éléments enfants directs

Les éléments enfants directs dans l'arborescence visuelle peuvent être sélectionnés avec le sélecteur element>element insensible à la casse :

stacklayout>image {
    height: 200;
    width: 200;
}

Ce sélecteur identifie tous les éléments Image qui sont des enfants directs d’éléments StackLayout et définit leur hauteur et leur largeur sur 200. Par conséquent, dans l’exemple suivant, le sélecteur de stacklayout>image identifie le Image qui est un enfant direct du StackLayoutet définit sa hauteur et sa largeur sur 200.

<ContentPage ...>
    <ContentPage.Resources>
        <StyleSheet Source="/Resources/styles.css" />
    </ContentPage.Resources>
    <ScrollView>
        <StackLayout>
            ...
            <Image ... />
            ...
        </StackLayout>
    </ScrollView>
</ContentPage>

Note

Le sélecteur element>element nécessite que l’élément enfant soit un enfant direct du parent.

Informations de référence sur le sélecteur

Les sélecteurs CSS suivants sont pris en charge par .NET MAUI :

Sélecteur Exemple Description
.class .header Sélectionne tous les éléments avec la propriété StyleClass contenant « header ». Ce sélecteur respecte la casse.
#id #email Sélectionne tous les éléments ayant StyleId défini sur email. Si StyleId n’est pas défini, basculer vers x:Name. Lors de l’utilisation de XAML, x:Name est préférable à StyleId. Ce sélecteur est sensible à la casse.
* * Sélectionne tous les éléments.
element label Sélectionne tous les éléments de type Label, mais pas les sous-classes. Ce sélecteur est insensible à la casse.
^base ^contentpage Sélectionne tous les éléments avec ContentPage comme classe de base, y compris ContentPage lui-même. Ce sélecteur ne respecte pas la casse et ne fait pas partie de la spécification CSS.
element,element label,button Sélectionne tous les éléments Button et tous les éléments Label. Ce sélecteur est insensible à la casse.
element element stacklayout label Sélectionne tous les éléments Label à l’intérieur d’un StackLayout. Ce sélecteur est insensible à la casse.
element>element stacklayout>label Sélectionne tous les éléments Label avec StackLayout en tant que parent direct. Ce sélecteur est insensible à la casse.
element+element label+entry Sélectionne tous les éléments Entry situés directement après un Label. Ce sélecteur est insensible à la casse.
element~element label~entry Sélectionne tous les éléments Entry précédés d’un Label. Ce sélecteur est insensible à la casse.

Les styles avec sélecteurs correspondants sont appliqués consécutivement, dans l’ordre de définition. Les styles définis sur un élément spécifique sont toujours appliqués en dernier.

Pourboire

Les sélecteurs peuvent être combinés sans limitation, tels que StackLayout>ContentView>label.email.

Les sélecteurs suivants ne sont pas pris en charge :

  • [attribute]
  • @media et @supports
  • : et ::

Note

La spécificité et les remplacements de spécificité ne sont pas pris en charge.

Si deux règles CSS ou plus pointent vers le même élément, le sélecteur avec la spécificité la plus élevée est prioritaire et sa déclaration de style est appliquée à l’élément. L’algorithme de spécificité calcule le poids d’un sélecteur CSS pour déterminer quelle règle des déclarations CSS concurrentes est appliquée à l’élément.

Informations de référence sur les propriétés

Les propriétés CSS suivantes sont prises en charge par .NET MAUI (dans la colonne Valeurs, les types sont italique, tandis que les littéraux de chaîne sont gray) :

Propriété S’applique à Valeurs Exemple
align-content FlexLayout stretch | center | start | end | spacebetween | spacearound | spaceevenly | flex-start | flex-end | space-between | space-around | initial align-content: space-between;
align-items FlexLayout stretch | center | start | end | flex-start | flex-end | initial align-items: flex-start;
align-self VisualElement auto | stretch | center | start | end | flex-start | flex-end | initial align-self: flex-end;
background-color VisualElement couleur | initial background-color: springgreen;
background-image Page chaîne | initial background-image: bg.png;
border-color Button, Frame, ImageButton couleur | initial border-color: #9acd32;
border-radius BoxView, Button, Frame, ImageButton double | initial border-radius: 10;
border-width Button, ImageButton double | initial border-width: .5;
color ActivityIndicator, BoxView, Button, CheckBox, DatePicker, Editor, Entry, Label, Picker, ProgressBar, SearchBar, Switch, TimePicker couleur | initial color: rgba(255, 0, 0, 0.3);
column-gap Grid double | initial column-gap: 9;
direction VisualElement ltr | rtl | inherit | initial direction: rtl;
flex-direction FlexLayout column | columnreverse | row | rowreverse | row-reverse | column-reverse | initial flex-direction: column-reverse;
flex-basis VisualElement float | auto | initial. En outre, un pourcentage de la plage de 0% à 100% peut être spécifié avec le signe %. flex-basis: 25%;
flex-grow VisualElement float | initial flex-grow: 1.5;
flex-shrink VisualElement float | initial flex-shrink: 1;
flex-wrap VisualElement nowrap | wrap | reverse | wrap-reverse | initial flex-wrap: wrap-reverse;
font-family Button, DatePicker, Editor, Entry, Label, Picker, SearchBar, TimePicker, Span string | initial font-family: Consolas;
font-size Button, DatePicker, Editor, Entry, Label, Picker, SearchBar, TimePicker, Span double | initial font-size: 12;
font-style Button, DatePicker, Editor, Entry, Label, Picker, SearchBar, TimePicker, Span bold | italic | initial font-style: bold;
height VisualElement double | initial height: 250;
justify-content FlexLayout start | center | end | spacebetween | spacearound | spaceevenly | flex-start | flex-end | space-between | space-around | initial justify-content: flex-end;
letter-spacing Button, DatePicker, Editor, Entry, Label, Picker, SearchBar, SearchHandler, Span, TimePicker double | initial letter-spacing: 2.5;
line-height Label, Span double | initial line-height: 1.8;
margin View épaisseur | initial margin: 6 12;
margin-left View épaisseur | initial margin-left: 3;
margin-top View épaisseur | initial margin-top: 2;
margin-right View épaisseur | initial margin-right: 1;
margin-bottom View épaisseur | initial margin-bottom: 6;
max-lines Label int | initial max-lines: 2;
min-height VisualElement double | initial min-height: 50;
min-width VisualElement double | initial min-width: 112;
opacity VisualElement double | initial opacity: .3;
order VisualElement int | initial order: -1;
padding Button, ImageButton, Layout, Page épaisseur | initial padding: 6 12 12;
padding-left Button, ImageButton, Layout, Page double | initial padding-left: 3;
padding-top Button, ImageButton, Layout, Page double | initial padding-top: 4;
padding-right Button, ImageButton, Layout, Page double | initial padding-right: 2;
padding-bottom Button, ImageButton, Layout, Page double | initial padding-bottom: 6;
position FlexLayout relative | absolute | initial position: absolute;
row-gap Grid double | initial row-gap: 12;
text-align Entry, EntryCell, Label, SearchBar left | top | right | bottom | start | center | middle | end | initial. left et right doivent être évités dans les environnements de droite à gauche. text-align: right;
text-decoration Label, Span none | underline | strikethrough | line-through | initial text-decoration: underline, line-through;
text-transform Button,Editor, Entry, Label, SearchBar, SearchHandler none | default | uppercase | lowercase | initial text-transform: uppercase;
transform VisualElement none, rotate, rotateX, rotateY, scale, scaleX, scaleY, translate, translateX, translateY, initial transform: rotate(180), scaleX(2.5);
transform-origin VisualElement double, double | initial transform-origin: 7.5, 12.5;
vertical-align Label left | top | right | bottom | start | center | middle | end | initial vertical-align: bottom;
visibility VisualElement true | visible | false | hidden | collapse | initial visibility: hidden;
width VisualElement double | initial width: 320;

Note

initial est une valeur valide pour toutes les propriétés. Il efface la valeur (réinitialise la valeur par défaut) définie à partir d’un autre style.

Les propriétés suivantes ne sont pas prises en charge :

  • all: initial.
  • Propriétés de disposition (zone ou grille).
  • Propriétés abrégées, telles que fontet border.

En outre, il n’existe aucune valeur inherit et l’héritage n’est donc pas pris en charge. Par conséquent, vous ne pouvez pas, par exemple, définir la propriété font-size sur une disposition et attendre que toutes les instances Label de la disposition héritent de la valeur. L’une des exceptions est la propriété direction, qui a une valeur par défaut de inherit.

Important

Span éléments ne peuvent pas être ciblés à l’aide de CSS.

Propriétés spécifiques à .NET MAUI

Les propriétés CSS spécifiques à .NET MAUI suivantes sont également prises en charge (dans la colonne Valeurs, les types sont italique, tandis que les littéraux de chaîne sont gray) :

Propriété S’applique à Valeurs Exemple
-maui-bar-background-color NavigationPage, TabbedPage couleur | initial -maui-bar-background-color: teal;
-maui-bar-text-color NavigationPage, TabbedPage couleur | initial -maui-bar-text-color: gray
-maui-horizontal-scroll-bar-visibility ScrollView default | always | never | initial -maui-horizontal-scroll-bar-visibility: never;
-maui-max-length Entry, Editor, SearchBar int | initial -maui-max-length: 20;
-maui-max-track-color Slider couleur | initial -maui-max-track-color: red;
-maui-min-track-color Slider couleur | initial -maui-min-track-color: yellow;
-maui-orientation ScrollView, StackLayout horizontal | vertical | both | initial. both est uniquement pris en charge sur un ScrollView. -maui-orientation: horizontal;
-maui-placeholder Entry, Editor, SearchBar texte cité | initial -maui-placeholder: Enter name;
-maui-placeholder-color Entry, Editor, SearchBar couleur | initial -maui-placeholder-color: green;
-maui-spacing StackLayout double | initial -maui-spacing: 8;
-maui-shadow VisualElement Les formats valides sont : couleur, offsetX, offsetY | offsetX, offsetY, rayon, couleur | offsetX, offsetY, rayon, couleur, opacité -maui-shadow: #000000 4 4;
-maui-thumb-color Slider, Switch color | initial -maui-thumb-color: limegreen;
-maui-vertical-scroll-bar-visibility ScrollView default | always | never | initial -maui-vertical-scroll-bar-visibility: always;
-maui-vertical-text-alignment Label start | center | end | initial -maui-vertical-text-alignment: end;
-maui-visual VisualElement chaîne de caractères | initial -maui-visual: material;

Propriétés spécifiques de .NET MAUI Shell

Les propriétés CSS spécifiques à .NET MAUI Shell suivantes sont également prises en charge (dans la colonne Valeurs, les types sont italique, tandis que les littéraux de chaîne sont gray) :

Propriété S’applique à Valeurs Exemple
-maui-flyout-background Shell couleur | initial -maui-flyout-background: red;
-maui-shell-background Element couleur | initial -maui-shell-background: green;
-maui-shell-disabled Element couleur | initial -maui-shell-disabled: blue;
-maui-shell-foreground Element couleur | initial -maui-shell-foreground: yellow;
-maui-shell-tabbar-background Element couleur | initial -maui-shell-tabbar-background: white;
-maui-shell-tabbar-disabled Element couleur | initial -maui-shell-tabbar-disabled: black;
-maui-shell-tabbar-foreground Element color | initial -maui-shell-tabbar-foreground: gray;
-maui-shell-tabbar-title Element couleur | initial -maui-shell-tabbar-title: lightgray;
-maui-shell-tabbar-unselected Element couleur | initial -maui-shell-tabbar-unselected: cyan;
-maui-shell-title Element couleur | initial -maui-shell-title: teal;
-maui-shell-unselected Element couleur | initial -maui-shell-unselected: limegreen;

Couleur

Les valeurs de color suivantes sont prises en charge :

  • X11 couleurs, qui correspondent aux couleurs CSS et aux couleurs .NET MAUI. Ces valeurs de couleur ne tiennent pas compte de la casse.
  • couleurs hexadécimal : #rgb, #argb, #rrggbb, #aarrggbb
  • couleurs rvb : rgb(255,0,0), rgb(100%,0%,0%). Les valeurs se trouvent dans la plage 0-255 ou 0%-100%.
  • couleurs rgba : rgba(255, 0, 0, 0.8), rgba(100%, 0%, 0%, 0.8). La valeur d’opacité se trouve dans la plage 0.0-1.0.
  • couleurs hsl : hsl(120, 100%, 50%). La valeur h se trouve dans la plage 0-360, tandis que s et l se trouvent dans la plage 0%-100%.
  • couleurs hsla : hsla(120, 100%, 50%, .8). La valeur d’opacité se trouve dans la plage 0.0-1.0.

Épaisseur

Une, deux, trois ou quatre valeurs thickness sont prises en charge, chacune séparée par un espace blanc :

  • Une valeur unique indique une épaisseur uniforme.
  • Deux valeurs indiquent une épaisseur verticale puis horizontale.
  • Trois valeurs indiquent le haut, puis horizontal (gauche et droite), puis l’épaisseur inférieure.
  • Quatre valeurs indiquent le haut, puis la droite, puis l’épaisseur inférieure, puis l’épaisseur gauche.

Note

Les valeurs thickness CSS diffèrent des valeurs de Thickness XAML. Par exemple, en XAML, une Thickness à deux valeurs indique une épaisseur horizontale puis verticale, tandis qu’une Thickness à quatre valeurs indique à gauche, puis en haut, puis à droite, puis en bas. En outre, les valeurs de Thickness XAML sont délimitées par des virgules.

Fonctions

Les dégradés linéaires et radials peuvent être spécifiés à l’aide des fonctions CSS linear-gradient() et radial-gradient(), respectivement. Le résultat de ces fonctions doit être affecté à la propriété background d’un contrôle.