Partager via


Applications de style en utilisant des feuilles de style en cascade

Vous pouvez appliquer un style à des applications .NET Multi-Platform App UI (.NET MAUI) en utilisant des feuilles de style en cascade (CSS). Une feuille de style se compose d’une liste de règles, chaque règle se composant 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, chaque déclaration se composant 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 certaines feuilles de style en cascade conformes à .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 en cascade sont analysées et évaluées au moment de l’exécution, plutôt qu’au moment de la compilation, et les feuilles de style sont réévaluées lors de l’utilisation.

Important

Il n’est pas possible d’appliquer un style complet à une application .NET MAUI en utilisant des feuilles de style en cascade. Toutefois, vous pouvez utiliser des styles XAML pour compléter des feuilles de style en cascade. Pour obtenir plus d’informations sur les styles XAML, consultez Appliquer un style aux applications en utilisant XAML.

Consommer une feuille de style

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

  1. Ajoutez un ficher de feuilles de style en cascade vide à votre projet d’application .NET MAUI. Vous pouvez placer le fichier de feuilles de style en cascade dans n’importe quel dossier, le dossier Ressources étant l’emplacement recommandé.
  2. Définissez l’action de build du fichier de feuilles de style en cascade sur MauiCss.

Chargement d’une feuille de style

Vous pouvez utiliser plusieurs approches pour charger une feuille de style.

Remarque

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

Charger une feuille de style dans XAML

Vous pouvez charger et analyser une feuille de style avec la classe StyleSheet avant de l’ajouter à 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 relatif à l’emplacement du fichier XAML joint, ou relatif à la racine du projet si l’URI commence par un /.

Avertissement

Le fichier de feuilles de style en cascade ne se chargera pas si son action de build 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’incorporant dans une section CDATA :

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

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

Charger une feuille de style en C#

Dans C#, vous pouvez charger une feuille de style à partir d’un StringReader et l’ajouter à 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 TextReader qui a lu la feuille de style.

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

Les feuilles de style en cascade utilisent des sélecteurs pour déterminer les éléments à cibler. Les styles avec les 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 obtenir plus d’informations sur les sélecteurs pris en charge, consultez Référence sur le sélecteur.

Les feuilles de style en cascade utilisent des propriétés pour appliquer un style à 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, alors que d’autres s’appliquent aux groupes d’éléments. Pour obtenir plus d’informations sur les propriétés prises en charge, consultez Référence sur la 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 d’une application est remplacé par un style défini dans les ressources de la page, s’il définit les mêmes propriétés.
  • Un style défini dans les ressources d’une page est remplacé par un style défini dans les ressources du contrôle, s’il définit les mêmes propriétés.
  • Un style défini dans les ressources d’une application est remplacé par un style défini dans les ressources du contrôle, s’il définit les mêmes propriétés.

Remarque

Les variables de feuilles de style en cascade 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 element ne respectant pas la casse :

stacklayout {
    margin: 20;
}

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

Remarque

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 ^base ne respectant pas la casse :

^contentpage {
    background-color: lightgray;
}

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

Remarque

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

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 respectant 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 à l’utilisation de l’élément x:Name. Par conséquent, dans l’exemple suivant, le sélecteur #listView identifie le ListView dont l’attribut x:Name est défini sur listView et 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 respectant la casse :

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

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

Une classe de feuilles de style en cascade 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 de feuilles de style en cascade. Par conséquent, dans l’exemple suivant, les styles définis par la classe .detailPageTitle sont attribués à la première Label, tandis que les styles définis par la classe .detailPageSubtitle sont affectés à la 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 element element ne respectant pas la casse :

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

Ce sélecteur identifie tous les éléments Image qui sont des enfants d’éléments ListView et définit leur hauteur et leur largeur sur 60. Par conséquent, dans l’exemple XAML suivant, le sélecteur listview image identifie Image qui est un enfant de 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>

Remarque

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 autre parent. La sélection se produit à condition qu’un ancêtre soit le premier élément spécifié.

Sélectionner des éléments enfants directs

Les éléments enfants directs de l’arborescence visuelle peuvent être sélectionnés avec le sélecteur element>element ne respectant pas 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 stacklayout>image identifie Image qui est un enfant de la 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>

Remarque

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

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

Les sélecteurs de feuilles de style en cascade 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 « en-tête ». Ce sélecteur respecte la casse.
#id #email Sélectionne tous les éléments dont la valeur de StyleId est définie sur email. Si StyleId n’est pas défini, effectue un retour vers x:Name. Lors de l’utilisation de XAML, x:Name est préféré à StyleId. Ce sélecteur respecte 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 ne respecte pas la casse.
^base ^contentpage Sélectionne tous les éléments avec ContentPage comme classe de base, notamment l’élément ContentPage lui-même. Ce sélecteur ne respecte pas la casse et ne fait pas partie de la spécification des feuilles de style en cascade.
element,element label,button Sélectionne tous les éléments Button et tous les éléments Label. Ce sélecteur ne respecte pas la casse.
element element stacklayout label Sélectionne tous les éléments Label dans une StackLayout. Ce sélecteur ne respecte pas la casse.
element>element stacklayout>label Sélectionne tous les éléments Label avec StackLayout comme parent direct. Ce sélecteur ne respecte pas la casse.
element+element label+entry Sélectionne tous les éléments Entry directement après une Label. Ce sélecteur ne respecte pas la casse.
element~element label~entry Sélectionne tous les éléments Entry précédés d’une Label. Ce sélecteur ne respecte pas la casse.

Les styles avec les 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.

Conseil

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

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

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

Remarque

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

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

Les propriétés de feuilles de style en cascade suivantes sont prises en charge par .NET MAUI (dans la colonne Valeurs, les types sont en 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 color | initial background-color: springgreen;
background-image Page string | initial background-image: bg.png;
border-color Button, Frame, ImageButton color | 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 color | 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 flottant | auto | initial. En outre, un pourcentage de la plage comprise entre 0 % et 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. Vous devez éviter left et right dans des 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;

Remarque

initial est une valeur valide pour toutes les propriétés. Elle 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 raccourcies, telles que font et border.

En outre, il n’existe aucune valeur inherit. 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 vous attendre à ce que toutes les instances Label de la disposition héritent de la valeur. La seule exception est la propriété direction qui a une valeur par défaut de inherit.

Important

Les éléments Span ne peuvent pas faire l’objet d’une cible en utilisant des feuilles de style en cascade.

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

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

Propriété S’applique à Valeurs Exemple
-maui-bar-background-color NavigationPage, TabbedPage color | initial -maui-bar-background-color: teal;
-maui-bar-text-color NavigationPage, TabbedPage color | 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 color | initial -maui-max-track-color: red;
-maui-min-track-color Slider color | 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 entre guillemets | initial -maui-placeholder: Enter name;
-maui-placeholder-color Entry, Editor, SearchBar color | initial -maui-placeholder-color: green;
-maui-spacing StackLayout double | initial -maui-spacing: 8;
-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 string | initial -maui-visual: material;

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

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

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

Couleur

Les valeurs color suivantes sont prises en charge :

  • X11 couleurs qui correspondent aux couleurs de feuilles de style en cascade et aux couleurs .NET MAUI. Ces deux valeurs de couleur ne respectent pas la casse.
  • couleurs hexadécimales : #rgb, #argb, #rrggbb, #aarrggbb
  • couleurs RVB : rgb(255,0,0), rgb(100%,0%,0%). Les valeurs sont dans la plage comprise entre 0 et 255, ou entre 0 et 100 %.
  • couleurs RVBA : rgba(255, 0, 0, 0.8), rgba(100%, 0%, 0%, 0.8). La valeur d’opacité se trouve dans la plage comprise entre 0.0 et 1.0.
  • couleurs TSL : hsl(120, 100%, 50%). La valeur h se trouve dans la plage comprise entre 0 et 360, tandis que s et l se trouvent dans la plage comprise entre 0 % et 100 %.
  • couleurs HSLA : hsla(120, 100%, 50%, .8). La valeur d’opacité se trouve dans la plage comprise entre 0.0 et 1.0.

Thickness

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 une épaisseur en haut, puis horizontale (gauche et droite) et en bas.
  • Quatre valeurs indiquent une épaisseur en haut, puis à droite, en bas et à gauche.

Remarque

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

Functions

Les dégradés linéaires et radiaux peuvent être spécifiés en utilisant les fonctions de linear-gradient() radial-gradient() et de feuilles de style en cascade, respectivement. Le résultat de ces fonctions doit être affecté à la propriété background d’un contrôle.