Поделиться через


Стили приложений с помощью каскадных таблиц стилей

Приложения многоплатформенного пользовательского интерфейса приложений .NET (.NET MAUI) можно стильировать с помощью каскадных таблиц стилей (CSS). Таблица стилей состоит из списка правил с каждым правилом, состоящим из одного или нескольких селекторов и блока объявления. Блок объявления состоит из списка объявлений в фигурных скобках с каждым объявлением, состоящим из свойства, двоеточия и значения. При наличии нескольких объявлений в блоке точка с запятой вставляется в качестве разделителя.

В следующем примере показан некоторый код CSS, совместимый с .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;
}

В .NET MAUI таблицы стилей CSS анализируются и оцениваются во время выполнения, а не во время компиляции, а таблицы стилей повторно анализируются при использовании.

Внимание

Невозможно полностью стиль приложения .NET MAUI с помощью CSS. Однако стили XAML можно использовать для дополнения CSS. Дополнительные сведения о стилях XAML см. в статье "Стили приложений с помощью XAML".

Использование таблицы стилей

Процесс добавления таблицы стилей в приложение .NET MAUI выглядит следующим образом:

  1. Добавьте пустой CSS-файл в проект приложения .NET MAUI. CSS-файл можно поместить в любую папку, а папка Resources — рекомендуемое расположение.
  2. Задайте для действия сборки CSS-файла значение MauiCss.

Загрузка таблицы стилей

Существует ряд подходов, которые можно использовать для загрузки таблицы стилей.

Примечание.

Невозможно изменить таблицу стилей во время выполнения и применить новую таблицу стилей.

Загрузка таблицы стилей в XAML

Таблицу стилей можно загрузить и проанализировать с StyleSheet классом ResourceDictionaryперед добавлением в :

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

Свойство StyleSheet.Source задает таблицу стилей в виде URI относительно расположения включающего XAML-файла или относительно корневого каталога проекта, если универсальный код ресурса (URI) начинается с /.

Предупреждение

CSS-файл не будет загружаться, если его действие сборки не задано для MauiCss.

Кроме того, таблицу стилей можно загрузить и проанализировать с StyleSheet классом, прежде чем добавлять его в ResourceDictionaryCDATA раздел.

<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 селектор будет определять ListView атрибут, для которого x:Name задано 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;
}

Класс CSS можно назначить элементу XAML, задав StyleClass свойству элемента имя класса CSS. Поэтому в следующем примере стили, определенные классом, назначаются первомуLabel, а стили, определенные .detailPageTitle .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;
}

Этот селектор определяет все Image элементы, которые являются дочерними элементами ListView элементов, и задает их высоту и ширину 60. Таким образом, listview image в следующем примере XAML селектор будет определять Image дочерний ListViewобъект и задает его высоту и ширину 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>

Примечание.

element element Селектор не требует, чтобы дочерний элемент был прямым дочерним элементом родительского элемента— дочерний элемент может иметь другой родительский элемент. Выбор происходит при условии, что предок является указанным первым элементом.

Выбор прямых дочерних элементов

Прямые дочерние элементы в визуальном дереве можно выбрать с помощью нечувствительного element>element селектора регистра:

stacklayout>image {
    height: 200;
    width: 200;
}

Этот селектор определяет все Image элементы, которые являются прямыми дочерними элементами StackLayout элементов, и задает их высоту и ширину 200. Таким образом, stacklayout>image в следующем примере селектор будет определять Image прямой дочерний элемент и StackLayoutзадает его высоту и ширину 200.

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

Примечание.

element>element Селектор требует, чтобы дочерний элемент был прямым дочерним элементом родительского элемента.

Справочник по селектору

Следующие селекторы CSS поддерживаются .NET MAUI:

Выбор Пример Description
.class .header Выбирает все элементы со свойством StyleClass , содержащим "заголовок". Этот селектор учитывает регистр.
#id #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 Выбирает все Label элементы внутри StackLayout. Этот селектор не учитывает регистр.
element>element stacklayout>label Выбирает все Label элементы с StackLayout прямым родительским элементом. Этот селектор не учитывает регистр.
element+element label+entry Выбирает все Entry элементы непосредственно после Label. Этот селектор не учитывает регистр.
element~element label~entry Выбирает все Entry элементы, предшествующие объекту Label. Этот селектор не учитывает регистр.

Стили с селекторами сопоставления применяются последовательно в порядке определения. Стили, определенные для определенного элемента, всегда применяются последним.

Совет

Селекторы можно объединить без ограничений, например StackLayout>ContentView>label.email.

Следующие селекторы не поддерживаются:

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

Примечание.

Особенности и переопределения конкретности не поддерживаются.

