CSS(Cascading Style Sheets)를 사용하여 앱 스타일 지정 Xamarin.Forms

Download Sample 샘플 다운로드

Xamarin.Forms 는 CSS(Cascading Style Sheets)를 사용하여 시각적 요소의 스타일을 지정하는 것을 지원합니다.

Xamarin.Forms 애플리케이션은 CSS를 사용하여 스타일을 지정할 수 있습니다. 스타일시트가 규칙 목록으로 구성되며 각 규칙은 하나 이상의 선택기와 선언 블록으로 구성됩니다. 선언 블록은 속성, 콜론 및 값으로 구성된 각 선언과 함께 중괄호로 된 선언 목록으로 구성됩니다. 블록에 여러 선언이 있는 경우 세미콜론이 구분 기호로 삽입됩니다. 다음 코드 예제에서는 일부 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;
}

CSS 스타일시트에서는 Xamarin.Forms컴파일 시간이 아닌 런타임에 구문 분석 및 평가되며, 스타일시트가 사용 시 다시 구문 분석됩니다.

참고 항목

현재 XAML 스타일 지정에서 가능한 모든 스타일은 CSS를 사용하여 수행할 수 없습니다. 그러나 XAML 스타일을 사용하여 현재 지원 Xamarin.Forms되지 않는 속성에 대한 CSS를 보완할 수 있습니다. XAML 스타일에 대한 자세한 내용은 XAML 스타일을 사용하여 Xamarin.Forms 앱 스타일 지정을 참조하세요.

MonkeyAppCSS 샘플은 CSS를 사용하여 간단한 앱의 스타일을 지정하는 방법을 보여 줍니다. 다음 스크린샷에 표시됩니다.

MonkeyApp Main Page with CSS styling

MonkeyApp Detail Page with CSS styling

스타일시트 사용

솔루션에 스타일시트를 추가하는 프로세스는 다음과 같습니다.

  1. .NET Standard 라이브러리 프로젝트에 빈 CSS 파일을 추가합니다.
  2. CSS 파일의 빌드 작업을 EmbeddedResource설정합니다.

스타일시트 로드

스타일시트를 로드하는 데 사용할 수 있는 방법은 여러 가지가 있습니다.

참고 항목

현재 런타임에 스타일시트를 변경하고 새 스타일시트를 적용할 수는 없습니다.

XAML

스타일시트를 로드하고 클래스와 함께 StyleSheet 구문 분석한 후 다음을 ResourceDictionary추가할 수 있습니다.

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

이 속성은 StyleSheet.Source 스타일시트를 바깥쪽 XAML 파일의 위치를 기준으로 하는 URI로 지정하거나, URI가 URI로 시작하는 경우 프로젝트 루트를 /기준으로 지정합니다.

Warning

빌드 작업이 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는 속성을 사용하여 선택한 요소의 스타일을 지정합니다. 각 속성에는 가능한 값 집합이 있으며 일부 속성은 요소의 모든 형식에 영향을 줄 수 있으며 다른 속성은 요소 그룹에 적용됩니다. 지원되는 속성에 대한 자세한 내용은 속성 참조를 참조하세요.

자식 스타일시트는 동일한 속성을 설정하는 경우 항상 부모 스타일시트를 재정의합니다. 따라서 동일한 속성을 설정하는 스타일을 적용할 때 다음 우선 순위 규칙이 따릅니다.

  • 애플리케이션 리소스에 정의된 스타일은 동일한 속성을 설정하는 경우 페이지 리소스에 정의된 스타일로 덮어씁니다.
  • 페이지 리소스에 정의된 스타일은 동일한 속성을 설정하는 경우 컨트롤 리소스에 정의된 스타일로 덮어씁니다.
  • 애플리케이션 리소스에 정의된 스타일은 동일한 속성을 설정하는 경우 컨트롤 리소스에 정의된 스타일로 덮어씁니다.

Important

CSS 변수는 지원되지 않습니다.

형식별 요소 선택

시각적 트리의 요소는 대/소문자를 구분 element 하지 않는 선택기를 사용하여 형식별로 선택할 수 있습니다.

