Applicazione di Xamarin.Forms stili alle app con fogli di stile CSS (Cascading Style Sheets)

Download Sample Scaricare l'esempio

Xamarin.Forms supporta lo stile degli elementi visivi usando css (Cascading Style Sheets).

Xamarin.Forms le applicazioni possono essere styled tramite CSS. Un foglio di stile è costituito da un elenco di regole, con ogni regola costituita da uno o più selettori e da un blocco di dichiarazione. Un blocco di dichiarazione è costituito da un elenco di dichiarazioni tra parentesi graffe, con ogni dichiarazione costituita da una proprietà, da due punti e da un valore. Quando sono presenti più dichiarazioni in un blocco, come separatore viene inserito un punto e virgola. L'esempio di codice seguente illustra alcuni Xamarin.Forms CSS conformi:

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;
}

In Xamarin.Formsi fogli di stile CSS vengono analizzati e valutati in fase di esecuzione, anziché in fase di compilazione e i fogli di stile vengono rivalutati in uso.

Nota

Attualmente, tutti gli stili possibili con lo stile XAML non possono essere eseguiti con CSS. Tuttavia, gli stili XAML possono essere usati per integrare CSS per le proprietà attualmente non supportate da Xamarin.Forms. Per altre informazioni sugli stili XAML, vedi Applicazione Xamarin.Forms di stili alle app con stili XAML.

L'esempio MonkeyAppCSS illustra l'uso di CSS per applicare uno stile a un'app semplice ed è illustrato negli screenshot seguenti:

MonkeyApp Main Page with CSS styling

MonkeyApp Detail Page with CSS styling

Utilizzo di un foglio di stile

Il processo di aggiunta di un foglio di stile a una soluzione è il seguente:

  1. Aggiungere un file CSS vuoto al progetto di libreria .NET Standard.
  2. Impostare l'azione di compilazione del file CSS su EmbeddedResource.

Caricamento di un foglio di stile

Esistono diversi approcci che possono essere usati per caricare un foglio di stile.

Nota

Non è attualmente possibile modificare un foglio di stile in fase di esecuzione e applicare il nuovo foglio di stile.

XAML

È possibile caricare e analizzare un foglio di stile con la StyleSheet classe prima di essere aggiunto a un ResourceDictionaryoggetto :

<Application ...>
    <Application.Resources>
        <StyleSheet Source="/Assets/styles.css" />
    </Application.Resources>
</Application>

La StyleSheet.Source proprietà specifica il foglio di stile come URI relativo al percorso del file XAML contenitore o relativo alla radice del progetto se l'URI inizia con un oggetto /.

Avviso

Il file CSS non verrà caricato se l'azione di compilazione non è impostata su EmbeddedResource.

In alternativa, un foglio di stile può essere caricato e analizzato con la StyleSheet classe , prima di essere aggiunto a un ResourceDictionary, inlining in una CDATA sezione:

<ContentPage ...>
    <ContentPage.Resources>
        <StyleSheet>
            <![CDATA[
            ^contentpage {
                background-color: lightgray;
            }
            ]]>
        </StyleSheet>
    </ContentPage.Resources>
    ...
</ContentPage>

Per altre informazioni sui dizionari risorse, vedere Dizionari risorse.

C#

In C# un foglio di stile può essere caricato da un StringReader oggetto e aggiunto a un ResourceDictionaryoggetto :

public partial class MyPage : ContentPage
{
    public MyPage()
    {
        InitializeComponent();

        using (var reader = new StringReader("^contentpage { background-color: lightgray; }"))
        {
            this.Resources.Add(StyleSheet.FromReader(reader));
        }
    }
}

L'argomento del StyleSheet.FromReader metodo è l'oggetto TextReader che ha letto il foglio di stile.

Selezione di elementi e applicazione di proprietà

CSS usa selettori per determinare gli elementi di destinazione. Gli stili con selettori corrispondenti vengono applicati consecutivamente, in ordine di definizione. Gli stili definiti in un elemento specifico vengono sempre applicati per ultimo. Per altre informazioni sui selettori supportati, vedere Riferimenti al selettore.

CSS usa le proprietà per applicare uno stile a un elemento selezionato. Ogni proprietà ha un set di valori possibili e alcune proprietà possono influire su qualsiasi tipo di elemento, mentre altre si applicano ai gruppi di elementi. Per altre informazioni sulle proprietà supportate, vedere Informazioni di riferimento sulle proprietà.

I fogli di stile figlio eseguono sempre l'override dei fogli di stile padre se impostano le stesse proprietà. Di conseguenza, vengono seguite le regole di precedenza seguenti quando si applicano stili che impostano le stesse proprietà:

  • Uno stile definito nelle risorse dell'applicazione verrà sovrascritto da uno stile definito nelle risorse della pagina, se impostano le stesse proprietà.
  • Uno stile definito nelle risorse di pagina verrà sovrascritto da uno stile definito nelle risorse del controllo, se impostano le stesse proprietà.
  • Uno stile definito nelle risorse dell'applicazione verrà sovrascritto da uno stile definito nelle risorse del controllo, se impostano le stesse proprietà.

