Aplikacje stylów korzystające z kaskadowych arkuszy stylów
Aplikacje interfejsu użytkownika aplikacji wieloplatformowych platformy .NET (.NET MAUI) można stylizować przy użyciu kaskadowych arkuszy stylów (CSS). Arkusz stylów składa się z listy reguł, z każdą regułą składającą się z co najmniej jednego selektora i bloku deklaracji. Blok deklaracji składa się z listy deklaracji w nawiasach klamrowych, z każdą deklaracją składającą się z właściwości, dwukropka i wartości. Jeśli w bloku znajduje się wiele deklaracji, średnik jest wstawiany jako separator.
W poniższym przykładzie przedstawiono kod CSS zgodny ze standardem MAUI platformy .NET:
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;
}
W programie .NET MAUI arkusze stylów CSS są analizowane i oceniane w czasie wykonywania, a nie w czasie kompilacji, a arkusze stylów są ponownie analizowane.
Ważne
Nie można w pełni stylizować aplikacji .NET MAUI przy użyciu arkuszy CSS. Jednak style XAML mogą służyć do uzupełnienia css. Aby uzyskać więcej informacji na temat stylów XAML, zobacz Style apps using XAML (Aplikacje stylów korzystające z języka XAML).
Korzystanie z arkusza stylów
Proces dodawania arkusza stylów do aplikacji MAUI platformy .NET jest następujący:
- Dodaj pusty plik CSS do projektu aplikacji .NET MAUI. Plik CSS można umieścić w dowolnym folderze, a folder Resources jest zalecaną lokalizacją.
- Ustaw akcję kompilacji pliku CSS na MauiCss.
Ładowanie arkusza stylów
Istnieje wiele podejść, których można użyć do załadowania arkusza stylów.
Uwaga
Nie można zmienić arkusza stylów w czasie wykonywania i zastosować nowy arkusz stylów.
Ładowanie arkusza stylów w języku XAML
Arkusz stylów można załadować i przeanalizować z StyleSheet
klasą przed dodaniu do klasy ResourceDictionary:
<Application ...>
<Application.Resources>
<StyleSheet Source="/Resources/styles.css" />
</Application.Resources>
</Application>
Właściwość StyleSheet.Source
określa arkusz stylów jako identyfikator URI względem lokalizacji otaczającego pliku XAML lub względem katalogu głównego projektu, jeśli identyfikator URI zaczyna się od /
.
Ostrzeżenie
Nie można załadować pliku CSS, jeśli jego akcja kompilacji nie jest ustawiona na MauiCss.
Alternatywnie arkusz stylów można załadować i przeanalizować z StyleSheet
klasą ResourceDictionary, zanim zostanie dodany do klasy , tworząc go w CDATA
sekcji:
<ContentPage ...>
<ContentPage.Resources>
<StyleSheet>
<![CDATA[
^contentpage {
background-color: lightgray;
}
]]>
</StyleSheet>
</ContentPage.Resources>
...
</ContentPage>
Aby uzyskać więcej informacji na temat słowników zasobów, zobacz Słowniki zasobów.
Ładowanie arkusza stylów w języku C#
W języku C# arkusz stylów można załadować z obiektu StringReader
i dodany do elementu 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));
}
}
}
Argumentem StyleSheet.FromReader
metody jest TextReader
to, który odczytał arkusz stylów.
Wybieranie elementów i stosowanie właściwości
Arkusz CSS używa selektorów do określania elementów docelowych. Style z pasującymi selektorami są stosowane kolejno w kolejności definicji. Style zdefiniowane na określonym elemencie są zawsze stosowane jako ostatnie. Aby uzyskać więcej informacji na temat obsługiwanych selektorów, zobacz Dokumentacja selektora.
Arkusz CSS używa właściwości do stylu wybranego elementu. Każda właściwość ma zestaw możliwych wartości, a niektóre właściwości mogą mieć wpływ na dowolny typ elementu, podczas gdy inne mają zastosowanie do grup elementów. Aby uzyskać więcej informacji na temat obsługiwanych właściwości, zobacz Dokumentacja właściwości.
Arkusze stylów podrzędnych zawsze zastępują nadrzędne arkusze stylów, jeśli ustawiają te same właściwości. W związku z tym następujące reguły pierwszeństwa są przestrzegane podczas stosowania stylów, które ustawiają te same właściwości:
- Styl zdefiniowany w zasobach aplikacji zostanie zastąpiony przez styl zdefiniowany w zasobach strony, jeśli ustawi te same właściwości.
- Styl zdefiniowany w zasobach strony zostanie zastąpiony przez styl zdefiniowany w zasobach sterujących, jeśli ustawi te same właściwości.
- Styl zdefiniowany w zasobach aplikacji zostanie zastąpiony przez styl zdefiniowany w zasobach sterujących, jeśli ustawi te same właściwości.
Uwaga
Zmienne CSS nie są obsługiwane.
Wybieranie elementów według typu
Elementy w drzewie wizualizacji można wybrać według typu z selektorem bez uwzględniania element
wielkości liter:
stacklayout {
margin: 20;
}
Ten selektor identyfikuje wszystkie StackLayout elementy na stronach korzystających z arkusza stylów i ustawia ich marginesy na jednolitą grubość 20.
Uwaga
Selektor element
nie identyfikuje podklas określonego typu.
Wybieranie elementów według klasy bazowej
Elementy w drzewie wizualizacji można wybrać za pomocą klasy bazowej z selektorem bez uwzględniania ^base
wielkości liter:
^contentpage {
background-color: lightgray;
}
Ten selektor identyfikuje wszystkie ContentPage elementy, które używają arkusza stylów, i ustawia kolor tła na lightgray
.
Uwaga
Selektor ^base
jest specyficzny dla interfejsu MAUI platformy .NET i nie jest częścią specyfikacji CSS.
Wybieranie elementu według nazwy
Poszczególne elementy w drzewie wizualizacji można wybrać za pomocą selektora uwzględniającego wielkość liter #id
:
#listView {
background-color: lightgray;
}
Ten selektor identyfikuje element, którego StyleId
właściwość jest ustawiona na listView
. Jeśli StyleId
jednak właściwość nie jest ustawiona, selektor powróci do użycia x:Name
elementu . W związku z tym w poniższym przykładzie #listView
selektor zidentyfikuje ListView , którego x:Name
atrybut jest ustawiony na listView
, i ustawi kolor tła na lightgray
.
<ContentPage ...>
<ContentPage.Resources>
<StyleSheet Source="/Resources/styles.css" />
</ContentPage.Resources>
<StackLayout>
<ListView x:Name="listView">
...
</ListView>
</StackLayout>
</ContentPage>
Wybieranie elementów z określonym atrybutem klasy
Elementy z określonym atrybutem klasy można wybrać za pomocą selektora uwzględniającego .class
wielkość liter:
.detailPageTitle {
font-style: bold;
font-size: 14;
text-align: center;
}
.detailPageSubtitle {
text-align: center;
font-style: italic;
}
Klasę CSS można przypisać do elementu XAML, ustawiając StyleClass
właściwość elementu na nazwę klasy CSS. W związku z tym w poniższym przykładzie style zdefiniowane przez klasę .detailPageTitle
są przypisywane do pierwszego Labelelementu , podczas gdy style zdefiniowane przez .detailPageSubtitle
klasę są przypisywane do drugiego Labelelementu .
<ContentPage ...>
<ContentPage.Resources>
<StyleSheet Source="/Resources/styles.css" />
</ContentPage.Resources>
<ScrollView>
<StackLayout>
<Label ... StyleClass="detailPageTitle" />
<Label ... StyleClass="detailPageSubtitle"/>
</StackLayout>
</ScrollView>
</ContentPage>
Wybieranie elementów podrzędnych
Elementy podrzędne w drzewie wizualizacji można wybrać za pomocą selektora bez uwzględniania element element
wielkości liter:
listview image {
height: 60;
width: 60;
}
Ten selektor identyfikuje wszystkie Image elementy podrzędne ListView elementów i ustawia ich wysokość i szerokość na 60. W związku z tym w poniższym przykładzie listview image
XAML selektor zidentyfikuje Image element podrzędny ListViewobiektu i ustawia jego wysokość i szerokość na 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>
Uwaga
Selektor element element
nie wymaga, aby element podrzędny był bezpośrednim elementem podrzędnym elementu nadrzędnego — element podrzędny może mieć inny element nadrzędny. Wybór występuje pod warunkiem, że element nadrzędny jest określonym pierwszym elementem.
Wybieranie bezpośrednich elementów podrzędnych
Bezpośrednie elementy podrzędne w drzewie wizualizacji można wybrać za pomocą selektora bez uwzględniania element>element
wielkości liter:
stacklayout>image {
height: 200;
width: 200;
}
Ten selektor identyfikuje wszystkie Image elementy, które są bezpośrednimi elementami podrzędnymi StackLayout elementów, i ustawia ich wysokość i szerokość na 200. W związku z tym w poniższym przykładzie stacklayout>image
selektor zidentyfikuje Image obiekt , który jest bezpośrednim elementem podrzędnym StackLayoutobiektu , i ustawia jego wysokość i szerokość na 200.
<ContentPage ...>
<ContentPage.Resources>
<StyleSheet Source="/Resources/styles.css" />
</ContentPage.Resources>
<ScrollView>
<StackLayout>
...
<Image ... />
...
</StackLayout>
</ScrollView>
</ContentPage>
Uwaga
Selektor element>element
wymaga, aby element podrzędny był bezpośrednim elementem podrzędnym elementu nadrzędnego.
Dokumentacja selektora
Następujące selektory CSS są obsługiwane przez program .NET MAUI:
Selektor | Przykład | opis |
---|---|---|
.class |
.header |
Wybiera wszystkie elementy z właściwością zawierającą StyleClass "nagłówek". W selektorze jest uwzględniana wielkość liter. |
#id |
#email |
Wybiera wszystkie elementy z ustawioną wartością StyleId email . Jeśli StyleId nie jest ustawiona, powrót do elementu x:Name . W przypadku korzystania z języka XAML x:Name preferowane jest użycie elementu StyleId . W selektorze jest uwzględniana wielkość liter. |
* |
* |
Wybiera wszystkie elementy. |
element |
label |
Wybiera wszystkie elementy typu Label, ale nie podklasy. Ten selektor jest niewrażliwy na wielkość liter. |
^base |
^contentpage |
Wybiera wszystkie elementy z ContentPage jako klasą bazową, w tym ContentPage samą klasą. Ten selektor nie uwzględnia wielkości liter i nie jest częścią specyfikacji CSS. |
element,element |
label,button |
Wybiera wszystkie Button elementy i wszystkie Label elementy. Ten selektor jest niewrażliwy na wielkość liter. |
element element |
stacklayout label |
Wybiera wszystkie Label elementy wewnątrz elementu StackLayout. Ten selektor jest niewrażliwy na wielkość liter. |
element>element |
stacklayout>label |
Wybiera wszystkie Label elementy z elementem StackLayout nadrzędnym bezpośrednim. Ten selektor jest niewrażliwy na wielkość liter. |
element+element |
label+entry |
Wybiera wszystkie Entry elementy bezpośrednio po elem.Label Ten selektor jest niewrażliwy na wielkość liter. |
element~element |
label~entry |
Wybiera wszystkie Entry elementy poprzedzone elementem Label. Ten selektor jest niewrażliwy na wielkość liter. |
Style z pasującymi selektorami są stosowane kolejno w kolejności definicji. Style zdefiniowane na określonym elemencie są zawsze stosowane jako ostatnie.
Napiwek
Selektory można łączyć bez ograniczeń, na przykład StackLayout>ContentView>label.email
.
Następujące selektory nie są obsługiwane:
[attribute]
@media
i@supports
:
i::
Uwaga
Specyfika i przesłonięcia specyficzne są nieobsługiwane.
Odwołanie do właściwości
Następujące właściwości CSS są obsługiwane przez program .NET MAUI (w kolumnie Wartości typy są kursywą, a literały ciągu to gray
):
Właściwości | Dotyczy | Wartości | Przykład |
---|---|---|---|
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 | Kolor | initial |
background-color: springgreen; |
background-image |
Page | string | initial |
background-image: bg.png; |
border-color |
Button, , FrameImageButton | Kolor | initial |
border-color: #9acd32; |
border-radius |
BoxView, , Button, , FrameImageButton | double | initial |
border-radius: 10; |
border-width |
Button, ImageButton | double | initial |
border-width: .5; |
color |
ActivityIndicator, BoxView, , , DatePickerLabelCheckBoxEntrySwitchEditorPickerProgressBarSearchBarButtonTimePicker | Kolor | 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 | zmiennoprzecinkowyinitial | auto | . Ponadto można określić wartość procentową w zakresie od 0% do 100% przy użyciu % znaku . |
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, LabelEntry, Picker, , TimePickerSearchBarSpan | string | initial |
font-family: Consolas; |
font-size |
Button, DatePicker, , Editor, LabelEntry, Picker, , TimePickerSearchBarSpan | double | initial |
font-size: 12; |
font-style |
Button, DatePicker, , Editor, LabelEntry, Picker, , TimePickerSearchBarSpan | 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, , , LabelSpanEntryPickerSearchBarSearchHandlerEditorTimePicker | double | initial |
letter-spacing: 2.5; |
line-height |
Label, Span | double | initial |
line-height: 1.8; |
margin |
View | grubość | initial |
margin: 6 12; |
margin-left |
View | grubość | initial |
margin-left: 3; |
margin-top |
View | grubość | initial |
margin-top: 2; |
margin-right |
View | grubość | initial |
margin-right: 1; |
margin-bottom |
View | grubość | 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, , LayoutPage | grubość | initial |
padding: 6 12 12; |
padding-left |
Button, , ImageButton, , LayoutPage | double | initial |
padding-left: 3; |
padding-top |
Button, , ImageButton, , LayoutPage | double | initial |
padding-top: 4; |
padding-right |
Button, , ImageButton, , LayoutPage | double | initial |
padding-right: 2; |
padding-bottom |
Button, , ImageButton, , LayoutPage | double | initial |
padding-bottom: 6; |
position |
FlexLayout | relative | absolute | initial |
position: absolute; |
row-gap |
Grid | double | initial |
row-gap: 12; |
text-align |
Entry, , EntryCell, , LabelSearchBar | left | top | right | bottom | start | center | middle | end | initial . left należy right unikać w środowiskach od prawej do lewej. |
text-align: right; |
text-decoration |
Label, Span | none | underline | strikethrough | line-through | initial |
text-decoration: underline, line-through; |
text-transform |
Button,Editor, Entry, Label, , , SearchBarSearchHandler | none | default | uppercase | lowercase | initial |
text-transform: uppercase; |
transform |
VisualElement | none , rotate , , , scale translate translateY rotateY scaleX scaleY translateX rotateX initial |
transform: rotate(180), scaleX(2.5); |
transform-origin |
VisualElement | podwójna, podwójna | 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; |
Uwaga
initial
jest prawidłową wartością dla wszystkich właściwości. Spowoduje to wyczyszczenie wartości (resetuje wartość domyślną), która została ustawiona z innego stylu.
Następujące właściwości nie są obsługiwane:
all: initial
.- Właściwości układu (pole lub siatka).
- Właściwości skrótu, takie jak
font
, iborder
.
Ponadto nie inherit
ma żadnej wartości i dlatego dziedziczenie nie jest obsługiwane. W związku z tym nie można na przykład ustawić font-size
właściwości w układzie i oczekiwać, że wszystkie Label wystąpienia w układzie będą dziedziczyć wartość. Jednym wyjątkiem jest direction
właściwość, która ma wartość inherit
domyślną .
Ważne
Span elementów nie można stosować przy użyciu arkuszy CSS.
Właściwości specyficzne dla interfejsu MAUI platformy .NET
Obsługiwane są również następujące właściwości CSS specyficzne dla programu .NET MAUI (w kolumnie Wartości typy są kursywą, a literały ciągu to gray
):
Właściwości | Dotyczy | Wartości | Przykład |
---|---|---|---|
-maui-bar-background-color |
NavigationPage, TabbedPage | Kolor | initial |
-maui-bar-background-color: teal; |
-maui-bar-text-color |
NavigationPage, TabbedPage | Kolor | 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, , EditorSearchBar | int | initial |
-maui-max-length: 20; |
-maui-max-track-color |
Slider | Kolor | initial |
-maui-max-track-color: red; |
-maui-min-track-color |
Slider | Kolor | initial |
-maui-min-track-color: yellow; |
-maui-orientation |
ScrollView, StackLayout | horizontal | vertical | both | initial . both program jest obsługiwany tylko w obiekcie ScrollView. |
-maui-orientation: horizontal; |
-maui-placeholder |
Entry, , EditorSearchBar | tekst cytowany | initial |
-maui-placeholder: Enter name; |
-maui-placeholder-color |
Entry, , EditorSearchBar | Kolor | initial |
-maui-placeholder-color: green; |
-maui-spacing |
StackLayout |
double | initial |
-maui-spacing: 8; |
-maui-thumb-color |
Slider, Switch | Kolor | 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; |
Właściwości specyficzne dla powłoki .NET MAUI
Obsługiwane są również następujące właściwości CSS specyficzne dla powłoki MAUI platformy .NET (w kolumnie Wartości typy są kursywą, a literały ciągu to gray
):
Właściwości | Dotyczy | Wartości | Przykład |
---|---|---|---|
-maui-flyout-background |
Shell | Kolor | initial |
-maui-flyout-background: red; |
-maui-shell-background |
Element | Kolor | initial |
-maui-shell-background: green; |
-maui-shell-disabled |
Element | Kolor | initial |
-maui-shell-disabled: blue; |
-maui-shell-foreground |
Element | Kolor | initial |
-maui-shell-foreground: yellow; |
-maui-shell-tabbar-background |
Element | Kolor | initial |
-maui-shell-tabbar-background: white; |
-maui-shell-tabbar-disabled |
Element | Kolor | initial |
-maui-shell-tabbar-disabled: black; |
-maui-shell-tabbar-foreground |
Element | Kolor | initial |
-maui-shell-tabbar-foreground: gray; |
-maui-shell-tabbar-title |
Element | Kolor | initial |
-maui-shell-tabbar-title: lightgray; |
-maui-shell-tabbar-unselected |
Element | Kolor | initial |
-maui-shell-tabbar-unselected: cyan; |
-maui-shell-title |
Element | Kolor | initial |
-maui-shell-title: teal; |
-maui-shell-unselected |
Element | Kolor | initial |
-maui-shell-unselected: limegreen; |
Color
Obsługiwane są następujące color
wartości:
X11
kolory, które są zgodne z kolorami CSS i kolorami MAUI platformy .NET. Te wartości kolorów są niewrażliwe na wielkość liter.- Kolory szesnastkowe:
#rgb
,#argb
, ,#rrggbb
#aarrggbb
- kolory rgb:
rgb(255,0,0)
,rgb(100%,0%,0%)
. Wartości znajdują się w zakresie od 0 do 255 lub 0%-100%. - kolory rgba:
rgba(255, 0, 0, 0.8)
,rgba(100%, 0%, 0%, 0.8)
. Wartość nieprzezroczystości znajduje się w zakresie od 0,0 do 1,0. - Kolory hsl:
hsl(120, 100%, 50%)
. Wartość h znajduje się w zakresie od 0 do 360, podczas gdy s i l znajdują się w zakresie 0%-100%. - Kolory hsla:
hsla(120, 100%, 50%, .8)
. Wartość nieprzezroczystości znajduje się w zakresie od 0,0 do 1,0.
Grubość
Obsługiwane są dwie, trzy lub cztery thickness
wartości, z których każda jest oddzielona białym znakiem:
- Pojedyncza wartość wskazuje jednolitą grubość.
- Dwie wartości wskazują pionową, a następnie poziomą grubość.
- Trzy wartości wskazują górną, a następnie poziomą (lewą i prawą), a następnie grubość dolnej.
- Cztery wartości wskazują górną, a następnie prawą, a następnie dolną, a następnie grubość po lewej stronie.
Uwaga
Wartości CSS thickness
różnią się od wartości XAML Thickness
. Na przykład w języku XAML wartość dwuwarta Thickness
wskazuje poziomą, a następnie pionową grubość, a cztery wartości Thickness
wskazują w lewo, a następnie górną, a następnie prawą, a następnie grubość dolną. Ponadto wartości XAML Thickness
są rozdzielane przecinkami.
Funkcje
Gradienty liniowe i promieniowe można określić odpowiednio przy użyciu linear-gradient()
funkcji i radial-gradient()
CSS. Wynik tych funkcji należy przypisać do background
właściwości kontrolki.