Styling Xamarin.Forms with CSS

The latest Xamarin.Forms nightly build includes support for CSS. For a comprehensive list of what is presently supported, check Stephane’s pull request. With a little downtime this holiday season, I was excited to put it into practice and get my head around it.

Before I dive in, it’s important context to understand that the Xamarin.Forms CSS parser is a mapping to the existing styling that we already use in XAML or C#. At its most basic, it’s just another way to express styling. As it matures, I think we’ll find it to be uniquely flexible.

First Impression

  • My XAML just went on a diet. By pulling my style-able properties into CSS files, the XAML got a lot thinner and legible.

  • XAML is still more powerful. You cannot style everything in CSS that you can in XAML. A prime example is the NavigationBar.

  • With the notable exception of the caret prefix, it is valid CSS. That means I can share CSS from and to web projects and my 20+ years of CSS experience is mostly applicable.

First App - Basic CSS

I broke my garage door opener in early December, and I broke it really well. Pieces flew everywhere. It was glorious.

To replace it, I purchased a Chamberlain wifi enabled opener for which I could build an app using an undocumented API. It’s (so far) a great garage door opener, and a pretty horrible API.

But enough about that. I took the opportunity to style it with CSS. Here’s the full source for my app, OpenSesame.

No time was wasted in the naming of this app.

I think the code here’s pretty self-explanatory, so I’ll just lay it out. In the Main.xaml I load my stylesheet which will be parsed at runtime. Is that slower than XAML styles with XAMLC enabled? Probably a little. TDB.

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

These are my styles, with a little explanation.

In order to style the MainView which extends ContentPage I need to style elements with that base class. This is indicated with the caret (^). This is not valid CSS and will not pass a linter. More on that later.

^ContentPage {
    background-color: #554a35;
    padding: 20;

Next, I can style controls by type. Capitalization doesn’t matter, and I should probably hate myself for mixing it up.

label { color: #ffc363; }

button {
    background-color: #e10032;
    color: white;

Entry { height: 40; }

And lastly in my example I can style using specific classes, and I can combine these as well.

.SecondaryButton {
    background-color: transparent;
    color: white;

So that’s simple enough. There are some gotchas and things I was left wanting, which I’ll leave for the end.

Second App - Supercharged with Sass

Now that Xamarin.Forms can make use of CSS for styling, we can also start to benefit from great productivity solutions like Sass and Less preprocessors. If you’ve done any web development in the past several years, you’ve at least tried one of these. From a productivity standpoint they can be quite amazing.

Key benefits:

  • variables
  • composition of style files with @import
  • block reuse @include
  • inheritance with @extend
  • mix-ins
  • so much more…

If you’re new to Sass, I recommend doing a little research. I used Compass extensively on ThisLife, now Shutterfly Photos, and it sold me. Every web project since then I’ve used Sass. The productivity benefits are fantastic.

To explore this aspect, I chose my ongoing and never-ending project, HowYouSay. You can see my playground of code on GitHub.

Settings Up Sass While Visual Studio 2017 and VS Code have more mature Sass support, and I believe the former even has a built in compiler, the Visual Studio for Mac support is catching up. You can add and edit Sass (scss) files and get some decent code completion.

However, I needed a solution to process my Sass files into CSS in order for Xamarin.Forms to parse. I chose to setup a nodejs project and use gulp with gulp-sass.

This is what I did.

  1. Added latest Nightly build of Xamarin.Forms ( to my solution.

  2. Added a folder to my Xamarin.Forms .NET Standard 2.0 project called /Styles and a subfolder /sass to keep my Sass source.

  3. Initialized a node project in the /sass directory > node init

  4. Install gulp, gulp-sass, and gulp-string-replace npm install gulp gulp-sass gulp-string-replace

  5. Add gulpfile.js with the contents below. var gulp = require(‘gulp’); var sass = require(‘gulp-sass’); var replace = require(‘gulp-string-replace’);

    gulp.task(‘sass’, function() { gulp.src(‘*.scss’) .pipe(sass()) .pipe(replace(/\^/g, ‘^’)) .pipe(gulp.dest(‘../’)) });

    gulp.task(‘default’, [‘sass’], function() {‘*.scss’, [‘sass’]); })

  6. Add a pre-build command to the project in VS Mac to make sure I get the latest changes.

Alternatively, you can run the task, but in Visual Studio for Mac you don’t have good visibility to see it running. VS Code is nicer for this right now.

Styling with Sass

So far, I styled most of this app using this pattern. There are a few things to be aware of.

  1. Adding an scss file is easy in Visual Studio for Mac, but the gulp generated CSS file must be manually added to the project. I right-click the Solution folder and choose Display Options > Show All Files. Then I can refresh the Styles folder, right-click to include those files, and set the Build setting to EmbeddedResource.

2. The Sass linter with choke on the caret symbol used in this custom way. Perhaps this will change in the future. I could not find a way to tell the linter to ignore it, or to create a custom rule to account for it. So, instead I chose to escape it, and added a post-process gulp task to replace the escape character. This is what you see here in the gulp file, and in my Sass file below.

.pipe(replace(/\\\^/g, '^'))

This is my HomeView.scss. I’ve imported shared color variables. I started another shared variable file for units as well. Note my use of @extend. Pretty nice.

@import "colors";

\^ContentPage {
    background-color: $blue;

.MainTab {
    border-color: transparent;
    background-color: transparent;
    color: $white;
    border-width: 0;

.MainTabSelected {
    @extend .MainTab;
    color: $teal;

.SelectedIndicator {
    height: 3;
    background-color: $orange;

ListView {
    background-color: $blue;

.AddButton {
    background-color: transparent;
    width: 60;
    height: 60;
    border: 0;

Parting Thoughts

I’m really inspired by this. I’ve gotten a taste for the styling productivity I had in previous projects, and I’m already nagging Stephane about adding media queries and supporting binding on StyleClass.

I’m a fan of lining up my CSS with my Views to optimize my style payload for only what I need, while still sharing with the rest of my project styles.

As I said at the top, XAML is still more feature rich. Much, if not all, of what I did here with Sass+CSS can be done today with XAML and C#.

Something to consider are all the 3rd party design tools that today have CSS support. Adobe’s suite of products, and others such as Sketch and Zeplin provide Sass and/or CSS output that may be brought directly into your applications.

When combining productivity boosts like this with ever improving IDE support, continued improvement to Xamarin.Forms stability and performance, and an amazing community of open source contributors, I cannot help but be very optimistic about what 2018 has in store for us. It’s enough to make you shout Ooui!

Categories: XamarinPermalink