Estilizando aplicativos usando CSS (Folhas de Xamarin.Forms Estilos em Cascata)
Xamarin.Forms suporta o estilo de elementos visuais usando CSS (Folhas de Estilos em Cascata).
Xamarin.Forms os aplicativos podem ser estilizados usando CSS. Uma folha de estilos consiste de uma lista de regras, com cada regra consistindo de um ou mais seletores e um bloco de declaração. Um bloco de declaração consiste de uma lista de declarações entre chaves, com cada declaração consistindo de uma propriedade, dois pontos e um valor. Quando existem várias declarações em um bloco, um ponto e vírgula é inserido como separador. O exemplo de código a seguir mostra alguns Xamarin.Forms CSS compatíveis:
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;
}
No Xamarin.Forms, as folhas de estilo CSS são analisadas e avaliadas em tempo de execução, em vez de compilação, e as folhas de estilo são analisadas novamente no uso.
Observação
Atualmente, todo o estilo possível com o estilo XAML não pode ser executado com CSS. No entanto, os estilos XAML podem ser usados para complementar o CSS para propriedades que atualmente não têm suporte do Xamarin.Forms. Para obter mais informações sobre estilos XAML, consulte Estilizando Xamarin.Forms aplicativos usando estilos XAML.
O exemplo demonstra o uso de CSS para estilizar um aplicativo simples e é mostrado nas seguintes capturas de tela:
Consumindo uma folha de estilos
O processo para adicionar uma folha de estilo a uma solução é o seguinte:
- Adicione um arquivo CSS vazio ao seu projeto de biblioteca do .NET Standard.
- Defina a ação de build do arquivo CSS como EmbeddedResource.
Como carregar uma folha de estilos
Existem várias abordagens que podem ser usadas para carregar uma folha de estilos.
Observação
No momento, não é possível alterar uma folha de estilos em tempo de execução e aplicar a nova folha de estilos.
XAML
Uma folha de estilos pode ser carregada e analisada com a classe StyleSheet
antes de ser adicionada a um ResourceDictionary
:
<Application ...>
<Application.Resources>
<StyleSheet Source="/Assets/styles.css" />
</Application.Resources>
</Application>
A propriedade StyleSheet.Source
especifica a folha de estilos como um URI com relação ao local do arquivo XAML delimitado ou com relação à raiz do projeto, se o URI começar com um /
.
Aviso
O arquivo CSS não será carregado se sua ação de build não estiver definida como EmbeddedResource.
Alternativamente, uma folha de estilos pode ser carregada e analisada com a classe StyleSheet
, antes de ser adicionada a um ResourceDictionary
, ao ser incorporada a uma seção CDATA
:
<ContentPage ...>
<ContentPage.Resources>
<StyleSheet>
<![CDATA[
^contentpage {
background-color: lightgray;
}
]]>
</StyleSheet>
</ContentPage.Resources>
...
</ContentPage>
Para mais informações sobre dicionários de recursos, confira Dicionários de recursos.
C#
No C#, uma folha de estilos pode ser carregada a partir de um StringReader
e adicionada a um ResourceDictionary
:
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 StyleSheet.FromReader
é o TextReader
que leu a folha de estilos.
Selecionando elementos e aplicando propriedades
O CSS usa seletores para determinar quais elementos serão visados. Os estilos com seletores combinando são aplicados de forma consecutiva, na ordem da definição. Os estilos definidos em um item específico são sempre aplicados por último. Para obter mais informações sobre seletores suportados, consulte Referência do seletor.
O CSS usa propriedades para definir o estilo de 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 filhas 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 da página será substituído por um estilo definido nos recursos de controle, se 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.
Importante
As variáveis de CSS não têm suporte.
Selecionando elementos por tipo
Os elementos na árvore visual podem ser selecionados por tipo com o seletor de element
, que não diferencia maiúsculas de minúsculas:
stacklayout {
margin: 20;
}
Esse seletor identifica todos os elementos de StackLayout
nas páginas que consomem a folha de estilos e define suas margens como uma espessura uniforme de 20.
Observação
O seletor de element
não identifica subclasses do tipo especificado.
Como selecionar elementos por classe base
Os elementos na árvore visual podem ser selecionados pela classe base com o seletor de ^base
, que não diferencia maiúsculas de minúsculas:
^contentpage {
background-color: lightgray;
}
Esse seletor identifica todos os elementos de ContentPage
que consomem a folha de estilos e define a cor da tela de fundo como lightgray
.
Observação
O ^base
seletor é específico do Xamarin.Formse não faz parte da especificação CSS.
Como selecionar um elemento por nome
Elementos individuais na árvore visual podem ser selecionados com o seletor de #id
, que diferencia maiúsculas de minúsculas:
#listView {
background-color: lightgray;
}
Esse seletor identifica o elemento cuja propriedade StyleId
é definida como listView
. No entanto, se a propriedade StyleId
não estiver definida, o seletor irá retroceder e usar o x:Name
do elemento. Portanto, no exemplo XAML a seguir, o #listView
seletor identificará o ListView
atributo cujo x:Name
está definido como listView
, e definirá sua cor de plano de fundo como lightgray
.
<ContentPage ...>
<ContentPage.Resources>
<StyleSheet Source="/Assets/styles.css" />
</ContentPage.Resources>
<StackLayout>
<ListView x:Name="listView" ...>
...
</ListView>
</StackLayout>
</ContentPage>
Selecionando elementos com um atributo de classe específico
Elementos com um atributo de classe específico podem ser selecionados com o seletor de .class
que diferencia maiúsculas de minúsculas:
.detailPageTitle {
font-style: bold;
font-size: medium;
text-align: center;
}
.detailPageSubtitle {
text-align: center;
font-style: italic;
}
Uma classe de CSS pode ser atribuída a um elemento XAML ao definir a propriedade StyleClass
do elemento como o nome da classe de CSS. Portanto, no exemplo XAML a seguir, os estilos definidos pela .detailPageTitle
classe são atribuídos ao primeiro Label
, enquanto os estilos definidos pela .detailPageSubtitle
classe são atribuídos ao segundo Label
.
<ContentPage ...>
<ContentPage.Resources>
<StyleSheet Source="/Assets/styles.css" />
</ContentPage.Resources>
<ScrollView>
<StackLayout>
<Label ... StyleClass="detailPageTitle" />
<Label ... StyleClass="detailPageSubtitle"/>
...
</StackLayout>
</ScrollView>
</ContentPage>
Selecionando elementos filho
Os elementos filhos na árvore visual podem ser selecionados com o seletor de element element
que não diferencia maiúsculas de minúsculas:
listview image {
height: 60;
width: 60;
}
Esse seletor identifica todos os elementos Image
que são filhos de elementos ListView
e define sua altura e largura como 60. Portanto, no exemplo de XAML a seguir, o seletor listview image
irá identificar o Image
, que é filho da ListView
, e definir sua altura e largura como 60.
<ContentPage ...>
<ContentPage.Resources>
<StyleSheet Source="/Assets/styles.css" />
</ContentPage.Resources>
<StackLayout>
<ListView ...>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid>
...
<Image ... />
...
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>
Observação
O seletor element element
não requer que o elemento filho seja um filho direto do pai: o elemento filho pode ter um pai diferente. A seleção ocorre sempre que um ancestral for o primeiro elemento especificado.
Selecionando elementos filho diretos
Os elementos filhos diretos na árvore visual podem ser selecionados com o seletor element>element
, que não diferencia maiúsculas de minúsculas:
stacklayout>image {
height: 200;
width: 200;
}
Esse seletor identifica todos os elementos Image
que são filhos diretos de elementos StackLayout
e define sua altura e largura como 200. Portanto, no exemplo XAML a seguir, o stacklayout>image
seletor identificará o Image
filho direto do StackLayout
, e definirá sua altura e largura como 200.
<ContentPage ...>
<ContentPage.Resources>
<StyleSheet Source="/Assets/styles.css" />
</ContentPage.Resources>
<ScrollView>
<StackLayout>
...
<Image ... />
...
</StackLayout>
</ScrollView>
</ContentPage>
Observação
O seletor element>element
requer que o elemento filho seja um filho direto do pai.
Referência de seletores
Os seguintes seletores de CSS são suportados por Xamarin.Forms:
Seletor | Exemplo | Descrição |
---|---|---|
.class |
.header |
Seleciona todos os elementos com a propriedade StyleClass contendo "cabeçalho". Observe que esse seletor diferencia maiúsculas de minúsculas. |
#id |
#email |
Seleciona todos os elementos com StyleId definida como email . Se StyleId não estiver definida, retroceda para x:Name . Ao usar XAML, x:Name é preferível em vez de StyleId . Observe que 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. Observe que esse seletor não diferencia maiúsculas de minúsculas. |
^base |
^contentpage |
Seleciona todos os elementos que têm ContentPage como classe base, incluindo a ContentPage propriamente dita. Observe que 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 Button e todos os elementos Label . Observe que esse seletor não diferencia maiúsculas de minúsculas. |
element element |
stacklayout label |
Seleciona todos os elementos Label dentro de um StackLayout . Observe que esse seletor não diferencia maiúsculas de minúsculas. |
element>element |
stacklayout>label |
Seleciona todos os elementos Label que têm StackLayout como um pai direto. Observe que esse seletor não diferencia maiúsculas de minúsculas. |
element+element |
label+entry |
Seleciona todos os elementos Entry diretamente após um Label . Observe que esse seletor não diferencia maiúsculas de minúsculas. |
element~element |
label~entry |
Seleciona todos os elementos Entry precedidos por um Label . Observe que esse seletor não diferencia maiúsculas de minúsculas. |
Os estilos com seletores combinando são aplicados de forma consecutiva, na ordem da 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 em um StackLayout>ContentView>label.email
.
No momento, não há suporte para os seguintes seletores:
[attribute]
@media
e@supports
:
e::
Observação
A especificidade e as substituições de especificidade não têm suporte.
Referência de propriedade
As seguintes propriedades CSS são suportadas por Xamarin.Forms (na coluna Valores, os tipos estão em 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 , Button , Frame , ImageButton |
double | initial |
border-radius: 10; |
border-width |
Button , ImageButton |
double | initial |
border-width: .5; |
color |
ActivityIndicator , BoxView , Button , CheckBox , DatePicker , Editor ProgressBar Entry Switch Label Picker SearchBar ,TimePicker |
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 |
derivar | auto | initial . Além disso, um percentual no intervalo de 0% a 100% pode ser especificado 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 , DatePicker , Editor , Entry , Label , Picker SearchBar TimePicker ,Span |
cadeia de caracteres | initial |
font-family: Consolas; |
font-size |
Button , DatePicker , Editor , Entry , Label , Picker SearchBar TimePicker ,Span |
tamanho duplo | nomeado | 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 |
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 Span Picker SearchBar SearchHandler ,TimePicker |
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 , ImageButton , Layout , Page |
espessura | 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 |
Grid |
double | initial |
row-gap: 12; |
text-align |
Entry , EntryCell , Label , SearchBar |
left | top | right | bottom | start | center | middle | end | initial . left e right deve ser evitados em ambientes com escrita 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 , Entry , Label , SearchBar , SearchHandler |
none | default | uppercase | lowercase | initial |
text-transform: uppercase; |
transform |
VisualElement |
none , rotate , rotateX , rotateY , scale translateX scaleX translate scaleY translateY ,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 |
min-width: 320; |
Observação
initial
é um valor válido para todas as propriedades. Limpa o valor (redefine para o padrão) que foi definido em um outro estilo.
No momento, não há suporte para as seguintes propriedades:
all: initial
.- Propriedades de layout (caixa ou grade).
- Propriedades abreviadas, como
font
eborder
.
Além disso, não existe nenhum valor inherit
e, portanto, a herança não tem suporte. Portanto, você não pode, por exemplo, definir a propriedade font-size
em um layout e esperar que todas as instâncias de Label
no layout herdem o valor. A única exceção é a propriedade direction
, que tem um valor padrão inherit
.
O direcionamento Span
de elementos tem um problema conhecido que impede que os intervalos sejam o destino de estilos CSS por elemento e nome (usando o #
símbolo). O Span
elemento deriva de GestureElement
, que não tem a propriedade, portanto, os intervalos não suportam o StyleClass
direcionamento de classe CSS. Para obter mais informações, consulte Não é possível aplicar o estilo CSS ao controle Span.
Xamarin.Forms Propriedades específicas
As seguintes Xamarin.Forms propriedades CSS específicas também são suportadas (na coluna Valores, os tipos estão em itálico, enquanto os literais de cadeia de caracteres sãogray
):
Propriedade | Aplicável ao | Valores | Exemplo |
---|---|---|---|
-xf-bar-background-color |
NavigationPage , TabbedPage |
color | initial |
-xf-bar-background-color: teal; |
-xf-bar-text-color |
NavigationPage , TabbedPage |
color | initial |
-xf-bar-text-color: gray |
-xf-horizontal-scroll-bar-visibility |
ScrollView |
default | always | never | initial |
-xf-horizontal-scroll-bar-visibility: never; |
-xf-max-length |
Entry , Editor , SearchBar |
int | initial |
-xf-max-length: 20; |
-xf-max-track-color |
Slider |
color | initial |
-xf-max-track-color: red; |
-xf-min-track-color |
Slider |
color | initial |
-xf-min-track-color: yellow; |
-xf-orientation |
ScrollView , StackLayout |
horizontal | vertical | both | initial . both só tem suporte em uma ScrollView . |
-xf-orientation: horizontal; |
-xf-placeholder |
Entry , Editor , SearchBar |
texto entre aspas | initial |
-xf-placeholder: Enter name; |
-xf-placeholder-color |
Entry , Editor , SearchBar |
color | initial |
-xf-placeholder-color: green; |
-xf-spacing |
StackLayout |
double | initial |
-xf-spacing: 8; |
-xf-thumb-color |
Slider , Switch |
color | 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 |
cadeia de caracteres | initial |
-xf-visual: material; |
Xamarin.Forms Propriedades específicas do shell
As seguintes Xamarin.Forms propriedades CSS específicas do Shell também são suportadas (na coluna Valores, os tipos estão em itálico, enquanto os literais de cadeia de caracteres sãogray
):
Propriedade | Aplicável ao | Valores | Exemplo |
---|---|---|---|
-xf-flyout-background |
Shell |
color | initial |
-xf-flyout-background: red; |
-xf-shell-background |
Element |
color | initial |
-xf-shell-background: green; |
-xf-shell-disabled |
Element |
color | initial |
-xf-shell-disabled: blue; |
-xf-shell-foreground |
Element |
color | initial |
-xf-shell-foreground: yellow; |
-xf-shell-tabbar-background |
Element |
color | initial |
-xf-shell-tabbar-background: white; |
-xf-shell-tabbar-disabled |
Element |
color | initial |
-xf-shell-tabbar-disabled: black; |
-xf-shell-tabbar-foreground |
Element |
color | initial |
-xf-shell-tabbar-foreground: gray; |
-xf-shell-tabbar-title |
Element |
color | initial |
-xf-shell-tabbar-title: lightgray; |
-xf-shell-tabbar-unselected |
Element |
color | initial |
-xf-shell-tabbar-unselected: cyan; |
-xf-shell-title |
Element |
color | initial |
-xf-shell-title: teal; |
-xf-shell-unselected |
Element |
color | initial |
-xf-shell-unselected: limegreen; |
Color
Há suporte para os seguintes valores de color
:
X11
cores, que correspondem a cores CSS, cores predefinidas UWP e Xamarin.Forms cores. Observe que 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%-100%. - cores rgba:
rgba(255, 0, 0, 0.8)
,rgba(100%, 0%, 0%, 0.8)
. O valor de opacidade está no intervalo 0,0-1,0. - cores hsl:
hsl(120, 100%, 50%)
. O valor h está no intervalo de 0-360, enquanto s e l estão no intervalo 0%-100%. - cores hsla:
hsla(120, 100%, 50%, .8)
. O valor de opacidade está no intervalo 0,0-1,0.
Espessura
Os valores de thickness
um, dois, três ou quatro têm suporte, cada um separado por um espaço em branco:
- Um único valor indica uma espessura uniforme.
- Dois valores indicam espessura vertical e, a seguir, horizontal.
- Três valores indicam a espessura da parte superior, horizontal (esquerda e direita) e da parte inferior, nesta ordem.
- Quatro valores indicam a espessura da parte superior, da direita, da parte inferior e da esquerda, nesta ordem.
Observação
Os valores de thickness
de CSS diferem dos valores de Thickness
de XAML. Por exemplo, em XAML, uma Thickness
de dois valores indica a espessura horizontal, e a seguir vertical, enquanto uma Thickness
de quatro valores indica a espessura da esquerda, da parte superior, da direita e da parte inferior, nesta ordem. Além disso, os valores de Thickness
em XAML são delimitados por vírgula.
NamedSize
Há suporte para os seguintes valores que não diferenciam maiúsculas de minúsculas namedsize
:
default
micro
small
medium
large
O significado exato de cada namedsize
valor depende da plataforma e da exibição.
Funções
Gradientes lineares e radiais podem ser especificados usando as funções CSS linear-gradient()
e radial-gradient()
, respectivamente. O resultado dessas funções deve ser atribuído à propriedade background
de um controle.
CSS com Xamarin.Forms Xamarin.University
Xamarin.Forms 3.0 Vídeo CSS