Creating a theme using SASS

Vaadin 7 comes with built in support for Sass, which can be thought of as a preprocessor for CSS. From the Sass homepage:

Sass makes CSS fun again. Sass is an extension of CSS3, adding nested rules, variables, mixins, selector inheritance, and more.

Sass looks like CSS with some added features, and is compiled into CSS before being sent to the browser. The compilation is either done beforehand, or (during development) on-the-fly by the servlet.

In Vaadin 7 you can make use of Sass in any of your CSS, and as usual there are more than one way to arrange this. The recommended way if you do not have a specific reason not to do so, is to compile your theme into one CSS file (that is: without any CSS @include), but we’ll start with the getting-your-feet-wet approach that looks exactly as before.It’s worth noting that you can continue to use CSS without Sass just as before, if you prefer.

Getting your feet wet

In Vaadin 7 you set the theme in use by specifying the @Theme annotation on your UI, e.g @Theme(“themename”). Ignoring Sass for a second, you would then create a mytheme/styles.css that typically @import the Reindeer theme (in case you forgot, your theme should be located in WebContent/VAADIN/themes/<themename>/styles.css). You can start using Sass with this approach, by renaming your styles.css to styles.scss and importing legacy-styles.css instead of styles.css - the resulting CSS will be exactly as the same as before, BUT now you’re free to use Sass in your theme:

@import url(../reindeer/legacy-styles.css);
$color : green;
.v-button-caption {
  color:  $color;
}

Here we just define a Sass variable to use as color for button captions.

NOTE that this way (using legacy-styles) you still lose one important new feature: you can’t have multiple themes on the same page when using the legacy-styles.css -approach. To gain this feature, which is crucial if you intend to run multiple applications with different themes embedded in the same page (e.g portals), you must use Sass.

Compiling

Provided you’re in development mode (not production), the scss will automatically be translated into CSS. You can also compile the scss manually (and MUST do so for production). To do this you should run com.vaadin.sass.SassCompiler with the Vaadin jars on the classpath and give it your scss file and output file as arguments. If you have the jars readily available, you could do something like this in the command line:

> java -cp '../../../WEB-INF/lib/*' com.vaadin.sass.SassCompiler styles.scss styles.css

Another way would be to save the auto-compiled styles.css from the browser.

Support has been added to the Eclipse plugin through the Compile Vaadin Theme button .

NOTE that if you’re using Ivy (the default if you’re using the Eclipse plugin), you must make sure to get the appropriate dependencies on your classpath some other way (since they are not present in WEB-INF/lib). In Eclipse, use the Run -dialog to inherit the classpath from your project.

You’ll notice that the resulting theme still uses @import to 'extend' the Reindeer theme:

@import url(../reindeer/legacy-styles.css);

This approach is an easy way to get started with Sass, but will cause two requests (one for our theme, one for Reindeer). Let’s have a look at the recommended approach next.

Going deeper

Instead of using CSS @import to base your application theme on, you can (and probably should) use Sass @import to make a monolithic theme (one CSS file, one request when using the application). Just @import reindeer.scss, and @include it:

// mytheme.scss
@import "../reindeer/reindeer.scss";

.mytheme {
   @include reindeer;

   $color : yellow;
   .v-button-caption {
    color:  $color;
   }
}

This produces a styles.css that contains all the styles for Reindeer as well as your custom styles (note that this makes your final CSS quite big to scroll trough, so you might not want to do this when just learning the Sass syntax). There is no @import in the compiled CSS, so it will not cause additional requests. Additionally, due to the way Vaadin Sass is structured, this opens up for many possibilities to customize, mix-and-match themes, and leave unused stuff out.

One important thing to notice, is that we wrapped everything in .themename {}, in this case .mytheme {}. This is the magic sauce that makes it possible to have multiple themes on one page. It is crucial that the name matches your themename, or your styles will not be applied.

Some of the nice features you get with Sass include variables, selector nesting, mixins (optionally with paramaters), selector inheritance. For more information of what you can do with Sass, you should refer to the official documentation at http://sass-lang.com

Please note that the Vaadin Sass compiler only supports the “SCSS”, which is the “new main syntax” (the original Sass also supports another, older syntax).The Vaadin version aims to be completely compatible, though initially there will be some limitations (and actually some added functionality). Please let us know if you find something is not working as expected.

In Vaadin 7, all Vaadin core themes are using Sass. The reindeer/styles.css we included first, is the compiled Reindeer theme, including the stuff from the Base theme that Reindeer extends. The Sass for the Reindeer theme is in reindeer/reindeer.scss, and contains one big mixin that will include the whole theme, unless you specifically tell it to leave out some parts. The themes are further divided into smaller parts, that can be left out, or separately included and renamed - providing a powerful way to customize and mix-and-match themes.

It is recommended that you go ahead an divide your own theme into at least two files as well: styles.scss and themename.scss (where 'themename' is the name of your theme). This is will make your theme extendable, and also has the nice benefit that file you usually edit is uniquely named (themename.scss) instead of a generic styles.scss that you might have many of.

For a theme named 'mytheme', this would look as follows:

mytheme/styles.scss:

@import "mytheme.scss";
.mytheme {
   @include mytheme;
}

mytheme/mytheme.scss:

@import "../reindeer/reindeer.scss";

@mixin mytheme {

   // your styles go here

   @include reindeer;
}

This is the exact structure Vaadin core themes are using, and the way the Eclipse plugin will set things up for you (not yet in beta 10).

Of course, you’re still free to arrange your theme in another way if you prefer.

Upcoming tutorials will address specific use-cases!