New! Check out my advanced Ionic tutorials at eliteionic.com

A Primer on CSS Variables/Custom Properties for Ionic

Another significant addition to Ionic available since version 4 is support for CSS variables/custom properties, which will now play the primary role in Ionic’s theming approach. In this article, we are going to take a brief look at what CSS4 variables are and how we will be using them in Ionic applications.

NOTE: Since originally writing this article, Ionic has also now also added support for CSS Shadow Parts which provides another way to style Ionic components that are protected by a Shadow DOM.

In previous versions of Ionic, the theming and styling of Ionic relied mostly on using SASS, where we would define .scss files that would be compiled down into standard CSS at runtime. Ionic will still be making use of SASS (which comes included by default for Angular projects), so if you are currently making use of SASS in your project you don’t need to worry about changing things up too much.

One of the key differences between using something like SASS and CSS variables is that SASS is a preprocessor whereas CSS variables make use of standard CSS that is supported by browsers (i.e. no compile/transpile step is required). The functionality made available through SASS doesn’t actually exist, we just use SASS style syntax, and then SASS will compile that into “normal” CSS for our application to use. This is basically the same idea as using TypeScript – the TypeScript we write doesn’t actually run in browsers, but the TypeScript compiler will convert that code into “normal” JavaScript that can be understood by browsers.

Why Use CSS Variables?

SASS provides us with more than just the ability to create variables in CSS, so why should we care about using CSS variables when the result is the same? It’s cool that we could use those without setting up SASS, but that’s already set up in Ionic anyway. What’s the big deal?

Primarily, there are two key benefits to using CSS variables:

  • CSS variables can be modified at runtime. Since CSS variables are supported natively by the browser, there is no compile step required to get the variables working. This means that you could just open up the browser debugger, modify some variables, and see the changes take effect in your application immediately. This also means that you can modify these variables dynamically in your application. This would make it quite easy to build functionality like a light/dark theme switcher, where a user could toggle a switch and instantly change the theme of the entire application.
  • CSS variables cascade just like normal CSS rules. We will look at an example of this in a moment, but CSS variables behave just like any other CSS property. You could apply a variable globally to your entire application, but then you could overwrite that variable just for one specific <ion-list> (or all of them), or a <p> tag, and so on.

This isn’t going to flip application on its head, but it definitely has its advantages.

How are CSS Variables used in Ionic ?

Now that we have the basic idea down, let’s take a look at how CSS variables might actually look in an Ionic application. First of all, a CSS variable looks like this:

--ion-background-color: #1f1e1e;

which is similar to a SASS variable, which looks like this:

$background-color: #1f1e1e;

In Ionic 3, we would commonly modify the $colors map to change the default styles for attributes like primary and secondary in our applications:

$colors: (
  primary:    #ecf0f1,
  secondary:  #e74c3c,
  danger:     #f53d3d,
  light:      #e74c3c,
  dark:       #222222
);

Now you will be able to use CSS variables to define your theme colours. If we wanted to set the same theme colours in Ionic 4 as the example above, we would do this instead:

:root {
    --ion-color-primary: #ecf0f1;
    --ion-color-secondary: #e74c3c;
    --ion-color-danger: #f53d3d;
    --ion-color-light: #e74c3c;
    --ion-color-dark: #222222;
}

We supply the corresponding CSS variables for each colour inside of the :root selector. The use of :root here is a pseudo selector, and is used to represent the root element of your DOM structure, which is typically <html>. So, don’t let the syntax freak you out, it’s basically the same thing as using:

html {
    --ion-color-primary: #ecf0f1;
    --ion-color-secondary: #e74c3c;
    --ion-color-danger: #f53d3d;
    --ion-color-light: #e74c3c;
    --ion-color-dark: #222222;
}

This means that the variables we supply inside of :root are going to apply across the entire application unless they are overwritten somewhere.

These variables are used in a lot of Ionic’s components, so a lot of your application will change right away by defining these. However, we might also want to use these colours for our own elements. In Ionic 3, with SASS, we could retrieve the values for colours in the $colors map by doing this:

.my-class {
    background-color: map-get($colors, primary);
}

With CSS variables, we would do this instead:

.my-class {
    background-color: var(--ion-color-primary);
}

We aren’t limited to just changing these colour variables. Many of Ionic’s styles are derived from these variables, so we can overwrite those with our own values if we like as well:

:root {
    --ion-item-background-color: #1f1e1e;
    --ion-background-color: #1f1e1e;
}

Adding the variables to the :root selector will apply those changes application wide, but as I mentioned before, CSS variables “cascade” just like other CSS properties. This means that we could also add CSS variables to other selectors:

app-page-settings {
    --ion-background-color: #fff;
    --ion-item-background-color: #fff;
}

In the example above, I have overwritten the variables for --ion-background-color and --ion-item-background-color, this means that anything inside of <app-page-settings> will be affected by these changes, but everything outside of that won’t be. I could then define different variables for something inside of <app-page-settings> to target that and its children specifically. The variables will behave just like normal CSS styles.

Another important aspect of Ionic’s usage of CSS variables is that it allows a way to modify the internal styles of components that are protected by a Shadow DOM. In some cases, the only way to change the styling of an Ionic component will be to modify the CSS Variables/Custom Properties that it exposes. You can see what CSS Variables are available for each component in the documentation for that component. You can also find the CSS Variables being used directly by using the browser DevTools if you know where to look.

Summary

For a lot of people, using CSS variables probably won’t change all that much, but it certainly does add some cool bonuses. There are functional benefits which will make changing application-wide styles dynamically from within your application much more feasible, but it also just adds a lot of niceties to development. It will be convenient to be able to mess with variables right from the debugger, and it’s also easier to see what variables are being used to determine an element’s styles (rather than having to hunt through the Ionic documentation to find the appropriate SASS variable).

Check out my latest videos: