📺 "One project. One language. Three apps." Learn more in our upcoming code sharing webinar!

NativeScript Angular

User Interface Styling

You change the looks and appearance of views (elements) in a NativeScript application similarly to how you do it in a web application—using Cascading Style Sheets (CSS) or changing the style object of the elements in JavaScript. Only a subset of the CSS language is supported.

Similarly to the DOM Style Object, each View instance exposes a style property, which holds all the style properties for the view. When the view is displayed, all its style properties are applied to the underlying native widget.

NOTE: If you are not using Angular with NativeScript, refer to the Styling docs for NativeScript Core.

Applying CSS styles

The CSS styles can be set on 3 different levels:

If there is CSS declared on different levels—all will be applied. The inline CSS will have the highest priority and the application CSS will have the lowest priority.

It is also possible to apply platform-specific CSS.

Application-wide CSS

When the application starts, NativeScript checks if the file app.css exists. If it does, any CSS styles that it contains are loaded and used across all application pages. This file is a convenient place to store styles that will be used on multiple pages.

You can change the name of the file from which the application-wide CSS is loaded. You need to do the change before the application is started, usually in the app.js or app.ts file as shown below:

platformNativeScriptDynamic({ bootInExistingPage:false, cssFile:"style.css" });

The path to the CSS file is relative to the application root folder.

Component-specific CSS

In an Angular application everything is a component, therefore, it is a very common task to add some CSS code that should only apply to one component. Adding component-specific CSS in a NativeScript-Angular app involves using a component’s styles or styleUrls property.

