Estilizando Xamarin.Forms aplicativos usando CSS (Folhas de Estilos em Cascata)
Xamarin.Forms dá suporte ao 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 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 entre 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 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 estiloS CSS são analisadas e avaliadas em runtime, em vez de tempo de compilação, e as folhas de estilos são analisadas novamente no uso.
Observação
Atualmente, todo o estilo possível com 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 pelo Xamarin.Forms. Para obter mais informações sobre estilos XAML, consulte Estilos Xamarin.Forms de aplicativos usando estilos XAML.
O exemplo MonkeyAppCSS 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 estilos 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.
Carregando uma folha de estilos
Há 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 runtime e aplicar a nova folha de estilos.
XAML
Uma folha de estilos pode ser carregada e analisada com a StyleSheet
classe antes de ser adicionada a um ResourceDictionary
:
<Application ...>
<Application.Resources>
<StyleSheet Source="/Assets/styles.css" />
</Application.Resources>
</Application>
A StyleSheet.Source
propriedade especifica a folha de estilos como um URI relativo ao local do arquivo XAML delimitado ou relativo à raiz do projeto se o URI começar com um /
.
Aviso
O arquivo CSS falhará ao carregar se sua ação de build não estiver definida como EmbeddedResource.
Como alternativa, uma folha de estilos pode ser carregada e analisada com a StyleSheet
classe , antes de ser adicionada a um ResourceDictionary
, inlining-a 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.
C#
Em C#, uma folha de estilos pode ser carregada 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 StyleSheet.FromReader
método é o TextReader
que leu a folha de estilos.
Selecionando elementos e aplicando propriedades
O CSS usa seletores para determinar quais elementos direcionar. Os estilos com seletores correspondentes são aplicados consecutivamente, na 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.
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 as propriedades com suporte, consulte Referência de propriedade.
Folhas de estilos filho sempre substituem folhas de estilos 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 em 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.
Importante
Não há suporte para variáveis CSS.
Selecionando elementos por tipo
Os elementos na árvore visual podem ser selecionados por tipo com o seletor que não diferencia maiúsculas element
de minúsculas:
stacklayout {
margin: 20;
}
Esse seletor identifica todos StackLayout
os elementos em páginas que consomem a folha de estilos e define suas margens como 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 pela classe base com o seletor que não diferencia maiúsculas ^base
de minúsculas:
^contentpage {
background-color: lightgray;
}
Esse seletor identifica todos ContentPage
os elementos que consomem a folha de estilos e define a cor da tela de fundo como lightgray
.
Observação
O ^base
seletor é específico de Xamarin.Formse não faz parte da especificação CSS.
Selecionando um elemento por nome
Elementos individuais na árvore visual podem ser selecionados com o seletor que diferencia maiúsculas #id
de minúsculas:
#listView {
background-color: lightgray;
}
Esse seletor identifica o elemento cuja StyleId
propriedade está definida como listView
. No entanto, se a StyleId
propriedade não estiver definida, o seletor voltará a usar o x:Name
do elemento . Portanto, no exemplo XAML a seguir, o #listView
seletor identificará o ListView
cujo x:Name
atributo está definido listView
como e definirá sua cor da tela 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 que diferencia maiúsculas .class
de minúsculas:
.detailPageTitle {
font-style: bold;
font-size: medium;
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 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 filho na árvore visual podem ser selecionados com o seletor que não diferencia maiúsculas de minúsculas element element
:
listview image {
height: 60;
width: 60;
}
Esse seletor identifica todos Image
os elementos que são filhos de ListView
elementos e define sua altura e largura como 60. Portanto, no exemplo XAML a seguir, o listview image
seletor identificará o Image
que é um filho do 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 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.
Selecionando elementos filho diretos
Os elementos filho diretos na árvore visual podem ser selecionados com o seletor que não diferencia maiúsculas de minúsculas element>element
:
stacklayout>image {
height: 200;
width: 200;
}
Esse seletor identifica todos Image
os elementos que são filhos diretos de StackLayout
elementos e define sua altura e largura como 200. Portanto, no exemplo XAML a seguir, o stacklayout>image
seletor identificará o Image
que é um 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 element>element
seletor requer que o elemento filho seja um filho direto do pai.
Referência do seletor
Os seguintes seletores de CSS são compatíveis com Xamarin.Forms:
Seletor | Exemplo | Descrição |
---|---|---|
.class |
.header |
Seleciona todos os elementos com a StyleClass propriedade que contém 'header'. Observe que esse seletor diferencia maiúsculas de minúsculas. |
#id |
#email |
Seleciona todos os elementos com StyleId definido email como . Se StyleId não estiver definido, fallback para x:Name . Ao usar XAML, x:Name é preferencial 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 com ContentPage como a classe base, incluindo ContentPage a própria. Observe que esse seletor não diferencia maiúsculas de minúsculas e não faz parte da especificação do CSS. |
element,element |
label,button |
Seleciona todos os Button elementos e todos os Label elementos. Observe que esse seletor não diferencia maiúsculas de minúsculas. |
element element |
stacklayout label |
Seleciona todos os Label elementos dentro de um StackLayout . Observe que esse seletor não diferencia maiúsculas de minúsculas. |
element>element |
stacklayout>label |
Seleciona todos os Label elementos com StackLayout como um pai direto. Observe que esse seletor não diferencia maiúsculas de minúsculas. |
element+element |
label+entry |
Seleciona todos os Entry elementos diretamente após um Label . Observe que esse seletor não diferencia maiúsculas de minúsculas. |
element~element |
label~entry |
Seleciona todos os Entry elementos precedidos por um Label . Observe que esse seletor não diferencia maiúsculas de minúsculas. |
Estilos com seletores correspondentes são aplicados consecutivamente, na 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
.
No momento, não há suporte para os seguintes seletores:
[attribute]
@media
e@supports
:
e::
Observação
Não há suporte para a especificidade e as substituições de especificidade.
Referência de propriedade
As propriedades CSS a seguir são compatíveis Xamarin.Forms com (na coluna Valores , os tipos são itálicos, enquanto os literais de cadeia de caracteres são gray
):
Propriedade | Aplica-se a | 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 |
Cor | initial |
background-color: springgreen; |
background-image |
Page |
String | initial |
background-image: bg.png; |
border-color |
Button , Frame , ImageButton |
Cor | initial |
border-color: #9acd32; |
border-radius |
BoxView , Button , Frame , ImageButton |
Duplo | initial |
border-radius: 10; |
border-width |
Button , ImageButton |
Duplo | initial |
border-width: .5; |
color |
ActivityIndicator , BoxView , Button , CheckBox , DatePicker , Editor , Entry , Label , Picker , ProgressBar , SearchBar , Switch , TimePicker |
Cor | initial |
color: rgba(255, 0, 0, 0.3); |
column-gap |
Grid |
Duplo | 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 . Além disso, um percentual no intervalo de 0% a 100% pode ser especificado com o % sinal. |
flex-basis: 25%; |
flex-grow |
VisualElement |
Flutuar | initial |
flex-grow: 1.5; |
flex-shrink |
VisualElement |
Flutuar | 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 |
String | initial |
font-family: Consolas; |
font-size |
Button , DatePicker , Editor , Entry , Label , Picker , SearchBar , TimePicker , Span |
Duplo | namedsize | initial |
font-size: 12; |
font-style |
Button , DatePicker , Editor , Entry , Label , Picker , SearchBar , TimePicker , Span |
bold | italic | initial |
font-style: bold; |
height |
VisualElement |
Duplo | 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 |
Duplo | initial |
letter-spacing: 2.5; |
line-height |
Label , Span |
Duplo | 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 |
Duplo | initial |
min-height: 50; |
min-width |
VisualElement |
Duplo | initial |
min-width: 112; |
opacity |
VisualElement |
Duplo | 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 |
Duplo | initial |
padding-left: 3; |
padding-top |
Button , ImageButton , Layout , Page |
Duplo | initial |
padding-top: 4; |
padding-right |
Button , ImageButton , Layout , Page |
Duplo | initial |
padding-right: 2; |
padding-bottom |
Button , ImageButton , Layout , Page |
Duplo | initial |
padding-bottom: 6; |
position |
FlexLayout |
relative | absolute | initial |
position: absolute; |
row-gap |
Grid |
Duplo | initial |
row-gap: 12; |
text-align |
Entry , EntryCell , Label , SearchBar |
left | top | right | bottom | start | center | middle | end | initial . left e right devem ser evitados 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 , 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 |
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 |
Duplo | initial |
min-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.
No momento, as seguintes propriedades não têm suporte:
all: initial
.- Propriedades de layout (caixa ou grade).
- Propriedades abreviadas, como
font
eborder
.
Além disso, não inherit
há nenhum valor e, portanto, não há suporte para herança. 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
.
O direcionamento de Span
elementos tem um problema conhecido que impede que os intervalos sejam o destino dos estilos CSS pelo elemento e pelo nome (usando o #
símbolo). O Span
elemento deriva de GestureElement
, que não tem a propriedade , portanto, os StyleClass
intervalos não dão suporte à segmentação 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 propriedades Xamarin.Forms CSS específicas a seguir também têm suporte (na coluna Valores , os tipos são itálicos, enquanto os literais de cadeia de caracteres são gray
):
Propriedade | Aplica-se a | Valores | Exemplo |
---|---|---|---|
-xf-bar-background-color |
NavigationPage , TabbedPage |
Cor | initial |
-xf-bar-background-color: teal; |
-xf-bar-text-color |
NavigationPage , TabbedPage |
Cor | 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 |
Cor | initial |
-xf-max-track-color: red; |
-xf-min-track-color |
Slider |
Cor | initial |
-xf-min-track-color: yellow; |
-xf-orientation |
ScrollView , StackLayout |
horizontal | vertical | both | initial . both só tem suporte em um ScrollView . |
-xf-orientation: horizontal; |
-xf-placeholder |
Entry , Editor , SearchBar |
texto entre aspas | initial |
-xf-placeholder: Enter name; |
-xf-placeholder-color |
Entry , Editor , SearchBar |
Cor | initial |
-xf-placeholder-color: green; |
-xf-spacing |
StackLayout |
Duplo | initial |
-xf-spacing: 8; |
-xf-thumb-color |
Slider , Switch |
Cor | 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 |
String | initial |
-xf-visual: material; |
Xamarin.Forms Propriedades específicas do shell
As propriedades Xamarin.Forms CSS específicas do Shell a seguir também têm suporte (na coluna Valores, os tipos são itálicos, enquanto os literais de cadeia de caracteres são gray
):
Propriedade | Aplica-se a | Valores | Exemplo |
---|---|---|---|
-xf-flyout-background |
Shell |
Cor | initial |
-xf-flyout-background: red; |
-xf-shell-background |
Element |
Cor | initial |
-xf-shell-background: green; |
-xf-shell-disabled |
Element |
Cor | initial |
-xf-shell-disabled: blue; |
-xf-shell-foreground |
Element |
Cor | initial |
-xf-shell-foreground: yellow; |
-xf-shell-tabbar-background |
Element |
Cor | initial |
-xf-shell-tabbar-background: white; |
-xf-shell-tabbar-disabled |
Element |
Cor | initial |
-xf-shell-tabbar-disabled: black; |
-xf-shell-tabbar-foreground |
Element |
Cor | initial |
-xf-shell-tabbar-foreground: gray; |
-xf-shell-tabbar-title |
Element |
Cor | initial |
-xf-shell-tabbar-title: lightgray; |
-xf-shell-tabbar-unselected |
Element |
Cor | initial |
-xf-shell-tabbar-unselected: cyan; |
-xf-shell-title |
Element |
Cor | initial |
-xf-shell-title: teal; |
-xf-shell-unselected |
Element |
Cor | initial |
-xf-shell-unselected: limegreen; |
Cor
Há suporte para os seguintes valores de color
:
X11
cores, que correspondem a cores CSS, cores Xamarin.Forms e cores predefinidas da UWP. Observe que esses valores de cor não diferenciam maiúsculas de minúsculas.- cores hexadecisivas:
#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 de 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 a 360, enquanto s e l estão no intervalo de 0%a 100%. - cores hsla:
hsla(120, 100%, 50%, .8)
. O valor de opacidade está no intervalo 0.0-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 parte superior e horizontal (esquerda e direita) e espessura inferior.
- Quatro valores indicam a espessura superior, direita, inferior e esquerda.
Observação
Os valores de CSS thickness
diferem dos valores XAML Thickness
. Por exemplo, em XAML, um valor Thickness
de dois indica espessura horizontal e vertical, enquanto um de quatro valores Thickness
indica esquerda, superior, direita e espessura inferior. Além disso, os valores XAML Thickness
são delimitados por vírgulas.
NamedSize
Há suporte para os seguintes valores que não diferenciam namedsize
maiúsculas de minúsculas:
default
micro
small
medium
large
O significado exato de cada namedsize
valor depende da plataforma e depende da exibição.
Funções
Gradientes lineares e radiais podem ser especificados usando as linear-gradient()
funções E radial-gradient()
CSS, respectivamente. O resultado dessas funções deve ser atribuído à background
propriedade de um controle .
CSS em Xamarin.Forms com Xamarin.University
Xamarin.Forms 3.0 Vídeo CSS