Adicionar estilos aos aplicativos Xamarin Forms nem sempre é uma tarefa simples de se fazer e de se manter. Os estilos no XAML requerem que você conheça especificamente a forma como o Xamarin Forms personaliza seus elementos de tela, coisas espeficicas como propriedades e tags. Além de ser algo específico do Xamarin Forms, caso você queira que um designer personalize seu app, o XAML poderia acabar dificultando um pouco o entendimento.  Você pode ler um pouco mais sobre estilos no XAML do Xamarin Forms na documentação.

Acredito que pensando em facilitar a criação e manutenção de estilos nos aplicativos, o Xamarin Forms irá suportar personalização por arquivos CSS, além de manter a forma de personalização com XAML citada acima.

Para ver um pouco mais esta nova feature que será adicionada ao Xamarin Forms, você pode acessar o PR 1207 disponível no GitHub

Nota: Até a data de publicação deste post, esta funcionalidade estava disponível somente na versão nightly build do Xamarin Forms 2.6+

Adicionando a versão 2.6+ nightly ao seu projeto

Para que você consiga adicionar estilos CSS ao seu projeto, você deve ter a versão 2.6+ nightly build do Xamarin Forms instalado no .Net Standart e em todas as plataformas específicas.

Nota: Para este post, utilizei a versão 2.6.0.62474-nightly

Para visualizar as versões nightly você precisará adicionar como fonte de pacotes Nuget o endereço: https://www.myget.org/F/xamarinforms-ci/api/v2

 
Package Manager

Tools > Options > Nuget Package Manager > Package Sources

Versão Xamarin

O que será suportado?

De acordo com o PR 1207, o CSS do Xamarin Forms terá suporte a alguns selectores do CSS, descritos na tabela abaixo:

Selector Example Description
.class .className Set the StyleClass property on the element. e.g. className
#id #emailEntry Checks StyleId, or fallbacks to x:Name
* * For all elements
element entry Selects all elements of type entry, but not subclasses.
^base ^contentpage Any element with this as a base class, including itself. This is the XF specific selector.
element,element label, entry Selecting multiple elements
element element contentview label Any labels inside a ContentView
element>element contentview>label Selects labels, that are a direct child of a ContentView
element+element label+entry All entry elements that come directly after a label
element~element label~entry All entries that have a label before it.

Veja também as propriedades que serão suportadas.

Vale lembrar que apesar de estar utilizando CSS, é importante que você siga estas referências para que tudo funcione como esperado.

