Стили приложений с помощью каскадных таблиц стилей
Приложения многоплатформенного пользовательского интерфейса приложений .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 выглядит следующим образом:
- Добавьте пустой CSS-файл в проект приложения .NET MAUI. CSS-файл можно поместить в любую папку, а папка Resources — рекомендуемое расположение.
- Задайте для действия сборки 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 | | 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, 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 , 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; |
Примечание.
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
свойству элемента управления.