Importante

Le variabili CSS non sono supportate.

Selezione di elementi per tipo

Gli elementi nella struttura ad albero visuale possono essere selezionati per tipo con il selettore senza distinzione tra maiuscole element e minuscole:

stacklayout {
    margin: 20;
}

Questo selettore identifica gli StackLayout elementi nelle pagine che utilizzano il foglio di stile e imposta i margini su uno spessore uniforme di 20.

Nota

Il element selettore non identifica le sottoclassi del tipo specificato.

Selezione di elementi per classe base

Gli elementi nella struttura ad albero visuale possono essere selezionati dalla classe base con il selettore senza distinzione tra maiuscole ^base e minuscole:

^contentpage {
    background-color: lightgray;
}

Questo selettore identifica tutti gli ContentPage elementi che utilizzano il foglio di stile e imposta il colore di sfondo su lightgray.

Nota

Il ^base selettore è specifico di Xamarin.Formse non fa parte della specifica CSS.

Selezione di un elemento in base al nome

È possibile selezionare singoli elementi nella struttura ad albero visuale con il selettore con distinzione tra maiuscole e minuscole #id :

#listView {
    background-color: lightgray;
}

Questo selettore identifica l'elemento la cui StyleId proprietà è impostata su listView. Tuttavia, se la StyleId proprietà non è impostata, il selettore eseguirà il fallback all'utilizzo dell'elemento x:Name . Nell'esempio XAML seguente, quindi, il #listView selettore identificherà l'attributo ListViewx:Name impostato su listViewe imposta il colore di sfondo su lightgray.

<ContentPage ...>
    <ContentPage.Resources>
        <StyleSheet Source="/Assets/styles.css" />
    </ContentPage.Resources>
    <StackLayout>
        <ListView x:Name="listView" ...>
            ...
        </ListView>
    </StackLayout>
</ContentPage>

Selezione di elementi con un attributo di classe specifico

Gli elementi con un attributo di classe specifico possono essere selezionati con il selettore con distinzione tra maiuscole e minuscole .class :

.detailPageTitle {
    font-style: bold;
    font-size: medium;
    text-align: center;
}

.detailPageSubtitle {
    text-align: center;
    font-style: italic;
}

Una classe CSS può essere assegnata a un elemento XAML impostando la StyleClass proprietà dell'elemento sul nome della classe CSS. Nell'esempio XAML seguente, pertanto, gli stili definiti dalla .detailPageTitle classe vengono assegnati al primo Label, mentre gli stili definiti dalla .detailPageSubtitle classe vengono assegnati al secondo Label.

<ContentPage ...>
    <ContentPage.Resources>
        <StyleSheet Source="/Assets/styles.css" />
    </ContentPage.Resources>
    <ScrollView>
        <StackLayout>
            <Label ... StyleClass="detailPageTitle" />
            <Label ... StyleClass="detailPageSubtitle"/>
            ...
        </StackLayout>
    </ScrollView>
</ContentPage>

Selezione di elementi figlio

Gli elementi figlio nella struttura ad albero visuale possono essere selezionati con il selettore senza distinzione element element tra maiuscole e minuscole:

listview image {
    height: 60;
    width: 60;
}

Questo selettore identifica tutti gli Image elementi figlio di ListView elementi e ne imposta l'altezza e la larghezza su 60. Nell'esempio XAML seguente, quindi, il listview image selettore identificherà l'elemento Image figlio di ListViewe ne imposta l'altezza e la larghezza su 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>

Nota

Il selettore non richiede che l'elemento figlio sia un elemento figlio diretto dell'elemento padre. L'elemento element element figlio può avere un elemento padre diverso. La selezione viene eseguita a condizione che un predecessore sia il primo elemento specificato.

Selezione di elementi figlio diretti

È possibile selezionare elementi figlio diretti nella struttura ad albero visuale con il selettore senza distinzione tra maiuscole element>element e minuscole:

stacklayout>image {
    height: 200;
    width: 200;
}

Questo selettore identifica tutti gli Image elementi figlio diretti degli StackLayout elementi e ne imposta l'altezza e la larghezza su 200. Nell'esempio XAML seguente, quindi, il stacklayout>image selettore identificherà l'elemento Image figlio diretto di StackLayoute ne imposta l'altezza e la larghezza su 200.

<ContentPage ...>
    <ContentPage.Resources>
        <StyleSheet Source="/Assets/styles.css" />
    </ContentPage.Resources>
    <ScrollView>
        <StackLayout>
            ...
            <Image ... />
            ...
        </StackLayout>
    </ScrollView>