@Component({
    selector: 'list-test',
    styles: ['.third { background-color: lime; }'],
    template: ...
@Component({
    selector: 'list-test',
    styleUrls: ['style.css'],
    template: ...

In each of these examples, the CSS rules will only apply to the declared component, and not other UI elements in the application.

The styles and styleUrls will be applied even if the component is moved to another page within the application.

Adding CSS from a string

This snippet adds a new style to the current set of styles. This is quite useful when you need to add a small CSS chunk to an element (for example, for testing purposes):

page.addCss("button {background-color: blue}");
page.addCss("button {background-color: blue}");

Adding CSS from a file

This snippet adds new CSS styles to the current set. However, this method reads them from a file. It is useful for organizing styles in files and reusing them across multiple pages.

page.addCssFile(cssFileName);
page.addCssFile(cssFileName);

The path to the CSS file is relative to the application root folder.

Inline CSS

Similarly to HTML, CSS can be defined inline for a UI view in the XML markup:

<Button text="inline style" style="background-color: green;"></Button>

Platform-Specific CSS

NativeScript conventions make it easy to apply platform specific CSS, either via separate stylesheets or via in-line declarations. For an overview of NativeScript's convention-based file name rules for targeting files at specific platforms and screen sizes, refer to this article in the docs. NOTE: If you are using Angular, file name rules do not work for targeting specific screen sizes or orientations. JavaScript is required to target styles at different screens at runtime. See this article for an example of targeting styles at tablets with Angular.

There are 4 primary ways to target styles at iOS or Android:

  1. Platform-specific stylesheets (styles.component.ios.css, styles.component.android.css)
  2. Platform-specific markup blocks (<ios> ... </ios>, <android> ... </android>)
  3. Platform-specific attributes (<Label ios:style="..." android:style="...")
  4. Platform-specific CSS rules (.ios .mystyle { ... }, .android .mystyle { ... }) *requires plugin

The most common and maintainable pattern for managing platform-agnostic and platform-specific styles in NativeScript is with multiple stylesheets and CSS imports. Use this Playground demo to see this pattern in action.

With this pattern, a page (or component) has 3 separate stylesheets: common, iOS and Android. For example, for page home.component.html you would have 3 stylesheets:

  1. home-common.css
  2. home.component.ios.css
  3. home.component.android.css

In both home.component.ios.css and home.component.android.css you then import the shared common styles from home-common.css:

/* Import shared style rules */
@import './home-common.css';

/* Add iOS/Android specific rules (if any) */
.mystyle { ... }

At build time, NativeScript will automatically import the common styles and choose the correct iOS or Android stylesheet depending on the target build platform.

Supported selectors

Currently the CSS support is limited only to the selectors and properties listed in the current article.

NativeScript supports a subset of the CSS selector syntax. Here is how to use the supported selectors:

Type selector

Like CSS element selectors, type selectors in NativeScript select all views of a given type. Type selectors are case insensitive, so you can use both button and Button.

button { background-color: gray }

Class selector

Class selectors select all views with a given class. The class is set using the className property of the view.

.title { font-size: 32 }
var label = new labelModule.Label();
label.className = "title"
let label = new labelModule.Label();
label.className = "title"
<Label className="title" ></Label>

ID selector

Id selectors select all views with a given id. The id is set using the id property of the view.

#login-button { background-color: blue }
var btn = new buttonModule.Button();
btn.id = "login-button"
let btn = new buttonModule.Button();
btn.id = "login-button"
<Button id="login-button" ></Button>

Hierachical selector (CSS combinators)

A CSS selector could contain more than one simple selector, and between selectors a combinator symbol could be included.

  • (space) - Descendant selector. For example, the following code will select all buttons inside StackLayouts (no matter) at which level.
StackLayout Button { background-color: blue; }
<StackLayout>
    <WrapLayout>
        <Button id="login-button" testAttr='flower' ></Button>
    </WrapLayout>
</StackLayout>
  • (>) - A direct child selector. Using the previous example, if the CSS is changed to:
StackLayout > Button { background-color: blue; }

The background-color rule will not be applied. In order to apply the selector, the WrapLayout element would need to be removed so that the Button is a direct child of the StackLayout.

  • (+) - An adjacent sibling selector, allows to select all elements, which are siblings of a specified element. #### Direct sibling test by class
<StackLayout class="layout-class">
    <Label text="Direct sibling test by id"></Label>
    <Button class="test-child" text="First Button"></Button>
    <Button class="test-child-2" text="Second Button"></Button>
</StackLayout>
.layout-class .test-child + .test-child-2 {
  background-color: green;
}

Direct sibling test by id

<StackLayout class="layout-class">
    <Label text="Direct sibling test by id"></Label>
    <Button id="test-child" text="First Button"></Button>
    <Button id="test-child-2" text="Second Button"></Button>
</StackLayout>
.layout-class #test-child + #test-child-2 {
  background-color: green;
}

Direct sibling by type

<StackLayout class="direct-sibling--type">
    <Label text="Direct sibling by type"></Label>
    <Button text="Test Button"></Button>
    <Label text="Test Label"></Label>
    <Button text="Test Button"></Button>
    <Label text="Test Label"></Label>
    <Button text="Test Button"></Button>
    <Label  text="Test Label"></Label>
</StackLayout>
StackLayout Button + Label{
    background-color:green;
    color:white;
}

Attribute selector

button[testAttr]{ background-color: blue; }
<Button testAttr="flower" ></Button>

This selector will select all buttons that have the attribute testAttr with some value.

Also, some more advanced scenarios are supported:

  • button[testAttr='flower'] {...} - Will apply CSS on every button that has the testAttr property set exactly to the value flower.
  • button[testAttr~='flower'] {...} - Selects all buttons with a testAttr property that contains a space-separated list of words, one of which is "flower".
  • button[testAttr|='flower'] {...} - Selects all buttons with a testAttr property value that begins with "flower". The value has to be a whole word, either alone like btn['testAttr'] = 'flower', or followed by hyphen (-), like btn['testAttr'] = 'flower-house'.
  • button[testAttr^='flower'] {...} - Selects all buttons with a testAttr property value that begins with "flower". The value does not have to be a whole word.
  • button[testAttr$='flower'] {...} - Selects all buttons with a testAttr property value that ends with "flower". The value does not have to be a whole word.
  • button[testAttr*='flo'] {...} - Selects all buttons with a testAttr property value that contains "flo". The value does not have to be a whole word.

Attribute selectors could be used alone or could be combined with all type of CSS selectors.

#login-button[testAttr='flower'] { background-color: blue; }
[testAttr] {color: white;}
<Button id="login-button" testAttr='flower' ></Button>
<Label testAttr="some value" ></Label>

Pseudo selector

A pseudo-selector or also pseudo-class is used to define a special state of an element. Currently, NativeScript supports only :highlighted pseudo-selector.

Supported CSS properties

This list of properties can be set in CSS or through the style property of each view:

CSS Property JavaScript Property Description
color color Sets a solid-color value to the matched view’s foreground.
background background Sets a solid-color value or a linear gradient to the matched view’s background.
background-color backgroundColor Sets a solid-color value to the matched view’s background.
placeholder-color placeholderColor Sets the placeholder (hint) font color to matched views.
background-image backgroundImage Sets a image url to the matched view’s background image.
background-repeat backgroundRepeat Sets if/how the background image should be repeated. Possible values: repeat, repeat-x, repeat-y, no-repeat
background-position backgroundPosition Sets the starting position of the background image. You can set the position with absolute, percent or alignment values. More info here.
background-size backgroundSize Sets the size of the background image. Possible values: "length length", "percent% percent%", "cover" or "contain".
border-color borderColor Sets border colors to the matched view’s.
border-top-color borderTopColor Sets a top border color to the matched view’s.
border-right-color borderRightColor Sets a right border color to the matched view’s.
border-bottom-color borderBottomColor Sets a bottom border color to the matched view’s.
border-left-color borderLeftColor Sets a left border color to the matched view’s.
border-width borderWidth Sets border widths to the matched view’s.
border-top-width borderTopWidth Sets a top border width to the matched view’s.
border-right-width borderRightWidth Sets a right border width to the matched view’s.
border-bottom-width borderBottomWidth Sets a bottom border width to the matched view’s.
border-left-width borderLeftWidth Sets a left border width to the matched view’s.
border-radius borderRadius Sets a border radius to the matched view’s.
font font Sets the font properties (this includes font-family, font-size, font-style and font-weight) of the matched view.
font-family fontFamily Sets the font family of the matched view.
font-size fontSize Sets the font size of the matched view (only supports device-independent units).
font-style fontStyle Sets the font style of the matched view. Possible values: italic, normal.
font-weight fontWeight Sets the font weight of the matched view Possible values: bold, normal OR 100,200,300,400,500,600,700,800,900, where 400 is normal and 700 is bold (NOTE: Some fonts do not support all available variants)
text-align textAlignment Sets text alignment in the matched view. Possible values: left , center, right.
text-decoration textDecoration Sets the text formatting. Possible values: none, line-through, underline.
text-transform textTransform Sets the text transform. Possible values: none, capitalize, uppercase, lowercase.
letter-spacing letterSpacing Sets the text letter spacing. (On Android API Level 21 and above.)
line-height lineHeight Sets the text line height
z-index zIndex Sets the z-index. (On Android API Level 21 and above.)
clip-path clip-path Sets the clip-path. Supported shapes are circle, ellipse, rect and polygon. You can define your own shape using clippy
vertical-align verticalAlignment Sets the vertical alignment of the current view within its parent. Possible values: top, center, bottom, stretch.
horizontal-align horizontalAlignment Sets the horizontal alignment of the current view within its parent. Possible values: left, center, right, stretch.
margin margin Sets the margin of the view within its parent.
margin-top marginTop Sets the top margin of the view within its parent.
margin-right marginRight Sets the right margin of the view within its parent.
margin-bottom marginBottom Sets the bottom margin of the view within its parent.
margin-left marginLeft Sets the left margin of the view within its parent.
width width Sets the view width.
height height Sets the view height.
min-width minWidth Sets the minimal view width.
min-height minHeight Sets the minimal view height.
padding padding Sets the distance between the boundaries of the layout container and its children.
padding-top paddingTop Sets the top padding of a layout container.
padding-right paddingRight Sets the right padding of a layout container.
padding-bottom paddingBottom Sets the bottom padding of a layout container.
padding-left paddingLeft Sets the left padding of a layout container.
visibility visibility Sets the view visibility. Possible values: visible, collapse (or collapsed).
opacity opacity Sets the view opacity. The value is in the [0, 1] range.

Supported Measurment Units

As a measurment units, NativeScript supports DIPs (Device Independent Pixels) , pixels (via postfix px) and percentages (partial support for width,height and margin).

The NativeScript's recommended measurment unit is DIP. All measurable properties like width, height, margin, paddings, border-width, etc.) support device independent pixels. The font size are always measured in DIP.

.myLabel {
    font-size: 28;
    width: 200;
    height: 30;
}

The device independent pixels (DIPs) are equal to the device screen's pixels divided by the device screen scale (density).

const screen = require("tns-core-modules/platform").screen;

// mainScreen is of type ScreenMetrics interface https://docs.nativescript.org/api-reference/interfaces/_platform_.screenmetrics
let scale =  screen.mainScreen.scale; 
let widthPixels = screen.mainScreen.widthPixels;
let heightPixels = screen.mainScreen.heightPixels;
let widthDIPs = screen.mainScreen.widthDIPs; // DIPs === pixels/scale (e.g 1024 pixels / 2x scale = 512 DIPs)
let heightDIPs = screen.mainScreen.heightDIPs; 
import { screen } from "tns-core-modules/platform";

// mainScreen is of type ScreenMetrics interface https://docs.nativescript.org/api-reference/interfaces/_platform_.screenmetrics
let scale =  screen.mainScreen.scale; 
let widthPixels = screen.mainScreen.widthPixels;
let heightPixels = screen.mainScreen.heightPixels;
let widthDIPs = screen.mainScreen.widthDIPs; // DIPs === pixels/scale (e.g 1024 pixels / 2x scale = 512 DIPs)
let heightDIPs = screen.mainScreen.heightDIPs; 

NativeScript supports percentage values for width, height and margins. When a layout pass begins, first the percent values are calculated based on parent available size. This means that on vertical StackLayout if you place two Buttons with height='50%' they will get all the available height (e.g., they will fill the StackLayout vertically.). The same applies for marginproperties. For example, if you set marginLeft='5%', the element will have a margin that corresponds to 5% of the parent's available width.

Accessing NativeScript component properties with CSS

You can set NativeScript component properties value that are not part of the CSS specification. For example:

StackLayout {
   orientation: horizontal;
}

This feature is limited to properties with simple types like string, number and boolean, and will set a local property value similar to component markup declaration in XML. CSS inheritance are not supported.

Using fonts

The font-family property can hold several values. The first supported font in the list will be used. There is also support for the following generic font-families:

  • serif (ex. Times New Roman)
  • sans-serif (ex. Helvetica)
  • monospace (ex. Courier New)

Platform specifics:

  • Android: The supported fonts depend very much on the system, thus using the generic font-families or custom-fonts is recommended.
  • iOS: There are more than 30 default fonts available on iOS. You can check the supported fonts for specific iOS versions and devices. To use a built-in font, simply specify the font name in the font-family property, such as font-family: "American Typewriter";. Adjust the font variant using the font-weight property.

Custom fonts

You can use custom fonts in your app (in .TTF or .OTF format). The NativeScript runtime will look for the font files under the app/fonts/ directory and load them automatically.

Custom fonts setup"

Note: In iOS your font file should be named exactly as the font name. If you have doubt about the original font name use Font Book app to get the original font name.

Import CSS

The @import CSS rule allows you to import CSS from local file. This rule must precede all other types of rules.

@import url('~/your-style.css');

Using SASS

With NativeScript, it is possible to manage your app styles using the SASS CSS pre-compiler instead of plain CSS files. Just as with web projects, SASS gives your stylesheets extra capabilities like shared variables, mixins and nested style tags.

To use SASS with NativeScript, the nativescript-dev-sass plugin is required. This plugin will hook-in to the NativeScript build process and automatically convert .scss/.sass files to .css during build and livesync operations. Since SASS is compiled to CSS at build time, it does not require any changes to your stylesheet naming conventions for NativeScript's normal convention-based patterns to work. SASS files with the same name as a NativeScript page will still be automatically linked.

For complete details on adding SASS support to a NativeScript project, see this page in the Theme docs.