Справочные данные по свойствам

Следующие свойства CSS поддерживаются .NET MAUI (в столбце "Значения", типы являются курсивными, а строковые литералы ):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 color | initial background-color: springgreen;
background-image Page string | initial background-image: bg.png;
border-color Button, , FrameImageButton color | initial border-color: #9acd32;
border-radius BoxView, , ButtonFrameImageButton double | initial border-radius: 10;
border-width Button, ImageButton double | initial border-width: .5;
color ActivityIndicator, BoxView, ButtonCheckBoxDatePickerEditorEntryLabelPickerProgressBarSearchBarSwitchTimePicker 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 float | | autoinitial. Кроме того, можно указать процент в диапазоне от 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, DatePickerEditorEntryLabelPickerSearchBarTimePickerSpan string | initial font-family: Consolas;
font-size Button, DatePickerEditorEntryLabelPickerSearchBarTimePickerSpan double | initial font-size: 12;
font-style Button, DatePickerEditorEntryLabelPickerSearchBarTimePickerSpan 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, EditorEntryLabelPickerSearchBarSearchHandlerSpanTimePicker double | initial letter-spacing: 2.5;
line-height Label, Span double | initial line-height: 1.8;
margin View толщина | initial margin: 6 12;
margin-left View толщина | initial margin-left: 3;
margin-top View толщина | initial margin-top: 2;
margin-right View толщина | initial margin-right: 1;
margin-bottom View толщина | 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, , ImageButtonLayoutPage толщина | initial padding: 6 12 12;
padding-left Button, , ImageButtonLayoutPage double | initial padding-left: 3;
padding-top Button, , ImageButtonLayoutPage double | initial padding-top: 4;
padding-right Button, , ImageButtonLayoutPage double | initial padding-right: 2;
padding-bottom Button, , ImageButtonLayoutPage double | initial padding-bottom: 6;
position FlexLayout relative | absolute | initial position: absolute;
row-gap Grid double | initial row-gap: 12;
text-align Entry, , EntryCellLabelSearchBar 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, , LabelEntry, SearchBarSearchHandler none | default | uppercase | lowercase | initial text-transform: uppercase;
transform VisualElement none, rotate, rotateXrotateYscalescaleXscaleYtranslatetranslateXtranslateYinitial 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;

Примечание.

initial является допустимым значением для всех свойств. Он очищает значение (сбрасывается по умолчанию), которое было задано из другого стиля.

Следующие свойства не поддерживаются.

  • all: initial.
  • Свойства макета (поле или сетка).
  • Короткие свойства, такие как font, и border.

Кроме того, нет inherit значения и поэтому наследование не поддерживается. Поэтому нельзя, например, задать font-size свойство макета и ожидать, что все Label экземпляры в макете наследуют значение. Одним из исключений direction является свойство, которое имеет значение inheritпо умолчанию.

Внимание

Span Элементы нельзя использовать с помощью CSS.

Определенные свойства .NET MAUI

Также поддерживаются следующие свойства CSS для .NET MAUI (в столбце "Значения", типы являются курсивными, а строковые литералы):gray

Свойство Применяется к Значения Пример
-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, , EditorSearchBar 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, , EditorSearchBar в кавычках текст | initial -maui-placeholder: Enter name;
-maui-placeholder-color Entry, , EditorSearchBar 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

Также поддерживаются следующие свойства CSS для .NET MAUI Shell (в столбце "Значения", типы являются курсивными, а строковые литералы):gray

Свойство Применяется к Значения Пример
-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;

Color

Поддерживаются следующие color значения:

  • X11цвета, соответствующие цветам CSS и цветам .NET MAUI. Эти значения цвета являются нечувствительными к регистру.
  • шестнадцатеричные цвета: #rgb, #argb, #rrggbb#aarrggbb
  • rgb colors: 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 значения, разделенные пробелами:

  • Одно значение указывает на единую толщину.
  • Два значения указывают вертикальную, а затем горизонтальную толщину.
  • Три значения указывают верхнюю, а затем горизонтальную (левую и правую), а затем толщину нижнего.
  • Четыре значения указывают верхнюю, а затем справа, а затем внизу, а затем левую толщину.

Примечание.

Значения CSS thickness отличаются от значений XAML Thickness . Например, в XAML двухзначное значение Thickness указывает горизонтальную и вертикальную толщину, а четыре значения Thickness — левую, а затем верхнюю, а затем справа, а затем толщину нижнего. Кроме того, значения XAML Thickness разделены запятыми.

Функции

Линейные и радиальные градиенты можно указать с помощью linear-gradient() функций и radial-gradient() CSS соответственно. Результат этих функций должен быть назначен background свойству элемента управления.