My previous article showed you how to use CSS inside your GWT application. Today, we will introduce the concept of variables, and show you how to manage them effectively using theme files.
- Naming Conventions
One of the best examples of variable use in CSS is probably color management. If your application has a default blue color, let’s say
#2054e8, and it is used in multiple places, you will need to remember this particular color code every time you specify that color. Then if you decide to make your default color the lovely
#f31ae5 shade of pink, you will need to do a find and replace across your whole project, and hope that everything went well.
All these hassles can be avoided if you use variables for your colors, so let’s do that!
Creating the Colors file
We will create
We will discuss variable naming conventions later. Right now, you only need to understand that we can define a variable, like
C_PRIMARY, and assign it a value, such as our initial shade of blue
The main purpose of this file is to contain all color values in the same place. It will then be easy to replace them later, and create different themes for our app.
Creating the associated GSS file
This is where we start to feel the real power of GSS over regular CSS files. After compilation, GSS files output basic CSS, transforming variables into the values associated with them.
In order to easily use our variables, we need to define them in a file. We will name that file
colors.gss and put it into
We define variable names, and point them to the associated variables inside
The most important part is the very first line:
We are providing this file with a name that we will be able to import later on, making the variables defined in this file accessible in other contexts.
Binding it with your default resources style file
Before we can use this file, we need to supply it to our style’s resource file. My default style file is named
style.gss and it uses the
AppResources.java resource file, located in
You can probably guess what you’ll find in this file:
We can see that we are using
style() with the file located at
css/style.gss. We need to add the
@Source, so it’s accessible. Instead of a string, we need to pass an array of strings, pointing to the desired files.
Note that we need to declare
style.gss will try to load the
colors.gss file, but it will not yet be defined, causing an error.
Using variables inside of the style file
Remember when we defined
@provide 'colors'? It is now required inside
style.gss. Once that’s done, you will have access to your variables!
You can define variables for a lot of things beside colors, like sizes and fonts. You could decide to create a variables.gss file and add all your variables there, but this can pose a problem as your application grows. I prefer to structure my files by what they do, giving each set of variables their own file:
// src/main/java/com/company/project/client/resources/variables -> Colors.java -> Fonts.java -> Sizes.java // src/main/resources/com/company/project/client/resources/variables -> colors.gss -> fonts.gss -> sizes.gss
This way, if you only need to use Colors inside of a specific style sheet, you can import them alone. Variable types become more modular.
As variables are not prefixed with any symbols, it helps to write them in uppercase. That way it’s easy to spot them in your CSS.
I also like to prefix them with a single letter that represents the type of variable that it is.
- Colors.java -> C_VARIABLE_NAME (C_PRIMARY, C_BACKGROUND, C_TEXT ...) - Fonts.java -> F_VARIABLE_NAME (F_PRIMARY, F_SECONDARY_BOLD ...) - Sizes.java -> S_VARIABLE_NAME (S_SECTION_PADDING, S_LINE_HEIGHT ...)
Give your variables meaningful names, something that you will be able to remember and understand upon reading. Describe the purpose of the variable, not its value.
F_PRIMARY is the primary font used inside the app, the most common one that will be almost everywhere. I find the use of primary / secondary easy to remember. It has a strong meaning, and it’s about what the variable is used for, and not about the value held by the variable. A bad example would be
F_ARIAL for the same variable with the same purpose. It’s bad because if, in the middle of the project, you decide to change the main font from Arial to Helvetica, you will need to refactor the name of your variable. This is what we are trying to avoid.
C_RED for an error message color, go for
C_ERROR. Or even better :
C_STATE_ERROR. You will be able to manage your state colors easily, like
C_STATE_DEFAULT without worrying about the color it is.
If you create different variable files, you gain the ability to only load the ones you want. This is both good and bad. If you need several variable types, you have to specify each one of them inside of your resource loader, and then require them in your GSS file. This can quickly become annoying, and it makes your code harder to maintain.
As you can see, if you have multiple GSS files, you need to include required variables inside each of those files. And if you need to add another variable set, or remove one, you will need to go inside each of your Resource and GSS files and adapt them accordingly. And that sucks.
Faced with the above problem, you might think going back to having just one
Variables.java file and a
variables.gss file is not a bad idea after all. But we can have our cake and eat it too. We can keep the separation in our Java files and have only one GSS to rule them all. This way, variable files will remain modular, and yet we will still have only one file to require in each GSS file that need to access variables. If we need to change the structure, like adding a new subset of variables, we will only need to update one file, and that’s all!
I call this super GSS file
theme.gss because it will be used to produce different themes, but you could name it
variables.gss and it would still be totally accurate.
With this new method, things are now easier to maintain:
As the constants’ values are stocked in Java files, these constants can be modified easily. With this technique, it is now super easy to create different themes that can be user-based or changed at compile time.
Using a theme file, my structure now looks like this:
src/main/java/com/company/project/client/resources/ -> elements/ -> pages/ -> theme/ -> Colors.java -> Fonts.java -> Sizes.java -> AppResources.java -> ResourcesLoader.java src/main/resources/com/company/project/client/resources/css -> elements/ -> pages/ -> style.gss -> theme.gss
A variable will output the string of text inside of it into your CSS. Sometimes, you will need a variable to output more then one set of properties. You can do so this way:
Can you spot the trick in
F_PRIMARY_BOLD? The variable is defining the font-family, closed with the semicolon
;, then define the font-weight, without a closing semicolon
; because the closure will be handled in the CSS.
You now understand the true power of variables. When used with a theme file, the management of your application becomes a breeze. Things can be made even easier, using a tool to manage the generation of your theme and the associated files. But that, my friends, is a topic for another blog post.