Xamarin.Forms 支持使用级联样式表 (CSS) 设置视觉元素样式。

Xamarin.Forms 应用程序可以使用 CSS 进行样式设置。 样式表由规则列表组成,每个规则由一个或多个选择器和声明块组成。 声明块由大括号中的声明列表组成,每个声明由属性、冒号和值组成。 当块中有多个声明时,分号将作为分隔符插入。 下面的代码示例显示了一些 Xamarin.Forms 合规的 CSS:

navigationpage {
    -xf-bar-background-color: lightgray;
^contentpage {
    background-color: lightgray;
#listView {
    background-color: lightgray;
stacklayout {
    margin: 20;
.mainPageTitle {
    font-style: bold;
    font-size: medium;
.mainPageSubtitle {
    margin-top: 15;
.detailPageTitle {
    font-style: bold;
    font-size: medium;
    text-align: center;
.detailPageSubtitle {
    text-align: center;
    font-style: italic;
listview image {
    height: 60;
    width: 60;
stacklayout>image {
    height: 200;
    width: 200;

在 Xamarin.Forms中,CSS 样式表在运行时进行分析和评估,而不是编译时,并重新分析使用的样式表。

目前,XAML 样式可能的所有样式都不能使用 CSS 执行。 但是,XAML 样式可用于补充当前不受支持 Xamarin.Forms的属性的 CSS。 有关 XAML 样式的详细信息,请参阅使用 XAML 样式设置 Xamarin.Forms 应用的样式

MonkeyAppCSS 示例演示了如何使用 CSS 设置简单应用的样式,并显示在以下屏幕截图中:

使用样式表

将样式表添加到解决方案的过程如下所示:

  • 将空 CSS 文件添加到 .NET Standard 库项目。
  • 将 CSS 文件的生成操作设置为 EmbeddedResource
  • 加载样式表

    有多种方法可用于加载样式表。

    目前无法在运行时更改样式表并应用新的样式表。

    在添加到ResourceDictionary以下项之前,可以加载并分析样式表与StyleSheet类:

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

    StyleSheet.Source 属性将样式表指定为相对于封闭 XAML 文件的位置的 URI,或相对于项目根目录(如果 URI 以 a /开头)。

    如果未将其生成操作设置为 EmbeddedResource,CSS 文件将无法加载。

    或者,可以通过将样式表内联CDATA到节中,在添加到类ResourceDictionary之前加载和分析StyleSheet样式表:

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

    有关资源字典的详细信息,请参阅 资源字典

    在 C# 中,可以从以下项加载 StringReader 样式表并将其添加到 ResourceDictionary

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

    方法的参数 StyleSheet.FromReaderTextReader 已读取样式表的参数。

    选择元素并应用属性

    CSS 使用选择器来确定要面向的元素。 按定义顺序连续应用具有匹配选择器的样式。 对特定项定义的样式始终最后应用。 有关受支持的选择器的详细信息,请参阅 选择器参考

    CSS 使用属性设置所选元素的样式。 每个属性都有一组可能的值,某些属性可能会影响任何类型的元素,而另一些属性则应用于元素组。 有关支持的属性的详细信息,请参阅 属性参考

    如果子样式表设置相同的属性,则子样式表始终重写父样式表。 因此,应用设置相同属性的样式时,会遵循以下优先规则:

  • 应用程序资源中定义的样式将被页面资源中定义的样式覆盖(如果它们设置了相同的属性)。
  • 如果控件资源中定义的样式设置相同的属性,页面资源中定义的样式将被覆盖。
  • 如果控件资源中定义了相同的属性,则应用程序资源中定义的样式将被覆盖。
  • 不支持 CSS 变量。

    按类型选择元素

    可以通过类型选择可视化树中的元素,并采用不区分 element 大小写的选择器:

    stacklayout {
        margin: 20;
    

    此选择器标识使用样式表的页面上的任何 StackLayout 元素,并将页边距设置为统一的粗细 20。

    element选择器不标识指定类型的子类。

    按基类选择元素

    可以通过基类选择可视化树中的元素,并采用不区分 ^base 大小写的选择器:

    ^contentpage {
        background-color: lightgray;
    

    此选择器标识使用样式表的任何 ContentPage 元素,并将其背景色设置为 lightgray

    选择 ^base 器特定于 Xamarin.FormsCSS 规范,不是 CSS 规范的一部分。

    按名称选择元素

    可以使用区分 #id 大小写的选择器选择可视化树中的单个元素:

    #listView {
        background-color: lightgray;
    

    此选择器标识其 StyleId 属性设置为 listView的元素。 但是,如果未设置属性 StyleId ,选择器将回退到使用 x:Name 元素。 因此,在以下 XAML 示例中, #listView 选择器将标识 ListViewx:Name 属性设置为 listView,并将其背景色设置为 lightgray

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

    选择具有特定类属性的元素

    可以使用区分 .class 大小写的选择器选择具有特定类属性的元素:

    .detailPageTitle {
        font-style: bold;
        font-size: medium;
        text-align: center;
    .detailPageSubtitle {
        text-align: center;
        font-style: italic;
    

    通过将元素的属性设置为 StyleClass CSS 类名称,可以将 CSS 类分配给 XAML 元素。 因此,在以下 XAML 示例中,类定义的 .detailPageTitle 样式将分配给第一 Label个,而类定义的 .detailPageSubtitle 样式则分配给第二个 Label样式。

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

    选择子元素

    可以使用不区分 element element 大小写的选择器选择可视化树中的子元素:

    listview image {
        height: 60;
        width: 60;
    

    此选择器标识元素 ImageListView 子元素,并将其高度和宽度设置为 60。 因此,在以下 XAML 示例中, listview image 选择器将标识 Image 其子级 ListView,并将其高度和宽度设置为 60。

    <ContentPage ...>
        <ContentPage.Resources>
            <StyleSheet Source="/Assets/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;
    

    此选择器标识任何 Image 直接子元素的 StackLayout 元素,并将其高度和宽度设置为 200。 因此,在以下 XAML 示例中, stacklayout>image 选择器将标识 ImageStackLayout子级,并将其高度和宽度设置为 200。

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

    element>element选择器要求子元素是父级的直接子元素。

    选择器参考

    以下 CSS 选择器受以下 Xamarin.Forms支持:

    #email Selects all elements with StyleId set to email. 如果未 StyleId 设置,则回退到 x:Name。 使用 XAML 时, x:Name 首选使用 StyleIdXAML。 请注意,此选择器区分大小写。 选择所有元素。 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
  • :::
  • 不支持特定性和特定性替代。

    列中 (支持Xamarin.Forms以下 CSS 属性,类型为斜体,而字符串文本gray) :

    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 颜色 | initial background-color: springgreen; background-image 字符串 | initial background-image: bg.png; border-color Button, Frame, ImageButton 颜色 | initial border-color: #9acd32; border-radius BoxView, Button, Frame, ImageButton | initial border-radius: 10; border-width Button, ImageButton | initial border-width: .5; color ActivityIndicator, BoxView, Button, CheckBox, DatePicker, Editor, Entry, Label, Picker, ProgressBar, SearchBar, Switch, TimePicker 颜色 | initial color: rgba(255, 0, 0, 0.3); column-gap | 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 浮动 | initial flex-grow: 1.5; flex-shrink VisualElement 浮动 | 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 | namedsize | initial font-size: 12; font-style Button, DatePicker, Editor, Entry, Label, Picker, SearchBar, TimePicker, Span bold | italic | initial font-style: bold; height VisualElement | initial min-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 | initial letter-spacing: 2.5; line-height Label, Span | initial line-height: 1.8; margin 厚度 | initial margin: 6 12; margin-left 厚度 | initial margin-left: 3; margin-top 厚度 | initial margin-top: 2; margin-right 厚度 | initial margin-right: 1; margin-bottom 厚度 | initial margin-bottom: 6; max-lines Label Int | initial max-lines: 2; min-height VisualElement | initial min-height: 50; min-width VisualElement | initial min-width: 112; opacity VisualElement | initial opacity: .3; order VisualElement Int | initial order: -1; padding Button, ImageButton, Layout, Page 厚度 | initial padding: 6 12 12; padding-left Button, ImageButton, Layout, Page | initial padding-left: 3; padding-top Button, ImageButton, Layout, Page | initial padding-top: 4; padding-right Button, ImageButton, Layout, Page | initial padding-right: 2; padding-bottom Button, ImageButton, Layout, Page | initial padding-bottom: 6; position FlexLayout relative | absolute | initial position: absolute; row-gap | initial row-gap: 12; text-align Entry, EntryCell, Label, SearchBar left | top | right | bottom | start | center | middle | end | initial. leftright 避免在从右到左的环境中使用。 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 doubledouble | 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 | initial min-width: 320;
  • 速记属性,如 fontborder
  • 此外,没有 inherit 值,因此不支持继承。 因此,不能在布局上设置 font-size 属性,并期望布局中的所有 Label 实例继承该值。 一个例外是 direction 属性,该属性的默认值为 inherit.

    目标 Span 元素有一个已知问题,阻止使用符号) 元素和名称 (# 成为 CSS 样式的目标。 元素 Span 派生自 GestureElement该属性, StyleClass 因此跨度不支持 CSS 类目标。 有关详细信息,请参阅 无法将 CSS 样式应用于 Span 控件

    Xamarin.Forms 特定属性

    列中还支持以下Xamarin.Forms特定的 CSS 属性 (,类型为斜体,而字符串文本) gray

    -xf-orientation ScrollView, StackLayout horizontal | vertical | both | initial. both 仅在一个 ScrollView. -xf-orientation: horizontal; -xf-placeholder Entry, Editor, SearchBar 带引号的文本 | initial -xf-placeholder: Enter name; -xf-placeholder-color Entry, Editor, SearchBar 颜色 | initial -xf-placeholder-color: green; -xf-spacing StackLayout | initial -xf-spacing: 8; -xf-thumb-color Slider, Switch 颜色 | initial -xf-thumb-color: limegreen; -xf-vertical-scroll-bar-visibility ScrollView default | always | never | initial -xf-vertical-scroll-bar-visibility: always; -xf-vertical-text-alignment Label start | center | end | initial -xf-vertical-text-alignment: end; -xf-visual VisualElement 字符串 | initial -xf-visual: material;

    Xamarin.Forms Shell 特定属性

    ”列中还支持以下Xamarin.Forms特定于 Shell 的 CSS 属性 (,类型为斜体,而字符串文本gray) :

  • X11 CSS 颜色、UWP 预定义颜色和 Xamarin.Forms 颜色匹配的颜色。 请注意,这些颜色值不区分大小写。
  • 十六进制颜色:#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 值以逗号分隔。

    NamedSize

    支持以下不区分 namedsize 大小写的值:

  • default
  • micro
  • small
  • medium
  • large
  • 每个 namedsize 值的确切含义与平台相关且依赖于视图。

    可以使用和 CSS 函数分别指定linear-gradient()radial-gradient()线性和径向渐变。 应将这些函数的结果分配给 background 控件的属性。

    使用 Xamarin.University 的 Xamarin.Forms CSS

    Xamarin.Forms 3.0 CSS 视频

  • MonkeyAppCSS (示例)
  • 使用 XAML 样式设置 Xamarin.Forms 应用的样式
  •