Property Applies to Values (string literals are grayed, while types are italic) Example
background-color VisualElement color (see Colors) | initial background-color: springgreen;
background-image Page string | initial background-image: bg.png;
border-color Button, Frame color (see Colors) | initial border-color: #9acd32;
border-width Button double | initial border-width: .5;
color Button, DatePicker, Editor, Entry, Label, Picker, SearchBar, TimePicker color (see Colors) | initial color: rgba(255, 0, 0, 0.3);
direction VisualElement ltr | rtl | inherit, initial direction: rtl;
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 double | namedsize (see 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;
margin View thickness (see Thickness) | initial margin: 6 12;
margin-left View thickness (see Thickness) | initial margin-left: 3;
margin-top View thickness (see Thickness) | initial margin-top: 2;
margin-right View thickness (see Thickness) | initial margin-right: 1;
margin-bottom View thickness (see Thickness) | initial margin-bottom: 6;
min-height VisualElement double | initial `min-height: 50;
min-width VisualElement double | initial `min-width: 112;
opacity VisualElement double | initial opacity: .3;
padding Layout, Page thickness (see Thickness) | initial padding: 6 12 12;
padding-left Layout, Page double | initial padding-left: 3;
padding-top Layout, Page double | initial padding-top: 4;
padding-right Layout, Page double | initial padding-right: 2;
padding-bottom Layout, Page double | initial padding-bottom: 6;
text-align Entry, EntryCell, Label, SearchBar left | right | center | start | end | initial. It is recommended to avoid left and right in non-ltr environments text-align: right;
visibility VisualElement true | visible | false | hidden | collapse | initial visibility: hidden;
width VisualElement double | initial `min-width: 320;

Criando o arquivo CSS

Você pode adotar a estrutura de organização de arquivos que for melhor para você e seu time. Neste exemplo vou criar uma pasta Styles no projeto .Net Standart para armazenar meu arquivo .css
Crie um novo arquivo css no seu projeto na pasta Styles, eu adicionei o trexo de código abaixo para personlizar meu botão, meu label e meu stacklayout, mas você pode utilizar qualquer personalização que seja suportada nos seletores e tags citados acima.

.botao {
    background-color: #11313F;
    color: white;
    font-size: 16;
    height: 60;
    border: 0;
}

#boasVindas {
    color: red;
    font-size: 25;
}

stacklayout {
    background-color: yellow;
    height:100;
    width: 100;
    margin: 10;
}

Para que o arquivo CSS seja reconhecido pelo aplicativo em tempo de execução é necessário setar a propriedade Build Action para Embedded resource.

Referenciando o arquivo CSS

Após criado o arquivo CSS e adicionado os estilos, precisamos referencia-lo na página que queremos que seja aplicado. Neste exemplo irei referenciar na própria MainPage.xaml adicionando o seguinte trecho de código após a decalaração da ContentPage


<ContentPage.Resources>
    <StyleSheet Source="Styles/MainView.css" />
</ContentPage.Resources>

Após referenciado os estilos que possuem seletores como ID e Elemento já serão automaticamente aplicados.

Para chamar sua classe CSS em um elemento específico da tela, você pode utilizar a propriedade StyleClass e preenche-la com o nome da classe criada no arquivo CSS referenciado na página. Como no exemplo abaixo:


<Button Text="Entrar" StyleClass="botao" />

MainPage.xaml


    <ContentPage.Resources>
        <StyleSheet Source="Styles/style.css" />
    </ContentPage.Resources>

    <ContentPage.Content>
        <StackLayout>
            <Label Text="SEJA BEM VINDO!" x:Name="boasVindas" />
            <Button Text="Entrar" StyleClass="botao" />
        </StackLayout>
    </ContentPage.Content>

É recomendável que você referencie o seu CSS no XAML da página, mas você também pode referenciar o arquivo CSS através do Code-Behind da adicionando o código abaixo:

this.Resources.Add(StyleSheet.FromAssemblyResource(this.GetType().Assembly, "css.id"));

Feito isto, basta rodar o app e verificar se seus elementos foram personalizados de acordo com o arquivo CSS.

Conclusão

O recurso de personalização do CSS ainda está em nightly build e por isso ainda não é recomendado utilizar em produção.

A utilização do CSS trará muitos benefícios para a personalização dos aplicativos, seja para criação do estilo ou para manutenção. É um recurso bastante interessante que está sendo implementado, e de acordo com o PR, não deve sofrer muitas alterações na versão final.  Nem tudo do CSS será suportado, o !important por exemplo não será,  por isso é importante utilizar a tabela citada neste post que foi retirada do PR para criação dos estilos.

A utilização do CSS não elimanará a personalização com XAML como já vem sendo feita, você ficará livre para escolher o que for melhor para você e seu time.

O código completo do exemplo deste post está disponível no meu GitHub

#Ubuntu

Referencias

https://github.com/xamarin/Xamarin.Forms/pull/1207

https://xamarinhelp.com/css-xamarin-forms/

https://javiersuarezruiz.wordpress.com/2018/01/02/xamarin-forms-estilos-con-css/

Imagem utilizada no post Negative Space

(Cross-post de http://rsamorim.azurewebsites.net/2018/01/03/xamarin-forms-personalizando-seu-app-com-css/ )

Robson Soares Amorim