カスケード スタイル シート (CSS) を使った Xamarin.Forms アプリのスタイル設定

Download Sampleサンプルのダウンロード

Xamarin.Forms では、カスケード スタイル シート (CSS) を使ったビジュアル要素のスタイル設定がサポートされています。

Xamarin.Forms アプリケーションは、CSS を使用してスタイルを設定できます。 スタイル シートはルールのリストで構成され、各ルールは 1 つ以上のセレクターと宣言ブロックで構成されます。 宣言ブロックは、プロパティ、コロン、値で構成される各宣言で、中かっこ内の宣言の一覧で構成されます。 ブロック内に複数の宣言がある場合は、セミコロンが区切り記号として挿入されます。 次のコード例は、Xamarin.Forms に準拠している CSS の一部を示します。

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

Xamarin.Forms では、CSS スタイル シートがコンパイル時ではなく実行時に解析および評価され、使用時にスタイル シートが再解析されます。

Note

現時点では、XAML スタイル設定で実行できるすべてのスタイル設定を CSS で実行することはできません。 ただし、現在 Xamarin.Forms でサポートされていないプロパティについて、XAML スタイルを使用して CSS を補完できます。 XAML スタイルの詳細については、「XAML スタイルを使用した Xamarin.Forms アプリのスタイル設定」を参照してください。

次のスクリーンショットの MonkeyAppCSS のサンプルでは、CSS を使用してシンプルなアプリのスタイルを設定する方法を示します。

MonkeyApp Main Page with CSS styling

MonkeyApp Detail Page with CSS styling

スタイル シートの使用

ソリューションにスタイル シートを追加するプロセスは次のとおりです。

  1. 空の CSS ファイルを .NET Standard ライブラリ プロジェクトに追加します。
  2. CSS ファイルのビルド アクションを EmbeddedResource に設定します。

スタイル シートの読み込み

スタイル シートの読み込み方法は多数あります。

Note

現時点では、実行時にスタイル シートを変更し、新しいスタイル シートを適用することはできません。

XAML

スタイル シートは、StyleSheet クラスを使用して読み込んで解析してから、ResourceDictionary に追加できます。

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

StyleSheet.Source プロパティは、外側の XAML ファイルの場所に関わる URI、あるいは URI が / で開始した場合は、プロジェクト ルートに関わる URI としてスタイル シートを指定します。

警告

ビルド アクションが EmbeddedResource に設定されていない場合、CSS ファイルの読み込みは失敗します。

または、スタイル シートを読み込んで StyleSheet クラスで解析してから、CDATA セクション内にインライン展開して、スタイル シートを ResourceDictionary に追加することもできます。

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

リソース ディクショナリの詳細については、「リソース ディクショナリ」をご覧ください。

C#

C# では、スタイル シートを StringReader から読み込んで、次のように ResourceDictionary に追加できます。

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

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

StyleSheet.FromReader メソッドの引数は、スタイル シートを読み取った TextReader です。

要素の選択とプロパティの適用

CSS はセレクターを使用して、どの要素をターゲットにするかを決定します。 セレクターが一致するスタイルを、定義順に連続して適用します。 特定の項目に定義されているスタイルは、常に最後に適用されます。 サポートされているセレクターの詳細については、「セレクター リファレンス」を参照してください。

CSS では、プロパティを使用して選択した要素のスタイルを設定します。 各プロパティには考えられる一連の値があり、一部のプロパティは任意の種類の要素に影響を与え、他のプロパティは要素のグループに適用します。 サポートされているプロパティの詳細については、「プロパティ リファレンス」を参照してください。

子スタイルシートは、同じプロパティを設定する場合、常に親スタイルシートをオーバーライドします。 そのため、同じプロパティを設定するスタイルを適用する場合は、次の優先順位の規則に従います。

  • 同じプロパティを設定した場合、アプリケーション リソースで定義されているスタイルは、ページ リソースで定義されているスタイルによって上書きされます。
  • ページ リソースで定義されているスタイルは、同じプロパティを設定した場合、コントロール リソースで定義されているスタイルで上書きされます。
  • 同じプロパティを設定した場合、アプリケーション リソースで定義されているスタイルは、コントロール リソースで定義されているスタイルによって上書きされます。

