カスケード スタイル シートを使用してアプリをスタイル設定する

.NET マルチプラットフォーム アプリ UI (.NET MAUI) アプリは、カスケード スタイル シート (CSS) を使用してスタイルを設定できます。 スタイル シートはルールのリストで構成され、各ルールは 1 つ以上のセレクターと宣言ブロックで構成されます。 宣言ブロックは、プロパティ、コロン、値で構成される各宣言で、中かっこ内の宣言の一覧で構成されます。 ブロック内に複数の宣言がある場合は、セミコロンが区切り記号として挿入されます。

次の例は、.NET MAUI に準拠している CSS を示しています。

navigationpage {
    -maui-bar-background-color: lightgray;
}

^contentpage {
    background-color: lightgray;
}

#listView {
    background-color: lightgray;
}

stacklayout {
    margin: 20;
    -maui-spacing: 6;
}

grid {
    row-gap: 6;
    column-gap: 6;
}
.mainPageTitle {
    font-style: bold;
    font-size: 14;
}

.mainPageSubtitle {
    margin-top: 15;
}

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

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

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

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

.NET MAUI では、CSS スタイル シートはコンパイル時ではなく実行時に解析して評価し、スタイル シートは使用中に再解析します。

重要

CSS を使用して .NET MAUI アプリのスタイルを完全に設定することはできません。 ただし、XAML スタイルを使用して CSS を補完できます。 XAML スタイルの詳細については、「XAML でアプリをスタイル設定する」をご覧ください。

スタイル シートを使用する

.NET MAUI アプリにスタイル シートを追加するプロセスは次のとおりです。

  1. 空の CSS ファイルを .NET MAUI アプリ プロジェクトに追加します。 CSS ファイルは任意のフォルダーに配置することができ、推奨場所は [リソース] フォルダーです。
  2. CSS ファイルのビルド アクションを MauiCss に設定します。

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

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

Note

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

XAML でスタイル シートを読み込む

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

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

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

警告

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

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

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

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

C# でスタイル シートを読み込む

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

using Microsoft.Maui.Controls.StyleSheets;

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

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

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

Note

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

型で要素を選択する

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

stacklayout {
    margin: 20;
}

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

Note

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

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

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

^contentpage {
    background-color: lightgray;
}

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

Note

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

名前で要素を選択する

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

#listView {
    background-color: lightgray;
}

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

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

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

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

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

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

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

<ContentPage ...>
    <ContentPage.Resources>
        <StyleSheet Source="/Resources/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="/Resources/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 に設定します。 したがって、次の例では、stacklayout>image セレクターは、StackLayout の直接の子である Image を識別し、その高さと幅を 200 に設定します。

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

Note

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

セレクター リファレンス

.NET MAUI では、次の 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

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

プロパティ リファレンス

次の CSS プロパティが .NET MAUI でサポートされています ([値] 列で、文字列リテラルは 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 BoxViewButtonFrameImageButton 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 ButtonDatePickerEditorEntryLabelPickerSearchBarTimePickerSpan string | initial font-family: Consolas;
font-size ButtonDatePickerEditorEntryLabelPickerSearchBarTimePickerSpan double | initial font-size: 12;
font-style ButtonDatePickerEditorEntryLabelPickerSearchBarTimePickerSpan bold | italic | initial font-style: bold;
height VisualElement double | initial 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 ButtonImageButtonLayoutPage 太さ | initial padding: 6 12 12;
padding-left ButtonImageButtonLayoutPage double | initial padding-left: 3;
padding-top ButtonImageButtonLayoutPage double | initial padding-top: 4;
padding-right ButtonImageButtonLayoutPage double | initial padding-right: 2;
padding-bottom ButtonImageButtonLayoutPage double | initial padding-bottom: 6;
position FlexLayout relative | absolute | initial position: absolute;
row-gap Grid double | initial row-gap: 12;
text-align EntryEntryCellLabelSearchBar 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 nonerotaterotateXrotateYscalescaleXscaleYtranslatetranslateXtranslateYinitial 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 width: 320;

Note

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

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

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

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

重要

Span 要素を CSS を使用してターゲットにすることはできません。

.NET MAUI 固有のプロパティ

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

プロパティ 適用対象
-maui-bar-background-color NavigationPageTabbedPage | initial -maui-bar-background-color: teal;
-maui-bar-text-color NavigationPageTabbedPage | initial -maui-bar-text-color: gray
-maui-horizontal-scroll-bar-visibility ScrollView default | always | never | initial -maui-horizontal-scroll-bar-visibility: never;
-maui-max-length EntryEditorSearchBar int | initial -maui-max-length: 20;
-maui-max-track-color Slider | initial -maui-max-track-color: red;
-maui-min-track-color Slider | initial -maui-min-track-color: yellow;
-maui-orientation ScrollViewStackLayout horizontal | vertical | both | initialboth は、ScrollView でのみサポートされます。 -maui-orientation: horizontal;
-maui-placeholder EntryEditorSearchBar 引用テキスト | initial -maui-placeholder: Enter name;
-maui-placeholder-color EntryEditorSearchBar | initial -maui-placeholder-color: green;
-maui-spacing StackLayout double | initial -maui-spacing: 8;
-maui-thumb-color SliderSwitch | initial -maui-thumb-color: limegreen;
-maui-vertical-scroll-bar-visibility ScrollView default | always | never | initial -maui-vertical-scroll-bar-visibility: always;
-maui-vertical-text-alignment Label start | center | end | initial -maui-vertical-text-alignment: end;
-maui-visual VisualElement string | initial -maui-visual: material;

NET MAUI Shell 固有のプロパティ

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

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

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

  • X11。CSS の色と .NET MAUI の色にマッチします。 これらの色値は、大文字と小文字が区別されます。
  • 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 値はコンマで区切られます。

関数

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