Ionic Sass

A Guide to Styling an Ionic 2 Application



·

One thing I really like about Ionic is that the default components look great right out of the box. Everything is really neat, sleek and clean…

…but also maybe a little boring. I like simple, simple is great – but you probably don’t want your app to look like every other app out there. Here’s an example of a couple Ionic 2 applications that I’ve done some custom styling for:

Giflist Screenshots

Giflist is currently available on app stores, just click the image

Quick Lists Screenshot

I certainly don’t claim to be some design guru, but I think the themes I’ve created for these applications are visually pleasing and help give the apps some character.

So, in this tutorial I’m going to show you the different ways you can customise your Ionic 2 applications, and the theory behind theming in general.

Introduction to Theming in Ionic 2

When styling an Ionic 2 application, there is nothing inherently different or special about it – it’s no different than the way you would style a normal website. I often see questions like “Can I create [Insert UI element / interface] in Ionic?” and the answer is generally yes. Could you do it on a normal webpage? If you can then you can do it in Ionic as well.

A lot of people may be used to just editing CSS files to change styles, but there is some added complexity with Ionic, which is primarily due to the fact that it uses SASS. Again, SASS isn’t specific to Ionic or mobile web app development – it can also be used on any normal website – but many people may not be as familiar with SASS as they are with CSS.

