カスケード スタイル シート (CSS) を使った Xamarin.Forms アプリのスタイル設定
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 アプリのスタイル設定」を参照してください。
次のスクリーンショットのサンプルでは、CSS を使用してシンプルなアプリのスタイルを設定する方法を示します。
スタイル シートの使用
ソリューションにスタイル シートを追加するプロセスは次のとおりです。
- 空の CSS ファイルを .NET Standard ライブラリ プロジェクトに追加します。
- 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 |
StyleId が email に設定されているすべての要素を選択します。 StyleId が設定されていない場合は、x:Name にフォールバックします。 XAML を使用する場合は、x:Name が StyleId より優先されます。 このセレクターでは大文字と小文字が区別されることに注意してください。 |
* |
* |
すべての要素を選択します。 |
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 |
Button 、 Frame 、 ImageButton |
色 | 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 、 ProgressBar 、 SearchBar 、 Switch 、 TimePicker |
色 | 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 |
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 |
太さ | 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 | initial . left と right は右から左の環境では避ける必要があります。 |
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 |
double | initial |
min-width: 320; |
Note
initial
は、すべてのプロパティの有効な値です。 別のスタイルから設定した値 (既定値にリセットされます) をクリアします。
現在、次のプロパティはサポートされていません。
all: initial
.- レイアウトのプロパティ (ボックスまたはグリッド)。
- 短縮形のプロパティ (例:
font
、border
)。
また、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 |
NavigationPage , TabbedPage |
色 | initial |
-xf-bar-background-color: teal; |
-xf-bar-text-color |
NavigationPage , TabbedPage |
色 | 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 |
色 | initial |
-xf-max-track-color: red; |
-xf-min-track-color |
Slider |
色 | initial |
-xf-min-track-color: yellow; |
-xf-orientation |
ScrollView , StackLayout |
horizontal | vertical | both | initial . both は、ScrollView でのみサポートされます。 |
-xf-orientation: horizontal; |
-xf-placeholder |
Entry 、 Editor 、 SearchBar |
引用テキスト | initial |
-xf-placeholder: Enter name; |
-xf-placeholder-color |
Entry 、 Editor 、 SearchBar |
色 | initial |
-xf-placeholder-color: green; |
-xf-spacing |
StackLayout |
double | initial |
-xf-spacing: 8; |
-xf-thumb-color |
Slider , Switch |
色 | 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 の動画