重要

CSS 変数はサポートされていません。

型による要素の選択

ビジュアル ツリー内の要素は、大文字と小文字を区別しない element セレクターで、型によって選択できます。

stacklayout {
    margin: 20;
}

このセレクターは、スタイル シートを使用するページ上の StackLayout 要素を識別し、余白を 20 の均一な太さに設定します。

Note

element セレクターは、指定された型のサブクラスを識別しません。

基底クラスで要素を選択する

ビジュアル ツリー内の要素は、大文字と小文字を区別しない ^base セレクターを使用して基底クラスで選択できます。

^contentpage {
    background-color: lightgray;
}

このセレクターは、スタイル シートを使用するあらゆる ContentPage 要素を識別し、その背景色を lightgray に設定します。

Note

^base セレクターは Xamarin.Forms に固有のものであり、CSS 仕様の一部ではありません。

名前で要素を選択する

ビジュアル ツリー内の個々の要素は、大文字と小文字を区別する #id セレクターを使用して選択できます。

#listView {
    background-color: lightgray;
}

このセレクターは、StyleId プロパティが listView に設定されている要素を識別します。 ただし、StyleId プロパティが設定されていない場合、セレクターはフォールバックして要素の x:Name を使用します。 したがって、次の XAML の例では、#listView セレクターは x:Name 属性が listView に設定されている ListView を識別し、背景色を lightgray に設定します。

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

特定のクラス属性を持つ要素の選択

特定のクラス属性を持つ要素は、大文字と小文字を区別する .class セレクターで選択できます。

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

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

CSS クラスは、要素の StyleClass プロパティを CSS クラス名に設定することで、XAML 要素に割り当てることができます。 したがって、次の XAML の例では、.detailPageTitle クラスによって定義されたスタイルが最初の Label に割り当てられますが、.detailPageSubtitle クラスによって定義されたスタイルは 2 番目の Label に割り当てられます。

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

子要素の選択

ビジュアル ツリー内の子要素は、大文字と小文字を区別しない element element セレクターで選択できます。

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

このセレクターは、ListView 要素の子である Image 要素を識別し、その高さと幅を 60 に設定します。 したがって、次の XAML の例では、listview image セレクターは、ListView の子である Image を識別し、その高さと幅を 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>

Note

element element セレクターでは、子要素が親の直接の子である必要はありません。場合によっては、子要素に別の親があります。 先祖が指定した最初の要素である場合、選択が行われます。

直接の子要素の選択

ビジュアル ツリー内の直接の子要素は、大文字と小文字を区別しない element>element セレクターで選択できます。

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

このセレクターは、StackLayout 要素の直接の子である Image 要素を識別し、その高さと幅を 200 に設定します。 したがって、次の XAML の例では、stacklayout>image セレクターが StackLayout の直接の子である Image を識別し、その高さと幅を 200 に設定します。

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

Note

element>element セレクターでは、子要素が親の直接の子である必要があります。

セレクター リファレンス

Xamarin.Forms では次の CSS セレクターがサポートされています。

セレクター 説明
.class .header "header" を含んだ StyleClass プロパティを持つすべての要素を選択します。 このセレクターでは大文字と小文字が区別されることに注意してください。
#id #email StyleIdemail に設定されているすべての要素を選択します。 StyleId が設定されていない場合は、x:Name にフォールバックします。 XAML を使用する場合は、x:NameStyleId より優先されます。 このセレクターでは大文字と小文字が区別されることに注意してください。
* * すべての要素を選択します。
element label Label 型のすべての要素を選択しますが、サブクラスは選択しません。 このセレクターでは大文字と小文字が区別されないことに注意してください。
^base ^contentpage ContentPage 自体を含め、ContentPage を基底クラスとするすべての要素を選択します。 このセレクターでは大文字と小文字が区別されず、CSS 仕様の一部ではないことに注意してください。
element,element label,button すべての Button 要素とすべての Label 要素を選択します。 このセレクターでは大文字と小文字が区別されないことに注意してください。
element element stacklayout label StackLayout 内のすべての Label 要素を選択します。 このセレクターでは大文字と小文字が区別されないことに注意してください。
element>element stacklayout>label StackLayout を直接の親とするすべての Label 要素を選択します。 このセレクターでは大文字と小文字が区別されないことに注意してください。
element+element label+entry Label の直後にあるすべての Entry 要素を選択します。 このセレクターでは大文字と小文字が区別されないことに注意してください。
element~element label~entry Label の前の Entry 要素をすべて選択します。 このセレクターでは大文字と小文字が区別されないことに注意してください。

