Partilhar via


Estilizando Xamarin.Forms aplicativos usando folhas de estilos em cascata (CSS)

Xamarin.Forms oferece suporte ao estilo de elementos visuais usando folhas de estilos em cascata (CSS).

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 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 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 tempo de compilação, e as folhas de estilo são analisadas novamente em 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 são suportadas pelo 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:

Página principal do MonkeyApp com estilo CSS

Página de detalhes do MonkeyApp com estilo CSS

Consumindo uma folha de estilos

O processo para adicionar uma folha de estilos a uma solução é o seguinte:

  1. Adicione um arquivo CSS vazio ao seu projeto de biblioteca do .NET Standard.
  2. Defina a ação de compilação 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 tempo de execução e aplicar a nova folha de estilos.

XAML

Uma folha de estilos pode ser carregada e analisada com a classe antes de ser adicionada StyleSheet 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 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 EmbeddedResource.

Como alternativa, uma folha de estilos pode ser carregada e analisada com a StyleSheet classe, antes de ser adicionada a um ResourceDictionary, inserindo-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 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.

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 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 Xamarin.Forms, 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 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 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

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: 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 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 listview image seletor identificará o Image que é 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 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 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 CSS são suportados por 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 como email. Se StyleId não estiver definido, fallback para x:Name. Ao usar XAML, x:Name é preferível a .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 si mesmo. 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 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 StackLayoutarquivo . Observe que esse seletor não diferencia maiúsculas de minúsculas.
element>element stacklayout>label Seleciona todos os Label elementos com StackLayout como 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 Labelarquivo . Observe que esse seletor não diferencia maiúsculas de minúsculas.
element~element label~entry Seleciona todos os Entry elementos precedidos por um Labelarquivo . Observe que esse 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 no momento:

  • [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 por Xamarin.Forms (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, Button, Frame, ImageButton double | initial border-radius: 10;
border-width Button, ImageButton double | initial border-width: .5;
color ActivityIndicator, BoxView, Button, CheckBox, DatePicker, Editor, Entry, Label, , Picker, SearchBarProgressBarSwitchTimePicker 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, 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 Double | NamedSize | 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, Picker, , SearchBar, SearchHandler, , Span, 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 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, 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 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. Ele limpa o valor (redefine para padrão) que foi definido de outro estilo.

As seguintes propriedades não são suportadas no momento:

  • all: initial.
  • Propriedades de layout (caixa ou grade).
  • Propriedades taquigráficas, como font, e border.

Além disso, não inherit há valor e, portanto, a herança não é 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.

A segmentação Span de elementos tem um problema conhecido que impede que extensões 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 StyleClass propriedade para que as extensões não ofereçam 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 seguintes Xamarin.Forms propriedades CSS específicas 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
-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ó é suportado em um ScrollViewarquivo . -xf-orientation: horizontal;
-xf-placeholder Entry, Editor, SearchBar texto citado | 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 são 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:

  • X11cores, que correspondem a cores CSS, cores pré-definidas 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% 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 Thickness espessura horizontal e vertical, enquanto um valor de quatro indica Thickness espessura esquerda, depois superior, direita e inferior. Além disso, os valores XAML Thickness são delimitados por vírgula.

NamedSize

Há suporte para os seguintes valores sem diferenciação de maiúsculas e minúsculas namedsize :

  • default
  • micro
  • small
  • medium
  • large

O significado exato de cada namedsize valor é dependente da plataforma e da visualização.

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.

CSS em Xamarin.Forms com Xamarin.University

Xamarin.Forms 3.0 Vídeo CSS