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

.NET Multi-Platform App 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ファイルはどのフォルダにも置くことができますが、Resources フォルダを推奨します。
  2. CSS ファイルのビルド アクションを MauiCssに設定します。

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

スタイル シートの読み込みに使用できる方法は多数あります。

Note

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

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

スタイル シートは、ResourceDictionary に追加する前に、StyleSheet クラスでロードして解析できます。

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

StyleSheet.Source プロパティは、スタイル シートを、それを囲んでいる XAML ファイルの保存先を基準とした相対 URI、または URI が / で始まる場合はプロジェクト ルートを基準とした相対 URI として指定します。

警告

CSS ファイルのビルド アクションが MauiCss に設定されていない場合、CSS ファイルは読み込めません。

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

<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 color | initial background-color: springgreen;
background-image Page string | initial background-image: bg.png;
border-color ButtonFrameImageButton color | initial border-color: #9acd32;
border-radius BoxViewButtonFrameImageButton double | initial border-radius: 10;
border-width ButtonImageButton double | initial border-width: .5;
color ActivityIndicatorBoxViewButtonCheckBoxDatePickerEditorEntryLabelPickerProgressBarSearchBarSwitchTimePicker 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 | 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 color | initial -maui-bar-background-color: teal;
-maui-bar-text-color NavigationPageTabbedPage color | 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 color | initial -maui-max-track-color: red;
-maui-min-track-color Slider color | 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 color | initial -maui-placeholder-color: green;
-maui-spacing StackLayout double | initial -maui-spacing: 8;
-maui-thumb-color SliderSwitch color | 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 color | initial -maui-flyout-background: red;
-maui-shell-background Element color | initial -maui-shell-background: green;
-maui-shell-disabled Element color | initial -maui-shell-disabled: blue;
-maui-shell-foreground Element color | initial -maui-shell-foreground: yellow;
-maui-shell-tabbar-background Element color | initial -maui-shell-tabbar-background: white;
-maui-shell-tabbar-disabled Element color | initial -maui-shell-tabbar-disabled: black;
-maui-shell-tabbar-foreground Element color | initial -maui-shell-tabbar-foreground: gray;
-maui-shell-tabbar-title Element color | initial -maui-shell-tabbar-title: lightgray;
-maui-shell-tabbar-unselected Element color | initial -maui-shell-tabbar-unselected: cyan;
-maui-shell-title Element color | initial -maui-shell-title: teal;
-maui-shell-unselected Element color | 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 では、2 つの値 Thickness は水平、垂直の厚さを示します。一方、4 つの値 Thickness は、左、上、右、下の厚さを示します。 さらに、XAML Thickness 値はコンマで区切られます。

関数

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