</ContentPage>

Nota

Il element>element selettore richiede che l'elemento figlio sia un figlio diretto dell'elemento padre.

Informazioni di riferimento sul selettore

I selettori CSS seguenti sono supportati da Xamarin.Forms:

Selettore Esempio Descrizione
.class .header Seleziona tutti gli elementi con la StyleClass proprietà contenente 'header'. Si noti che questo selettore fa distinzione tra maiuscole e minuscole.
#id #email Seleziona tutti gli elementi con StyleId impostato su email. Se StyleId non è impostato, eseguire il fallback su x:Name. Quando si usa XAML, x:Name è preferibile rispetto StyleIda . Si noti che questo selettore fa distinzione tra maiuscole e minuscole.
* * Seleziona tutti gli elementi.
element label Seleziona tutti gli elementi di tipo Label, ma non le sottoclassi. Si noti che questo selettore non fa distinzione tra maiuscole e minuscole.
^base ^contentpage Seleziona tutti gli elementi con ContentPage come classe di base, incluso ContentPage se stesso. Si noti che questo selettore non fa distinzione tra maiuscole e minuscole e non fa parte della specifica CSS.
element,element label,button Seleziona tutti gli Button elementi e tutti gli Label elementi. Si noti che questo selettore non fa distinzione tra maiuscole e minuscole.
element element stacklayout label Seleziona tutti gli Label elementi all'interno di un oggetto StackLayout. Si noti che questo selettore non fa distinzione tra maiuscole e minuscole.
element>element stacklayout>label Seleziona tutti gli Label elementi con StackLayout come elemento padre diretto. Si noti che questo selettore non fa distinzione tra maiuscole e minuscole.
element+element label+entry Seleziona tutti gli Entry elementi direttamente dopo un oggetto Label. Si noti che questo selettore non fa distinzione tra maiuscole e minuscole.
element~element label~entry Seleziona tutti gli Entry elementi preceduti da un oggetto Label. Si noti che questo selettore non fa distinzione tra maiuscole e minuscole.

Gli stili con selettori corrispondenti vengono applicati consecutivamente, in ordine di definizione. Gli stili definiti in un elemento specifico vengono sempre applicati per ultimo.

Suggerimento

I selettori possono essere combinati senza limitazioni, ad esempio StackLayout>ContentView>label.email.

I selettori seguenti non sono attualmente supportati:

  • [attribute]
  • @media e @supports
  • : e ::

Nota

La specificità e le sostituzioni di specificità non sono supportate.

Informazioni di riferimento sulle proprietà

Le proprietà CSS seguenti sono supportate da Xamarin.Forms (nella colonna Valori i tipi sono corsivi, mentre i valori letterali stringa sono gray):

Proprietà Si applica a Valori Esempio
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 string | initial background-image: bg.png;
border-color Button, Frame, ImageButton color | initial border-color: #9acd32;
border-radius BoxView, Button, FrameImageButton double | initial border-radius: 10;
border-width Button, ImageButton double | initial border-width: .5;
color ActivityIndicatorButton, BoxView, CheckBox, DatePicker, Editor, Entry, LabelPicker, , ProgressBarSearchBar, , SwitchTimePicker 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 float | | autoinitial. Inoltre, con il % segno è possibile specificare una percentuale compresa tra 0% e 100%. 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, LabelPicker, SearchBar, , TimePickerSpan string | initial font-family: Consolas;
font-size Button, DatePicker, Editor, Entry, LabelPicker, SearchBar, , TimePickerSpan double | namedsize | initial font-size: 12;
font-style Button, DatePicker, Editor, Entry, LabelPicker, SearchBar, , TimePickerSpan 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 ButtonEditor, DatePicker, , Entry, LabelPicker, SearchBar, SearchHandler, , SpanTimePicker double | initial letter-spacing: 2.5;
line-height Label, Span double | initial line-height: 1.8;
margin View Spessore | initial margin: 6 12;
margin-left View Spessore | initial margin-left: 3;
margin-top View Spessore | initial margin-top: 2;
margin-right View Spessore | initial margin-right: 1;
margin-bottom View Spessore | 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, LayoutPage Spessore | initial padding: 6 12 12;
padding-left Button, ImageButton, LayoutPage double | initial padding-left: 3;
padding-top Button, ImageButton, LayoutPage double | initial padding-top: 4;
padding-right Button, ImageButton, LayoutPage double | initial padding-right: 2;
padding-bottom Button, ImageButton, LayoutPage double | initial padding-bottom: 6;
position FlexLayout relative | absolute | initial position: absolute;
row-gap Grid double | initial row-gap: 12;
text-align Entry, EntryCell, LabelSearchBar left | top | right | bottom | start | center | middle | end | initial. left e right devono essere evitati in ambienti da destra a sinistra. text-align: right;
text-decoration Label, Span none | underline | strikethrough | line-through | initial text-decoration: underline, line-through;
text-transform ButtonEntry,Editor , Label, , SearchBar,SearchHandler none | default | uppercase | lowercase | initial text-transform: uppercase;
transform VisualElement none, rotate, , rotateY, scalescaleX, translatescaleYtranslateX, translateYrotateXinitial 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 double | initial min-width: 320;

