Estilizar aplicativos usando folhas de estilos em cascata
Os aplicativos .NET Multi-Platform App UI (.NET MAUI) podem ser estilizados usando CSS (Folhas de Estilos em Cascata). Uma folha de estilos consiste em uma lista de regras, com cada regra consistindo em um ou mais seletores e um bloco de declaração. Um bloco de declaração consiste em uma lista de declarações em chaves, com cada declaração consistindo em uma propriedade, dois pontos e um valor. Quando há várias declarações em um bloco, um ponto-e-vírgula é inserido como um separador.
O exemplo a seguir mostra alguns CSS compatíveis com .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;
}
No .NET MAUI, as folhas de estilo CSS são analisadas e avaliadas em tempo de execução, em vez de tempo de compilação, e as folhas de estilo são reanalisadas em uso.
Importante
Não é possível estilizar totalmente um aplicativo .NET MAUI usando CSS. No entanto, os estilos XAML podem ser usados para complementar o CSS. Para obter mais informações sobre estilos XAML, consulte Estilizar aplicativos usando XAML.
Consumir uma folha de estilos
O processo para adicionar uma folha de estilos a um aplicativo .NET MAUI é o seguinte:
- Adicione um arquivo CSS vazio ao seu projeto de aplicativo .NET MAUI. O arquivo CSS pode ser colocado em qualquer pasta, com a pasta Recursos sendo o local recomendado.
- Defina a ação de compilação do arquivo CSS como MauiCss.
Carregando uma folha de estilos
Há várias abordagens que podem ser usadas para carregar uma folha de estilos.
Observação
Não é possível alterar uma folha de estilos em tempo de execução e aplicar a nova folha de estilos.
Carregar uma folha de estilos em XAML
Uma folha de estilos pode ser carregada e analisada com a classe antes de ser adicionada a StyleSheet
um ResourceDictionary:
<Application ...>
<Application.Resources>
<StyleSheet Source="/Resources/styles.css" />
</Application.Resources>
</Application>
A StyleSheet.Source
propriedade especifica a folha de estilos como um URI relativo ao local do arquivo XAML de delimitação, ou relativo à raiz do projeto se o URI começar com um /
arquivo .
Aviso
O arquivo CSS falhará ao carregar se sua ação de compilação não estiver definida como MauiCss.
Como alternativa, uma folha de estilos pode ser carregada e analisada com a classe, antes de ser adicionada a um ResourceDictionary, inserindo-a StyleSheet
em uma CDATA
seção:
<ContentPage ...>
<ContentPage.Resources>
<StyleSheet>
<![CDATA[
^contentpage {
background-color: lightgray;
}
]]>
</StyleSheet>
</ContentPage.Resources>
...
</ContentPage>
Para obter mais informações sobre dicionários de recursos, consulte Dicionários de recursos.
Carregar uma folha de estilos em C#
Em C#, uma folha de estilos pode ser carregada de um e adicionada a um 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));
}
}
}
O argumento para o método é o StyleSheet.FromReader
TextReader
que leu a folha de estilos.
Selecionar elementos e aplicar propriedades
O CSS usa seletores para determinar quais elementos serão direcionados. Os estilos com seletores correspondentes são aplicados consecutivamente, em ordem de definição. Os estilos definidos em um item específico são sempre aplicados por último. Para obter mais informações sobre seletores com suporte, consulte Referência do seletor.
CSS usa propriedades para estilizar um elemento selecionado. Cada propriedade tem um conjunto de valores possíveis, e algumas propriedades podem afetar qualquer tipo de elemento, enquanto outras se aplicam a grupos de elementos. Para obter mais informações sobre propriedades com suporte, consulte Referência de propriedade.
As folhas de estilo filho sempre substituem as folhas de estilo pai se definirem as mesmas propriedades. Portanto, as seguintes regras de precedência são seguidas ao aplicar estilos que definem as mesmas propriedades:
- Um estilo definido nos recursos do aplicativo será substituído por um estilo definido nos recursos da página, se eles definirem as mesmas propriedades.
- Um estilo definido nos recursos de página será substituído por um estilo definido nos recursos de controle, se eles definirem as mesmas propriedades.
- Um estilo definido nos recursos do aplicativo será substituído por um estilo definido nos recursos de controle, se eles definirem as mesmas propriedades.
Observação
Não há suporte para variáveis CSS.
Selecionar elementos por tipo
Os elementos na árvore visual podem ser selecionados por tipo com o seletor sem diferenciação element
de maiúsculas e minúsculas:
stacklayout {
margin: 20;
}
Esse seletor identifica quaisquer StackLayout elementos nas páginas que consomem a folha de estilos e define suas margens para uma espessura uniforme de 20.
Observação
O element
seletor não identifica subclasses do tipo especificado.
Selecionando elementos por classe base
Os elementos na árvore visual podem ser selecionados por classe base com o seletor sem diferenciação ^base
de maiúsculas e minúsculas:
^contentpage {
background-color: lightgray;
}
Esse seletor identifica todos os ContentPage elementos que consomem a folha de estilos e define sua cor de plano de fundo como lightgray
.
Observação
O ^base
seletor é específico para .NET MAUI e não faz parte da especificação CSS.
Selecionando um elemento por nome
Elementos individuais na árvore visual podem ser selecionados com o seletor de diferenciação de maiúsculas #id
e minúsculas:
#listView {
background-color: lightgray;
}
Esse seletor identifica o elemento cuja StyleId
propriedade está definida como listView
. No entanto, se a propriedade não estiver definida, o seletor voltará a StyleId
usar o x:Name
do elemento . Portanto, no exemplo a seguir, o #listView
seletor identificará o ListView atributo cujo x:Name
está definido como , e definirá sua cor de plano de fundo como listView
lightgray
.
<ContentPage ...>
<ContentPage.Resources>
<StyleSheet Source="/Resources/styles.css" />
</ContentPage.Resources>
<StackLayout>
<ListView x:Name="listView">
...
</ListView>
</StackLayout>
</ContentPage>
Selecionar elementos com um atributo de classe específico
Os elementos com um atributo de classe específico podem ser selecionados com o seletor que diferencia maiúsculas de minúsculas .class
:
.detailPageTitle {
font-style: bold;
font-size: 14;
text-align: center;
}
.detailPageSubtitle {
text-align: center;
font-style: italic;
}
Uma classe CSS pode ser atribuída a um elemento XAML definindo a StyleClass
propriedade do elemento como o nome da classe CSS. Portanto, no exemplo a seguir, os estilos definidos pela classe são atribuídos ao primeiro , enquanto os estilos definidos pela .detailPageTitle
.detailPageSubtitle
classe são atribuídos ao segundoLabel.Label
<ContentPage ...>
<ContentPage.Resources>
<StyleSheet Source="/Resources/styles.css" />
</ContentPage.Resources>
<ScrollView>
<StackLayout>
<Label ... StyleClass="detailPageTitle" />
<Label ... StyleClass="detailPageSubtitle"/>
</StackLayout>
</ScrollView>
</ContentPage>
Selecionar elementos filho
Os elementos filho na árvore visual podem ser selecionados com o seletor sem diferenciação element element
de maiúsculas e minúsculas:
listview image {
height: 60;
width: 60;
}
Esse seletor identifica quaisquer Image elementos que são filhos de ListView elementos e define sua altura e largura como 60. Portanto, no exemplo XAML a seguir, o seletor identificará o listview image
Image que é filho do ListView, e definirá sua altura e largura como 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>
Observação
O element element
seletor não exige que o elemento filho seja um filho direto do pai – o elemento filho pode ter um pai diferente. A seleção ocorre desde que um ancestral seja o primeiro elemento especificado.
Selecionar elementos filho diretos
Os elementos filho diretos na árvore visual podem ser selecionados com o seletor sem diferenciação element>element
de maiúsculas e minúsculas:
stacklayout>image {
height: 200;
width: 200;
}
Esse seletor identifica quaisquer Image elementos que são filhos diretos de StackLayout elementos e define sua altura e largura como 200. Portanto, no exemplo a seguir, o seletor identificará o stacklayout>image
Image que é um filho direto do StackLayout, e definirá sua altura e largura como 200.
<ContentPage ...>
<ContentPage.Resources>
<StyleSheet Source="/Resources/styles.css" />
</ContentPage.Resources>
<ScrollView>
<StackLayout>
...
<Image ... />
...
</StackLayout>
</ScrollView>
</ContentPage>
Observação
O element>element
seletor requer que o elemento filho seja um filho direto do pai.
Referência do seletor
Os seguintes seletores CSS são suportados pelo .NET MAUI:
Seletor | Exemplo | Descrição |
---|---|---|
.class |
.header |
Seleciona todos os elementos com a StyleClass propriedade que contém 'header'. Esse seletor diferencia maiúsculas de minúsculas. |
#id |
#email |
Seleciona todos os elementos com StyleId definido como email . Se StyleId não estiver definido, fallback para x:Name . Ao usar XAML, x:Name é preferível a .StyleId Esse seletor diferencia maiúsculas de minúsculas. |
* |
* |
Seleciona todos os elementos. |
element |
label |
Seleciona todos os elementos do tipo Label, mas não subclasses. Este seletor não diferencia maiúsculas de minúsculas. |
^base |
^contentpage |
Seleciona todos os elementos com ContentPage como a classe base, incluindo ContentPage a si mesmo. Esse seletor não diferencia maiúsculas de minúsculas e não faz parte da especificação CSS. |
element,element |
label,button |
Seleciona todos os elementos e todos Button os Label elementos. Este seletor não diferencia maiúsculas de minúsculas. |
element element |
stacklayout label |
Seleciona todos os Label elementos dentro de um StackLayoutarquivo . Este seletor não diferencia maiúsculas de minúsculas. |
element>element |
stacklayout>label |
Seleciona todos os Label elementos com StackLayout como pai direto. Este seletor não diferencia maiúsculas de minúsculas. |
element+element |
label+entry |
Seleciona todos os Entry elementos diretamente após um Labelarquivo . Este seletor não diferencia maiúsculas de minúsculas. |
element~element |
label~entry |
Seleciona todos os Entry elementos precedidos por um Labelarquivo . Este seletor não diferencia maiúsculas de minúsculas. |
Os estilos com seletores correspondentes são aplicados consecutivamente, em ordem de definição. Os estilos definidos em um item específico são sempre aplicados por último.
Dica
Os seletores podem ser combinados sem limitação, como StackLayout>ContentView>label.email
.
Os seguintes seletores não são suportados:
[attribute]
@media
e@supports
:
e::
Observação
Não há suporte para substituições de especificidade e especificidade.
Referência de propriedade
As seguintes propriedades CSS são suportadas pelo .NET MAUI (na coluna Valores, os tipos são itálico, enquanto os literais de cadeia de caracteres sãogray
):
Propriedade | Aplicável ao | Valores | Exemplo |
---|---|---|---|
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 | cadeia de caracteres | initial |
background-image: bg.png; |
border-color |
Button, Frame, ImageButton | 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, , , , , , , , , , SearchBarProgressBarSwitchBoxViewDatePickerPickerEditorLabelEntryButtonCheckBoxTimePicker | 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 | flutuaçãoinitial | auto | . Além disso, uma porcentagem na faixa de 0% a 100% pode ser especificada com o % sinal. |
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, , , , , , , , Editor, DatePickerPickerEntryLabelSearchBarTimePickerSpan | cadeia de caracteres | initial |
font-family: Consolas; |
font-size |
Button, , , , , , , , Editor, DatePickerPickerEntryLabelSearchBarTimePickerSpan | double | initial |
font-size: 12; |
font-style |
Button, , , , , , , , Editor, DatePickerPickerEntryLabelSearchBarTimePickerSpan | 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, , , , , , , , , , Picker, SearchBarDatePickerLabelEditorEntrySearchHandlerSpanTimePicker | double | initial |
letter-spacing: 2.5; |
line-height |
Label, Span | double | initial |
line-height: 1.8; |
margin |
View | espessura | initial |
margin: 6 12; |
margin-left |
View | espessura | initial |
margin-left: 3; |
margin-top |
View | espessura | initial |
margin-top: 2; |
margin-right |
View | espessura | initial |
margin-right: 1; |
margin-bottom |
View | espessura | 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 | espessura | 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 e right deve ser evitado em ambientes da direita para a esquerda. |
text-align: right; |
text-decoration |
Label, Span | none | underline | strikethrough | line-through | initial |
text-decoration: underline, line-through; |
text-transform |
Button,Editor, , Label, , EntrySearchBarSearchHandler | none | default | uppercase | lowercase | initial |
text-transform: uppercase; |
transform |
VisualElement | none , , , , , , , , rotateY , , , translate scale translateY rotate scaleX scaleY translateX rotateX initial |
transform: rotate(180), scaleX(2.5); |
transform-origin |
VisualElement | duplo, duplo | 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; |
Observação
initial
é um valor válido para todas as propriedades. Ele limpa o valor (redefine para padrão) que foi definido de outro estilo.
As seguintes propriedades não são suportadas:
all: initial
.- Propriedades de layout (caixa ou grade).
- Propriedades taquigráficas, como
font
, eborder
.
Além disso, não há valor e, portanto, a herança não inherit
é suportada. Portanto, você não pode, por exemplo, definir a font-size
propriedade em um layout e esperar que todas as Label instâncias no layout herdem o valor. A única exceção é a direction
propriedade, que tem um valor padrão de inherit
.
Importante
Span elementos não podem ser direcionados usando CSS.
Propriedades específicas do .NET MAUI
As seguintes propriedades CSS específicas do .NET MAUI também são suportadas (na coluna Valores, os tipos são itálico, enquanto os literais de cadeia de caracteres sãogray
):
Propriedade | Aplicável ao | Valores | Exemplo |
---|---|---|---|
-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, 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 só é suportado em um ScrollViewarquivo . |
-maui-orientation: horizontal; |
-maui-placeholder |
Entry, Editor, SearchBar | texto citado | 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 | cadeia de caracteres | initial |
-maui-visual: material; |
Propriedades específicas do Shell do .NET MAUI
As seguintes propriedades CSS específicas do Shell do .NET MAUI também são suportadas (na coluna Valores, os tipos são itálico, enquanto os literais de cadeia de caracteres sãogray
):
Propriedade | Aplicável ao | Valores | Exemplo |
---|---|---|---|
-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
Há suporte para os seguintes valores de color
:
X11
cores, que correspondem a cores CSS e cores do .NET MAUI. Esses valores de cor não diferenciam maiúsculas de minúsculas.- Cores hexadecimais:
#rgb
, ,#argb
#rrggbb
#aarrggbb
- cores RGB:
rgb(255,0,0)
,rgb(100%,0%,0%)
. Os valores estão no intervalo de 0 a 255 ou 0% a 100%. - rgba cores:
rgba(255, 0, 0, 0.8)
,rgba(100%, 0%, 0%, 0.8)
. O valor de opacidade está no intervalo de 0,0 a 1,0. - hsl cores:
hsl(120, 100%, 50%)
. O valor de h está no intervalo de 0 a 360, enquanto s e l estão no intervalo de 0% a 100%. - hsla cores:
hsla(120, 100%, 50%, .8)
. O valor de opacidade está no intervalo de 0,0 a 1,0.
Espessura
Há suporte para um, dois, três ou quatro thickness
valores, cada um separado por espaço em branco:
- Um único valor indica espessura uniforme.
- Dois valores indicam espessura vertical e horizontal.
- Três valores indicam espessura superior, depois horizontal (esquerda e direita) e inferior.
- Quatro valores indicam espessura superior, depois direita, depois inferior e esquerda.
Observação
Os valores CSS thickness
diferem dos valores XAML Thickness
. Por exemplo, em XAML, um valor de dois indica espessura horizontal e vertical, enquanto um valor de quatro indica Thickness
Thickness
espessura esquerda, depois superior, direita e inferior. Além disso, os valores XAML Thickness
são delimitados por vírgula.
Funções
Gradientes lineares e radiais podem ser especificados usando as linear-gradient()
funções CSS e radial-gradient()
CSS, respectivamente. O resultado dessas funções deve ser atribuído à background
propriedade de um controle.
Comentários
https://aka.ms/ContentUserFeedback.
Em breve: Ao longo de 2024, eliminaremos os problemas do GitHub como o mecanismo de comentários para conteúdo e o substituiremos por um novo sistema de comentários. Para obter mais informações, consulteEnviar e exibir comentários de