If you’re not already familiar, .scss is the file type for SASS or Syntactically Awesome Style Sheets. If this is new to you, you should read more about what SASS is and what it does here. For those of you short on time, what you put in your .scss files is exactly the same as what you would put in .css files, you can just do a bunch of extra cool stuff as well like define variables that can be reused in multiple areas. These .scss files are then compiled into normal .css files (it’s basically the same concept we use in Ionic 2, where we code using all the fancy new ES6 features, but that is then transpiled into ES5 which is actually supported by browsers now.

When theming your application, you’re mainly going to be editing your .html templates and .scss stylesheets – you will NEVER edit any .css files directly. The .css files are generated from the .scss files, so if you make any changes to the .css file it’s just going to get overwritten.

If you take a look at the files generated when you create a new Ionic 2 project, you will see some .scss files so, let’s quickly run through what their purpose is.

  • app.scss is the main .scss file. It is used to declare any styles that will be used globally throughout the application. Although it is the “main” .scss file, you won’t likely use it often – most of the styling will happen in the component specific .scss files.
  • variables.scss is used to modify the apps shared variables. Here you can edit the default values for things like the $colors map which sets up the default colours for the application, $list-background-color, $checkbox-ios-background-color-on and so on. For a list of all the variables that you can overwrite, take a look at this page

On top of these .scss files, you will also have one for each component you create (or at least you should). To refresh your memory, most components you create in Ionic 2 will look like this:

  • mycomponent
    • mycomponent.ts
    • mycomponent.html
    • mycomponent.scss

We have a class definition in the .ts file, the template in the .html file and any styles for the component in the .scss file. Although it’s not strictly required, you should always create the .scss file for any components that have styling, rather than just defining the style in the app.scss file.

NOTE: By using the ionic g page MyPage command all the files you need will automatically be set up for you.

Why shouldn’t you put styles in app.scss? Well you could just put all of your styles in the app.scss file and everything would work exactly the same, but there are two major benefits to splitting your styles up in the way I described above:

  1. Organisation – Splitting your code up in this way will keep the size of your files down, making it a lot easier to maintain. Since all of the styles for a particular component can be found in that components .scss file, you’ll never have to search around much.
  2. Modularity – one of the main reasons for the move to this component style architecture in Angular 2 and Ionic 2 is modularity. Before, code would be very intertwined and hard to separate and reuse. Now, almost all the code required for a particular feature is contained within its own folder, and it could easily be reused and dropped into other projects.

Since each component can be given its own selector, i.e:

@Component({
  selector: 'my-page',
  templateUrl: 'my-page.html'
})

You can easily use SASS nesting to make sure rules you create only affect that one component, i.e:

my-page {

  img {
    width: 100%:
    height: auto;
  }

}

With the above .scss file, only images in the MyPage component will be affected by that rule. You can also nest within the ios and md classes to specifically only target iOS or Android, i.e:

.ios, .md {

    my-page {

      img {
        width: 100%:
        height: auto;
      }

    }

}

This will apply the styles to both iOS and Android, but you can target each class specifically if you like. Now that we’ve gone over the theory, let’s look at how to actually start styling our Ionic 2 applications.

Methods for Theming an Ionic 2 Application

I’m going to cover a few different ways you can alter the styles in your application. It may seem a little unclear what way to do things because in a lot of cases you could achieve the same thing using any of the following 3 methods I’m about to list. In general, you should try to style your applications using the methods below in the order they appear. If you can do it using method #1 use that, if not use method #2 and finally use method #3 if you need to.

1. Attributes

One of the easiest ways to change the style of your application is to simply add an attribute to the element you’re using. As I mentioned above, SASS is used to define some colours, and these are:

  • primary
  • secondary
  • danger
  • light
  • dark

Ionic provides some defaults for what these colours are, but you can also override each of these to be any colours you want (which we will talk about soon). So if you add the primary attribute to most elements it will turn blue, or if you add the danger attribute it will be a red colour.

So for example, if I wanted to use the secondary colour on a button I could do this:

<button color="secondary"></button>

or if I wanted to use the secondary colour on a the nav bar I could do this:

<ion-navbar color="secondary"></ion-navbar>

Keep in mind that these attributes aren’t limited to just changing the colour of elements, some attributes will also change things like the position:

<ion-navbar color="secondary">
  <ion-buttons end>
    <button ion-button color="primary">I'm a primary coloured button in the end position of the nav bar</button>
  </ion-buttons>
</ion-navbar>

whether or not a list should have borders:

<ion-list no-lines></ion-list>

or even whether a list item should display an arrow to indicate that it can be tapped:

<ion-item detail-none></ion-item>

There’s a bunch more of these attributes, so make sure to poke around the documentation when you are using Ionics built-in components. The no-lines attribute is a real easy way to remove lines from a list, but if you didn’t know this attribute existed (which is quite possible) then you’d likely end up creating your own custom styles unnecessarily.

2. SASS Variables

The next method you can use to control the style of your application is by changing the default SASS variables. These are really handy because it allows you to make app wide style changes to specific things. I touched on SASS variables before, but basically in your .scss files you can do something like this:

$my-variable: red;

and then you could reference $my-variable anywhere in the .scss file. So for example if you wanted to make the background colour on 20 different elements red, rather than doing:

background-color: red;

for all of them, you could instead do this:

background-color: $my-variable;

The benefit of this is that now if you wanted to change the background color from red to green, all you have to do is edit that one variable – not every single class you have created.

Ionic defines and uses a bunch of these variables, and you can easily overwrite them to be something else. Let’s take a look at a few:

  • $background-color
  • $link-color
  • $list-background-color
  • $list-border-color
  • $menu-width
  • $segment-button-ios-activated-transition

You can look at the documentation for more information on these and what they default to, but it’s pretty clear by their name what they do. As you can see by the last example there, they even get very specific.

Editing these variables is really simple, just open variables.scss and insert your own definitions. Here’s an example of one of my variables.scss files:

$colors: (
  primary:    #387ef5,
  secondary:  #32db64,
  danger:     #f53d3d,
  light:      #f4f4f4,
  dark:       #222
);

$list-background-color: #fff;
$list-ios-activated-background-color: #3aff74;
$list-md-activated-background-color: #3aff74;

$checkbox-ios-background-color-on: #32db64;
$checkbox-ios-icon-border-color-on: #fff;

$checkbox-md-icon-background-color-on: #32db64;
$checkbox-md-icon-background-color-off: #fff;
$checkbox-md-icon-border-color-off: #cecece;
$checkbox-md-icon-border-color-on: #32db64;

Notice the use of md here, this stand for material design and is used for Android. Ionic 2 seamlessly adapts to the conventions of the platform it is running on with little to no style changes required from you – for Android this means material design is used.

The great thing about editing these default SASS variables is that you can, with one change, make all the changes necessary everywhere in the app. Some variables use the values of other variables, so if you wanted to just do this manually with CSS you would probably need to make a lot of edits to get the effect you wanted.

3. Custom Styles

Before we talked about using attributes to change the colours of elements. Given that you can override these attributes to whatever you like, it’s a good approach to set the primary, secondary, danger etc. variables to match the colour palette of your design, and then use those to set the styles of elements, rather than defining custom CSS classes.

But, sometimes there will come a time where you need to define some plain old CSS classes to achieve what you want. You can either define these custom classes in app.scss if the class will be used throughout the application, or in an individual component’s .scss file if it is only going to be used for one component.

Of course, you can also define custom styles on the element directly by using the style tag, but make sure you use this sparingly.

Summary

As you can see, there are a few different ways you can change the styling of your Ionic 2 applications. In general, it’s best to do as little as possible to achieve what you need. Try to achieve as much as you can with attributes and SASS variables, because not only will this make your life easier, it will also make Ionic’s job easier (which in turn, is also good for you!).

As I mentioned before, Ionic seamlessly adapts to the UI conventions of both iOS and Android, so the more “hacky” or “brute force” your solution for styling is, the greater chance you have of breaking this behaviour.

What to watch next...

  • edanweis

    Thanks Josh! I’d love to get started, but I’m having trouble with `ionic setup sass`. It says No gulpfile found. Is this CLI command still required? Tried a bunch of solutions from Ionic forums and SA posts with no luck.

    • No need to run `ionic setup sass` in Ionic 2 🙂

  • How do you access $colors(‘primary’) variable inside sass file?

    • hodispk

      If you asking how can you apply it here’s an example:
      This text will be red if the primary is color red</p

    • Eduardo Lara Rabelo

      Here’s an example: background-color: color($colors, primary);
      Not sure if this is the best way, but it works =)

  • Keith Moore

    Thanks for the great article. By the way “Ionics in built components”, I think you meant “Ionics’ built-in components.”

    • Andrew Forrest

      It would be “Ionic’s”—singular posessive.

  • ghenry22

    This article was really helpful for me trying to transition from ionic v1 to v2. I have a related question (possibly a future post topic). Starting with the default sidemenu starter app. If I wanted to have a solid red side menu (using the danger color variable) how would i achieve this? I have tried messing around with the different components and it seems like the only thing that responds is the color of the top tool bar. Eveything else stays adamantly white.

    Also if I want to do more with the side menu should it be split into it’s own menu component rather than just being embedded in the root app.html/app.js?

    Another possibility would be an image as the background for the menu vs a solid color. These seem like they would be fairly common use cases for app styling but I can’t seem to find a tutorial or any references probably because ionic2 is still very new.

    Sorry of these are more obvious than I realise, just trying to get my head around the right way to do this.

  • Pingback: An In Depth Look at the Grid System in Ionic 2 | HTML5 Mobile Tutorials | Ionic, Phaser, Sencha Touch & PhoneGap()

  • M. Ali Setia Pratama

    Hey, do you know how to change the background color for one page, but not the whole app ?

    As i know, if we want to change the background color for the whole app, we should just override $background-color variable in app.variables.scss.

    But, what if i want to just change the background color of a particular page ?

    Thanks!

  • nadreal

    Once I change .toolbar-background {background-color: green;} in any of scss all my page’s header change color to green.
    What I need is to have different (side-menu color) and different color for each of pages

  • Pingback: Tips & Tricks for Styling Ionic 2 Applications | HTML5 Mobile Tutorials | Ionic, Phaser, Sencha Touch & PhoneGap()

  • Tobias Mücksch

    Thank you! The third part “custom styles” really helped me a lot!

  • Balog Dominik

    You are amasing. Thank you.

  • Pingback: Building a Hotel Booking App with Ionic 2, MongoDB & Node | joshmorony - Build Mobile Apps with HTML5()

  • Pingback: An In Depth Look at the Grid System in Ionic 2 | joshmorony - Build Mobile Apps with HTML5()

  • Fábio Burkard

    Hi, Josh! I really love your tutorials!

    One question: is there a way to change a button from “primary” to “outline” (or secondary, etc), from the code? I mean, not hacking it via css, but more directly…

    I’m trying to make a toggle button, so it should change from “on” (primary) to “off” (outline).

    I know there’s a toggle component, but it would be a lot cooler this way =D

    Thanks in advance!!

  • Pingback: Create an Animated Login Screen in Ionic 2 | joshmorony - Build Mobile Apps with HTML5()

  • Marko Djordjevic

    Like

  • JB

    Hi Josh,
    In this articule, you say:

    Since each component can be given its own selector, i.e:

    @Component({
    selector: ‘my-page’,
    templateUrl: ‘my-page.html’
    })
    You can easily use SASS nesting to make sure rules you create only affect that one component, i.e:

    my-page {

    img {
    width: 100%:
    height: auto;
    }

    }
    With the above .scss file, only images in the MyPage component will be affected by that rule. Now that we’ve gone over the theory, let’s look at how to actually start styling our Ionic 2 applications.

    but…

    what about this?

    http://ionicframework.com/docs/v2/faq/#common-mistakes

    so, what is the right way?

    Regards!

    • I’m not sure what you’re referring to on that page

      • JB

        This page talks about common mistakes when using ionic 2

        Page components acting odd
        Page components that are loaded with NavController do not need selectors added to them. If you place a selector on a page component, chances are it will animate incorrectly and have the wrong styles applied to it.

        Wrong

        @Component({
        selector: ‘my-page’,
        template: `

        Login

        Hello World`
        })
        export class StartPage {}

        Correct

        @Component({
        template: `

        Login

        Hello World`
        })
        export class StartPage {}

      • That’s outdated, adding selectors to pages was introduced in RC.0 I believe.

  • didi one

    Thank you very much Josh, this tutorial made my night 🙂
    I really learned stuff that i never thought they excisted in ionic2 CSS

  • amine

    give me code source please

  • Gail Parsloe

    Hello. Thanks for your tutorial. It’s very helpful.

    Is there a list of attributes (‘start’ and ‘end’ for buttons, for example) somewhere ? I’ve looked on the Components documentation page (http://ionicframework.com/docs/api/components/button/Button/) and on the API page (
    https://ionicframework.com/docs/api/components/button/Button/). Neither has a list of attributes available. There are a few examples, but I can’t find a list of attributes available. I’d like to see all the attributes that are available.

  • Guillermo Acosta

    Hi Josh, nice guide.
    Thanks for sharing. I’m working trying to style an Ionic 2 app, and I need your help
    I´m trying to set an image as a backgorund for ion-content of a ionic page, I need this image degraded, so with opacity I put it 0.6 and it works.

    Ion-content {
    Background-image: url (‘../assets/back/2.jpg’);
    -webkit-background-image: url (‘../assets/back/2.jpg’);
    Opacity: 0.50;
    }

    But the problem is that it also applies apha to all the images that I show in grid (or card o col) within ion-content.

    The question: how do I change the opacity of the background image without also affecting the opacity of the images I want to display in ion-content, as content?

    Thanks in advance!

  • Matt Hart

    Your articles are excellent Josh, especially to a back-end developer who’s had no exposure to Web design and dived straight into ionic.

    My only comment is, although I can write something like:

    Is that the right approach?
    Shouldn’t my html defining structure and content with all my styling within selectors in sccs files?

  • akshat

    Sir, I am having a problem that if I want to change default button size using ionic sass variable for a specific page for instance home page, how do I achieve it? I mean if I add someIonicDefaultVariable: someValue to variables.sass the changes are global or if I add to page-home sass file, there are no changes at all.
    Thanks and Regards.

  • Michelle Diamond

    Hi, Please can you advise regarding what gets overwritten when updating ionic. Im a bit dubious about overwriting default sass

  • Kristof De Laet

    Hey,

    I created a settings page in my app with a toggle button, if the toggle is checked I want the primary color to change to a different color for the whole app.
    What’s the best way of doing this?

  • Mohamed Yassin

    can you list the process to use a theme from the ionic themes
    i make a lot of search but i didn’t make it yet