セレクターが一致するスタイルを、定義順に連続して適用します。 特定の項目に定義されているスタイルは、常に最後に適用されます。

ヒント

セレクターは、StackLayout>ContentView>label.email のような制限なく組み合わせることができます。

現在、次のセレクターはサポートされていません。

  • [attribute]
  • @media および @supports
  • : および ::

Note

特殊性および特殊性のオーバーライドはサポートされていません。

プロパティ リファレンス

Xamarin.Forms では、次の CSS プロパティがサポートされています ([値] 列で型は "斜体"、文字列リテラルは gray で示します)。

プロパティ 適用対象
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 | initial background-color: springgreen;
background-image Page string | initial background-image: bg.png;
border-color ButtonFrameImageButton | initial border-color: #9acd32;
border-radius BoxView, Button, Frame, ImageButton double | initial border-radius: 10;
border-width ButtonImageButton double | initial border-width: .5;
color ActivityIndicatorBoxViewButtonCheckBoxDatePickerEditorEntryLabelPickerProgressBarSearchBarSwitchTimePicker | 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 | auto | initial。 さらに、0% から 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, Label, Picker, SearchBar, TimePicker, Span string | 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 ButtonDatePickerEditorEntryLabelPickerSearchBarSearchHandlerSpanTimePicker double | initial letter-spacing: 2.5;
line-height LabelSpan double | initial line-height: 1.8;
margin View 太さ | initial margin: 6 12;
margin-left View 太さ | initial margin-left: 3;
margin-top View 太さ | initial margin-top: 2;
margin-right View 太さ | initial margin-right: 1;
margin-bottom View 太さ | 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 太さ | 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 | initialleftright は右から左の環境では避ける必要があります。 text-align: right;
text-decoration LabelSpan none | underline | strikethrough | line-through | initial text-decoration: underline, line-through;
text-transform ButtonEditorEntryLabelSearchBarSearchHandler 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 doubledouble | 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;

Note

initial は、すべてのプロパティの有効な値です。 別のスタイルから設定した値 (既定値にリセットされます) をクリアします。

現在、次のプロパティはサポートされていません。

  • all: initial
  • レイアウトのプロパティ (ボックスまたはグリッド)。
  • 短縮形のプロパティ (例: fontborder)。

また、inherit の値がないため、継承はサポートされていません。 そのためたとえば、レイアウトに font-size プロパティを設定して、レイアウト内のすべての Label インスタンスが値を継承することを想定することはできません。 1 つの例外は direction プロパティで、既定値は inherit です。