stacklayout {
    margin: 20;
}

이 선택기는 스타일시트를 사용하는 페이지의 요소를 StackLayout 식별하고 여백을 균일한 두께 20으로 설정합니다.

참고 항목

element 선택기는 지정된 형식의 하위 클래스를 식별하지 않습니다.

기본 클래스별 요소 선택

대/소문자를 구분 ^base 하지 않는 선택기를 사용하여 기본 클래스에서 시각적 트리의 요소를 선택할 수 있습니다.

^contentpage {
    background-color: lightgray;
}

이 선택기는 스타일시트를 사용하는 요소를 ContentPage 식별하고 배경색을 .로 lightgray설정합니다.

참고 항목

^base 선택기는 Xamarin.FormsCSS 사양에 속하지 않으며 특정합니다.

이름으로 요소 선택

대/소문자를 구분 #id 하는 선택기를 사용하여 시각적 트리의 개별 요소를 선택할 수 있습니다.

#listView {
    background-color: lightgray;
}

이 선택기는 해당 속성이 .로 설정된 요소를 StyleId 식별합니다 listView. 그러나 속성이 StyleId 설정되지 않은 경우 선택기는 요소의 사용 x:Name 으로 대체됩니다. 따라서 다음 XAML 예제 #listView 에서 선택기는 해당 특성이 설정된 listView특성을 식별하고 ListViewx:Name 배경색을 으로 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 클래스는 요소의 속성을 CSS 클래스 이름으로 설정 StyleClass 하여 XAML 요소에 할당할 수 있습니다. 따라서 다음 XAML 예제에서는 클래스에서 정의한 스타일이 첫 번째 Label스타일에 .detailPageTitle 할당되고 클래스에서 정의한 .detailPageSubtitle 스타일은 두 번째 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>

참고 항목

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>

참고 항목

element>element 선택기를 사용하려면 자식 요소가 부모의 직접 자식이되어야 합니다.

선택기 참조

다음 CSS 선택기는 다음에서 Xamarin.Forms지원됩니다.

선택기 예제 설명
.class .header 'header'가 포함된 속성이 StyleClass 있는 모든 요소를 선택합니다. 이 선택기는 대/소문자를 구분합니다.
#id #email 로 설정된 email모든 요소를 StyleId 선택합니다. 설정되지 않은 경우 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 내의 모든 Label 요소를 StackLayout선택합니다. 이 선택기는 대/소문자를 구분하지 않습니다.
element>element stacklayout>label 직접 부모로 있는 모든 Label 요소를 StackLayout 선택합니다. 이 선택기는 대/소문자를 구분하지 않습니다.
element+element label+entry 바로 뒤에 Label있는 모든 Entry 요소를 선택합니다. 이 선택기는 대/소문자를 구분하지 않습니다.
element~element label~entry 앞에 Label오는 모든 Entry 요소를 선택합니다. 이 선택기는 대/소문자를 구분하지 않습니다.

일치하는 선택기가 있는 스타일은 정의 순서대로 연속적으로 적용됩니다. 특정 항목에 정의된 스타일은 항상 마지막으로 적용됩니다.

선택기는 다음과 같은 StackLayout>ContentView>label.email제한 없이 결합할 수 있습니다.

현재 지원되지 않는 선택기는 다음과 같습니다.

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

참고 항목

특이성 및 특이성 재정의는 지원되지 않습니다.

속성 참조

