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 :
- 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é.
- 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
etborder
.
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.