可以使用级联样式表 (CSS) 为.NET Multi-platform App UI (.NET MAUI) 应用设置样式。 样式表由规则列表组成,每个规则由一个或多个选择器和声明块组成。 声明块由放在大括号中的声明列表组成,每个声明由属性、冒号和值组成。 当块中有多个声明时,将插入分号作为分隔符。
以下示例展示了一些适用于 .NET MAUI 的 CSS:
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;
在 .NET MAUI 中,会在运行时(而不是编译时)分析和计算 CSS 样式表,并在使用时重新分析样式表。
无法使用 CSS 对 .NET MAUI 应用的样式进行全面设置。 但是,作为 CSS 的补充,可以使用 XAML 样式。 有关 XAML 样式的详细信息,请参阅使用 XAML 设置应用的样式。
使用样式表
将样式表添加到 .NET MAUI 应用的过程如下所示:
将空 CSS 文件添加到 .NET MAUI 应用项目。 可以将 CSS 文件放在任何文件夹中,但建议放在 Resources 文件夹中。
将 CSS 文件的生成操作设置为 MauiCss。
加载样式表
有多种方法可用于加载样式表。
无法在运行时更改样式表并应用新的样式表。
在 XAML 中加载样式表
将样式表添加到 ResourceDictionary 之前,可以使用 StyleSheet
类加载和分析样式表:
<Application ...>
<Application.Resources>
<StyleSheet Source="/Resources/styles.css" />
</Application.Resources>
</Application>
StyleSheet.Source
属性将样式表指定为相对于封闭 XAML 文件位置的 URI,如果 URI 以 /
开头,则将样式表指定为相对于项目根目录的 URI。
如果未将 CSS 文件的生成操作设置为 MauiCss,则将无法加载此文件。
或者,在将样式表添加到 ResourceDictionary 之前,可以通过将其内联到 CDATA
部分中,使用 StyleSheet
类加载和分析样式表:
<ContentPage ...>
<ContentPage.Resources>
<StyleSheet>
<![CDATA[
^contentpage {
background-color: lightgray;
</StyleSheet>
</ContentPage.Resources>
</ContentPage>
要详细了解资源字典,请参阅资源字典。
在 C# 中加载样式表
在 C# 中,可以从 StringReader
加载样式表并将其添加到 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));
StyleSheet.FromReader
方法的参数是已读取样式表的 TextReader
。
选择元素并应用属性
CSS 使用选择器来确定目标元素。 会按定义顺序连续应用具有匹配选择器的样式。 会在最后应用针对特定项定义的样式。 有关支持的选择器的详细信息,请参阅选择器引用。
CSS 使用属性为所选元素设置样式。 每个属性都有一组可能的值,一些属性可以影响任何类型的元素,而另一些属性则适用于元素组。 有关支持的属性的详细信息,请参阅属性引用。
如果子样式表设置相同的属性,则子样式表会始终替代父样式表。 因此,在应用设置了相同属性的样式时,将遵循以下优先规则:
应用资源中定义的样式将被页面资源中定义的样式覆盖(如果它们设置了相同的属性)。
页面资源中定义的样式将被控件资源中定义的样式覆盖(如果它们设置了相同的属性)。
应用资源中定义的样式将被控件资源中定义的样式覆盖(如果它们设置了相同的属性)。
不支持 CSS 变量。
按类型选择元素
可以使用不区分大小写的 element
选择器按类型选择可视化树中的元素:
stacklayout {
margin: 20;
此选择器会标识使用样式表的页面上的任何 StackLayout 元素,并将其边距设置为统一厚度 20。
element
选择器不标识指定类型的子类。
按基类选择元素
可以使用不区分大小写的 ^base
选择器按基类选择可视化树中的元素:
^contentpage {
background-color: lightgray;
此选择器可标识使用样式表的任何 ContentPage 元素,并将其背景色设置为 lightgray
。
^base
选择器特定于 .NET MAUI,不属于 CSS 规范。
按名称选择元素
可以使用区分大小写的 #id
选择器来选择可视化树中的单个元素:
#listView {
background-color: lightgray;
此选择器可标识其 StyleId
属性被设置为 listView
的元素。 但是,如果未设置 StyleId
属性,则选择器将回退以使用元素的 x:Name
。 因此,在以下示例中,#listView
选择器将标识其 x:Name
特性被设置为 listView
的 ListView,并将其背景色设置为 lightgray
。
<ContentPage ...>
<ContentPage.Resources>
<StyleSheet Source="/Resources/styles.css" />
</ContentPage.Resources>
<StackLayout>
<ListView x:Name="listView">
</ListView>
</StackLayout>
</ContentPage>
选择具有特定类特性的元素
可以使用区分大小写的 .class
选择器来选择具有特定类特性的元素:
.detailPageTitle {
font-style: bold;
font-size: 14;
text-align: center;
.detailPageSubtitle {
text-align: center;
font-style: italic;
可以通过将元素的 StyleClass
属性设置为 CSS 类名,将 CSS 类分配给 XAML 元素。 因此,在以下示例中,将 .detailPageTitle
类定义的样式分配给第一个 Label,而将 .detailPageSubtitle
类定义的样式分配给第二个 Label。
<ContentPage ...>
<ContentPage.Resources>
<StyleSheet Source="/Resources/styles.css" />
</ContentPage.Resources>
<ScrollView>
<StackLayout>
<Label ... StyleClass="detailPageTitle" />
<Label ... StyleClass="detailPageSubtitle"/>
</StackLayout>
</ScrollView>
</ContentPage>
选择子元素
可以使用不区分大小写的 element element
选择器来选择可视化树中的子元素:
listview image {
height: 60;
width: 60;
此选择器可标识所有作为 ListView 元素的子元素的 Image 元素,并将其高度和宽度设置为 60。 因此,在以下 XAML 示例中,listview image
选择器将标识作为 ListView 子级的 Image,并将其高度和宽度设置为 60。
<ContentPage ...>
<ContentPage.Resources>
<StyleSheet Source="/Resources/styles.css" />
</ContentPage.Resources>
<StackLayout>
<ListView ...>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Image ... />
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>
element element
选择器不要求子元素是父元素的直接子级 - 子元素可能有不同的父元素。 如果上级是指定的第一个元素,则会进行选择。
选择直接子元素
可以使用不区分大小写的 element>element
选择器来选择可视化树中的直接子元素:
stacklayout>image {
height: 200;
width: 200;
此选择器可识别所有作为 StackLayout 元素的直接子元素的 Image 元素,并将其高度和宽度设置为 200。 因此,在以下示例中,stacklayout>image
选择器将标识作为 StackLayout 的直接子元素的 Image,并将其高度和宽度设置为 200。
<ContentPage ...>
<ContentPage.Resources>
<StyleSheet Source="/Resources/styles.css" />
</ContentPage.Resources>
<ScrollView>
<StackLayout>
<Image ... />
</StackLayout>
</ScrollView>
</ContentPage>
element>element
选择器要求子元素是父元素的直接子级。
选择器引用
.NET MAUI 支持以下 CSS 选择器:
#email
选择其 StyleId
被设置为 email
的所有元素。 如果未设置 StyleId
,则回退到 x:Name
。 使用 XAML 时,首选 x:Name
而不是 StyleId
。 此选择器区分大小写。
选择所有元素。
element
label
选择类型为 Label 的所有元素,但不选择子类。 此选择器不区分大小写。
^base
^contentpage
选择其 ContentPage 被用作基类的所有元素,包括 ContentPage 本身。 此选择器不区分大小写,不属于 CSS 规范。
element,element
label,button
选择所有 Button 元素和所有 Label 元素。 此选择器不区分大小写。
element element
stacklayout label
选择 StackLayout 中的所有 Label 元素。 此选择器不区分大小写。
element>element
stacklayout>label
选择 StackLayout 的所有 Label 元素作为直接父级。 此选择器不区分大小写。
element+element
label+entry
直接选择 Label 之后的所有 Entry 元素。 此选择器不区分大小写。
element~element
label~entry
选择前面是 Label 的所有 Entry 元素。 此选择器不区分大小写。
会按定义顺序连续应用具有匹配选择器的样式。 会在最后应用针对特定项定义的样式。
选择器可以不受限制地组合在一起,例如 StackLayout>ContentView>label.email
。
不支持以下选择器:
[attribute]
@media
和 @supports
:
和 ::
不支持特异性和特异性替代。
.NET MAUI 支持以下 CSS 属性(在“值”列中,类型为“斜体”,而字符串文本为 gray
):
properties
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
字符串 | 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
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
。 此外,可以使用 %
符号指定介于 0% 到 100% 之间的百分比。
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
字符串 | 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
thickness | initial
margin: 6 12;
margin-left
thickness | initial
margin-left: 3;
margin-top
thickness | initial
margin-top: 2;
margin-right
thickness | initial
margin-right: 1;
margin-bottom
thickness | 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
thickness | 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
double | initial
row-gap: 12;
text-align
Entry、EntryCell、Label、SearchBar
left
| top
| right
| bottom
| start
| center
| middle
| end
| initial
。 在从右到左的环境中应避免 left
和 right
。
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;
速记属性,如 font
和 border
。
此外,没有 inherit
值,因此不支持继承。 因此,无法在布局上设置 font-size
属性,也无法让布局中的所有 Label 实例都继承该值。 唯一例外是 direction
属性,其默认值为 inherit
。
不能使用 CSS 将 Span 元素设为目标。
.NET MAUI 特定属性
还支持以下特定于 .NET MAUI 的 CSS 属性(在“值”列中,类型为“斜体”,而字符串文本为 gray
):
properties
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
仅在 ScrollView 上受支持。
-maui-orientation: horizontal;
-maui-placeholder
Entry、Editor、SearchBar
quoted text | 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;
.NET MAUI Shell 特定属性
还支持以下特定于 .NET MAUI Shell 的 CSS 属性(在“值”列中,类型为“斜体”,而字符串文本为 gray
):
properties
X11
颜色,它与 CSS 颜色和 .NET MAUI 颜色匹配。 这些颜色值不区分大小写。
hex 颜色:#rgb
、#argb
、#rrggbb
、#aarrggbb
rgb 颜色:rgb(255,0,0)
、rgb(100%,0%,0%)
。 值在 0-255 或 0%-100% 范围内。
rgba 颜色:rgba(255, 0, 0, 0.8)
、rgba(100%, 0%, 0%, 0.8)
。 不透明度值介于 0.0-1.0 之间。
hsl 颜色:hsl(120, 100%, 50%)
。 h 值介于 0-360 之间,而 s 和 l 值介于 0%-100% 之间。
hsla 颜色:hsla(120, 100%, 50%, .8)
。 不透明度值介于 0.0-1.0 之间。
Thickness
支持一个、两个、三个或四个 thickness
值,每个值用空格分隔:
单个值指示统一的厚度。
两个值指示垂直和水平厚度。
三个值指示顶部、水平(左和右),以及底部厚度。
四个值指示上、右、下、左的厚度。
CSS thickness
值不同于 XAML Thickness
值。 例如,在 XAML 中,两个值 Thickness
指示水平和垂直厚度,而四个值 Thickness
表示左、上、右、下的厚度。 此外,XAML Thickness
值以逗号分隔。
可以分别使用 linear-gradient()
和 radial-gradient()
CSS 函数指定线性和径向渐变。 应将这些函数的结果分配给控件的 background
属性。