다음 CSS 속성은 지원 Xamarin.Forms 됩니다(값 열에서 형식은 기울기이고 문자열 리터럴은 다음과 같습니다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 Button, , FrameImageButton 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 ActivityIndicator, BoxView,Button, CheckBox, DatePicker, Editor, Entry, Label, PickerProgressBar, SearchBarSwitchTimePicker 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. 또한 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, PickerSearchBar, TimePickerSpan string | initial font-family: Consolas;
font-size Button,DatePicker, Editor, Entry, Label, PickerSearchBar, TimePickerSpan double | namedsize | initial font-size: 12;
font-style Button,DatePicker, Editor, Entry, Label, PickerSearchBar, 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 Button, DatePicker, Editor, Entry, Label, Picker, SearchBarSearchHandler, SpanTimePicker 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, LayoutPage 두께 | 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 오른쪽 right 에서 왼쪽 환경에서는 피해야 합니다. text-align: right;
text-decoration Label, Span none | underline | strikethrough | line-through | initial text-decoration: underline, line-through;
text-transform Button,Editor, , LabelEntry, SearchBarSearchHandler none | default | uppercase | lowercase | initial text-transform: uppercase;
transform VisualElement none, rotate, rotateX, rotateY, scale, scaleX, scaleY, translatetranslateX, translateYinitial 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;

참고 항목

initial 는 모든 속성에 유효한 값입니다. 다른 스타일에서 설정된 값(기본값으로 다시 설정)을 지웁니다.

현재 지원되지 않는 속성은 다음과 같습니다.

  • all: initial.
  • 레이아웃 속성(상자 또는 눈금).
  • 약식 속성(예: fontborder.

또한 값이 없 inherit 으므로 상속이 지원되지 않습니다. 따라서 예를 들어 레이아웃에서 font-size 속성을 설정하고 레이아웃의 모든 Label 인스턴스가 값을 상속할 것으로 예상할 수 없습니다. 한 가지 예외는 direction 기본값 inherit이 .인 속성입니다.

Span 대상 요소에는 범위가 요소와 이름(기호 사용#)으로 CSS 스타일의 대상이 되는 것을 방지하는 알려진 문제가 있습니다. 요소는 Span 속성이 없 StyleClass 으므로 범위가 CSS 클래스 대상 지정을 지원하지 않는 파생GestureElement됩니다. 자세한 내용은 Span 컨트롤에 CSS 스타일을 적용할 수 없음을 참조 하세요.

Xamarin.Forms 특정 속성

다음과 같은 Xamarin.Forms 특정 CSS 속성도 지원됩니다(값 열에서 형식은 기울기이고 문자열 리터럴은 다음과 같습니다gray.)

속성 적용 대상: 예시
-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, , EditorSearchBar 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 는 .에서 ScrollView만 지원됩니다. -xf-orientation: horizontal;
-xf-placeholder Entry, , EditorSearchBar 따옴표 붙은 텍스트 | initial -xf-placeholder: Enter name;
-xf-placeholder-color Entry, , EditorSearchBar 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 셸 관련 속성

다음 Xamarin.Forms Shell 특정 CSS 속성도 지원됩니다(값 열에서 형식은 기울기이고 문자열 리터럴은 다음과 같습니다gray.)

속성 적용 대상: 예시
-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 같습니다.

  • X11CSS 색, 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 값이 지원됩니다.

  • 단일 값은 균일한 두께를 나타냅니다.
  • 두 값은 세로 및 가로 두께를 나타냅니다.
  • 세 값은 위쪽, 가로(왼쪽 및 오른쪽), 아래쪽 두께를 나타냅니다.
  • 네 개의 값은 위쪽, 오른쪽, 아래쪽, 왼쪽 두께를 나타냅니다.

참고 항목

CSS thickness 값은 XAML Thickness 값과 다릅니다. 예를 들어 XAML에서 두 값 Thickness 은 가로 및 세로 두께를 나타내고, 4개 값 Thickness 은 왼쪽, 위쪽, 오른쪽, 아래쪽 두께를 나타냅니다. 또한 XAML Thickness 값은 쉼표로 구분됩니다.

NamedSize

다음과 같은 경우 구분되지 않는 namedsize 값이 지원됩니다.

  • default
  • micro
  • small
  • medium
  • large

namedsize 값의 정확한 의미는 플랫폼 종속 및 뷰 종속입니다.

함수

선형 및 방사형 그라데이션은 각각 CSS 함수와 radial-gradient() CSS 함수를 사용하여 linear-gradient() 지정할 수 있습니다. 이러한 함수의 결과는 컨트롤의 속성에 background 할당되어야 합니다.

Xamarin.University를 Xamarin.Forms 사용한 CSS

Xamarin.Forms 3.0 CSS 비디오