Nota

initial è un valore valido per tutte le proprietà. Cancella il valore (reimposta il valore predefinito) impostato da un altro stile.

Le proprietà seguenti non sono attualmente supportate:

  • all: initial.
  • Proprietà del layout (casella o griglia).
  • Proprietà abbreviate, ad esempio font, e border.

Inoltre, non esiste alcun inherit valore e quindi l'ereditarietà non è supportata. Non è quindi possibile, ad esempio, impostare la font-size proprietà in un layout e prevedere che tutte le Label istanze del layout ereditino il valore. L'unica eccezione è la direction proprietà , che ha un valore predefinito di inherit.

La destinazione Span degli elementi presenta un problema noto che impedisce agli intervalli di essere la destinazione degli stili CSS in base sia all'elemento che al nome (usando il # simbolo). L'elemento Span deriva da GestureElement, che non dispone della proprietà , pertanto gli intervalli non supportano la StyleClass destinazione della classe CSS. Per altre informazioni, vedere Non è possibile applicare stili CSS al controllo Span.

Xamarin.Forms proprietà specifiche

Sono supportate anche le proprietà CSS specifiche seguenti Xamarin.Forms (nella colonna Valori i tipi sono corsivi, mentre i valori letterali stringa sono gray):

Proprietà Si applica a Valori Esempio
-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 è supportato solo in un oggetto ScrollView. -xf-orientation: horizontal;
-xf-placeholder Entry, Editor, SearchBar testo racchiuso tra virgolette | 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 string | initial -xf-visual: material;

Xamarin.Forms Proprietà specifiche della shell

Sono supportate anche le proprietà CSS specifiche della shell seguenti Xamarin.Forms (nella colonna Valori i tipi sono corsivi, mentre i valori letterali stringa sono gray):

Proprietà Si applica a Valori Esempio
-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

Sono supportati i valori seguenti color :

  • X11colori, che corrispondono ai colori CSS, ai colori predefiniti della piattaforma UWP e Xamarin.Forms ai colori. Si noti che questi valori di colore non fanno distinzione tra maiuscole e minuscole.
  • colori esadecimali: #rgb, #argb, #rrggbb, #aarrggbb
  • colori rgb: rgb(255,0,0), rgb(100%,0%,0%). I valori sono compresi nell'intervallo compreso tra 0 e 255 o 0%-100%.
  • colori rgba: rgba(255, 0, 0, 0.8), rgba(100%, 0%, 0%, 0.8). Il valore di opacità è compreso nell'intervallo 0.0-1.0.
  • colori hsl: hsl(120, 100%, 50%). Il valore h è compreso nell'intervallo compreso tra 0 e 360, mentre s e l sono compresi nell'intervallo 0%-100%.
  • hsla colors: hsla(120, 100%, 50%, .8). Il valore di opacità è compreso nell'intervallo 0.0-1.0.

Thickness

Uno, due, tre o quattro thickness valori sono supportati, ognuno separato da spazi vuoti:

  • Un singolo valore indica lo spessore uniforme.
  • Due valori indicano lo spessore verticale e orizzontale.
  • Tre valori indicano la parte superiore, quindi orizzontale (sinistra e destra), quindi spessore inferiore.
  • Quattro valori indicano in alto, quindi a destra, quindi in basso, quindi spessore sinistro.

Nota

I valori CSS thickness differiscono dai valori XAML Thickness . Ad esempio, in XAML un valore Thickness a due valori indica lo spessore orizzontale e verticale, mentre un valore Thickness a quattro valori indica a sinistra, quindi in alto, in alto, a destra, quindi nello spessore inferiore. Inoltre, i valori XAML Thickness sono delimitati da virgole.

NamedSize

Sono supportati i valori senza distinzione tra maiuscole e minuscole namedsize seguenti:

  • default
  • micro
  • small
  • medium
  • large

Il significato esatto di ogni namedsize valore è dipendente dalla piattaforma e dipendente dalla visualizzazione.

Funzioni

È possibile specificare sfumature lineari e radiali usando rispettivamente le linear-gradient() funzioni CSS e radial-gradient() . Il risultato di queste funzioni deve essere assegnato alla background proprietà di un controllo .

CSS in Xamarin.Forms con Xamarin.University

Xamarin.Forms Video CSS 3.0