Span 要素をターゲットに設定すると、(# シンボルを使用する) 要素と名前の両方でスパンが CSS スタイルのターゲットにならないという、既知の問題があります。 Span 要素は StyleClass プロパティを持たない GestureElement から派生するため、スパンでは CSS クラスのターゲット設定をサポートしません。 詳細については、「Span コントロールに CSS スタイル設定を適用できない」を参照してください。

Xamarin.Forms 固有のプロパティ

次の Xamarin.Forms 固有の CSS プロパティもサポートされています ([値] 列で型は "斜体"、文字列リテラルは gray で示します)。

プロパティ 適用対象
-xf-bar-background-color NavigationPageTabbedPage | initial -xf-bar-background-color: teal;
-xf-bar-text-color NavigationPageTabbedPage | 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 EntryEditorSearchBar int | initial -xf-max-length: 20;
-xf-max-track-color Slider | initial -xf-max-track-color: red;
-xf-min-track-color Slider | initial -xf-min-track-color: yellow;
-xf-orientation ScrollViewStackLayout horizontal、 | 、vertical、 | 、both、 | 、initial both は、ScrollView でのみサポートされます。 -xf-orientation: horizontal;
-xf-placeholder EntryEditorSearchBar 引用テキスト | initial -xf-placeholder: Enter name;
-xf-placeholder-color EntryEditorSearchBar | initial -xf-placeholder-color: green;
-xf-spacing StackLayout double | initial -xf-spacing: 8;
-xf-thumb-color SliderSwitch | 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 シェル固有のプロパティ

次の Xamarin.Forms Shell 固有の CSS プロパティもサポートされています ([値] 列で型は "斜体"、文字列リテラルは gray で示します)。

プロパティ 適用対象
-xf-flyout-background Shell | initial -xf-flyout-background: red;
-xf-shell-background Element | initial -xf-shell-background: green;
-xf-shell-disabled Element | initial -xf-shell-disabled: blue;
-xf-shell-foreground Element | initial -xf-shell-foreground: yellow;
-xf-shell-tabbar-background Element | initial -xf-shell-tabbar-background: white;
-xf-shell-tabbar-disabled Element | initial -xf-shell-tabbar-disabled: black;
-xf-shell-tabbar-foreground Element | initial -xf-shell-tabbar-foreground: gray;
-xf-shell-tabbar-title Element | initial -xf-shell-tabbar-title: lightgray;
-xf-shell-tabbar-unselected Element | initial -xf-shell-tabbar-unselected: cyan;
-xf-shell-title Element | initial -xf-shell-title: teal;
-xf-shell-unselected Element | initial -xf-shell-unselected: limegreen;

サポートされている color 値を次に示します。

  • X11の色。CSS の色、UWP の定義済みの色、Xamarin.Forms の色に一致します。 これらの色の値では大文字と小文字が区別されません。
  • 16 進数の色: #rgb#argb#rrggbb#aarrggbb
  • RGB 色: rgb(255,0,0)rgb(100%,0%,0%)。 値の範囲は 0 ~ 255、または 0% ~ 100% です。
  • RGBA 色: rgba(255, 0, 0, 0.8)rgba(100%, 0%, 0%, 0.8)。 不透明度の値の範囲は 0.0 ~ 1.0 です。
  • HSL 色: hsl(120, 100%, 50%)。 H の値の範囲は 0 ~ 360 の範囲で、S と L は 0% ~ 100% の範囲です。
  • HSLA 色: hsla(120, 100%, 50%, .8)。 不透明度の値の範囲は 0.0 ~ 1.0 です。

厚さ

1 つ、2 つ、3 つ、または 4 つの thickness 値がサポートされ、それぞれ空白で区切られます。

  • 値が 1 つの場合は、厚さが均一であることを示します。
  • 値が 2 つの場合は、垂直方向、水平方向の厚さを示します。
  • 値が 3 つの場合は、上面、水平方向 (左と右)、下面の厚さを示します。
  • 値が 4 つの場合は、上、右、下、左の厚さの順に示します。

Note

CSS の thickness 値は、XAML の Thickness 値とは異なります。 たとえば、XAML では、Thickness の値が 2 つの場合は水平方向と垂直方向の厚さを示し、Thickness の値が 4 つの場合は左、上面、右、下面の厚さを示します。 さらに、XAML Thickness 値はコンマで区切られます。

NamedSize

次の大文字と小文字が区別されない namedsize 値がサポートされています。

  • default
  • micro
  • small
  • medium
  • large

namedsize 値の正確な意味は、プラットフォームとビューに依存します。

関数

直線的なグラデーションと放射状のグラデーションは、それぞれ CSS 関数 linear-gradient()radial-gradient() を使用して指定できます。 これらの関数の結果は、コントロールの background プロパティに割り当てる必要があります。

Xamarin University で学ぶ Xamarin.Forms の CSS

Xamarin.Forms 3.0 CSS の動画