Getting started with CSS (GSS) in GWT

GWT can be hard to tackle at first, especially if your experience is entirely in front-end web development. You may be an HTML and CSS ninja, but not much of a Java wizard. This tutorial introduces how style sheets are used in GWT. I will not explain how to create a new GWT project, and will assume that you have an application you can run. That will let us focus on style sheets in GWT.

Once completed, don’t forget to have a look at the second part : Managing your CSS (GSS) files with variables and a theme.

From the beginning

If there is no style sheet inside of your application, or if you want a rough understanding of how it works, here’s a small step-by-step guide to add your default CSS file. Note that your application might be using a different folder structure than my example program, and that you will have to replace com/company/project to match your project.

The CSS file

We will create our initial CSS file into src/main/resources/com/company/project/client/resources/css and will name it style.gss. That’s right, .gss and not .css, as GSS files are like CSS files, but with more power. And we always want more power, don’t we?

We should add at least one line in our file, so we know that it’s working. Let’s use :

body { background-color: pink; }

At this point, it should not be working yet.

The Resource file

We then need to create the resource file that will be the bridge between your GSS file and your Java classes. This is because GWT will obfuscate class names on compliation, so this file will handle the links between the obfuscated names and classes inside of your GSS file.

Let’s create AppResources.java inside of src/main/java/com/company/project/client/resources

The code inside of it goes like this:

The Resource Loader file

We now need to setup the loader file to, well, to load everything inside the application.

Once again inside src/main/java/com/company/project/client/resources, create a file named ResourceLoader.java, containing :

The ensureInjected() is the important part here, as it will inject your CSS into the DOM.

Don’t forget to bind this file inside your ClientModule, probably located at src/main/java/com/company/project/client/gin/ClientModule.java

Activate GSS

GSS has been included in GWT since version 2.7, but is not enabled by default. To enable it, you need to add one line of code inside your GWT module. Mine is located at src/main/java/com/company/project/AppModule.gwt.xml and looks like this:

Voilà! If things went well, your application should build and run, loading your style.gss file in the process. Don’t worry if it fails, as you might have your application structured in a different way than shown in this tutorial. If you take time to read compile errors, you should manage to make it right. If you don’t, but have a backend dev near you, it’s always good to ask for help.

Using classes

One of the most confusing thing at first while working on GSS files in GWT is that you will need to declare your classes inside of your resource file to be able to access them.

Let’s add some classes into our style.gss file :

We then need to adapt the resource file accordingly:

Congratulations! You can now use you classes inside your views (you know, the files ending with .ui.xml) and even with your Java files.

We will first need a view. The file that we will be working on, aka ApplicationView.ui.xml, looks like this:

In order to use our classes, we will need to import the desired resource into the view :

 

We can now call the required classes using resources.style.name_of_my_class

In the precedent view, the final code would be :

You should know that Java uses the CamelCase naming convention, and that hyphenated class names using “-" will not compile. In order to make it work, you will need to use @ClassName inside of your CssResource:

Structure

It’s good to split your CSS into multiple files. It will be easier to maintain and understand, and will help you think in blocks and structure your classes accordingly; rather than having only one CSS file that does everything, but where you are not sure what that everything is.

A structure that I like, (but feel free to adapt it), is this one:

/resources
    /css
        /elements               // -> Elements that you reuse here and there
            section.gss
            form.gss
            anyElement.gss
        /pages                  // -> Pages related style
            login.gss
            contact.gss
        style.gss               // -> Your main style

Working with multiple GSS files

While working with multiple GSS files, you have two options: you can create a resource file for that GSS and include it only in views that will need it, or you can declare multiple GSS files into the same resource.

One resource file per GSS

It might sound easier to stack everything into the same resource file, but as with CSS files, it’s always better to break your code in blocks. If you have a contact.gss file that will only be used inside of your contact.ui.xml, you should create a dedicated resource for that. And I’d guess that you would also need your default style inside that view.

Multiple GSS files in the same resource

Let’s say you have a small application with only 3 pages: homepage, services and contact. For each page, you created a corresponding GSS file (homepage.gss, services.gss and contact.gss).

You could create one resource file for each, like in the previous example. You could also create one resource file to rule them all, named PageResources.java.

You will need to update your ResourceLoader.java accordingly:

Now, you can include the PageResources in each of your pages. It will give you access to every interfaces in it (homepage, services, contact).

Using images

If you want to use images inside of your GSS file, you will need to declare them as an ImageResource. Your image will need to be inside your resources folder, and like your GSS files, it’s always a good thing to create a proper folder structure in order to maintain control.

Conclusion

CSS with GWT is not an easy task at first, but after mastering the basics, you can regain your status as a front end ninja in GWT-land. Find the workflow that suits your need, structure your files and don’t forget to have fun!

In my next post, I will teach you how to leverage the real power behind GSS and simplify your life, using variables and a theme file. Stay tuned!

 

  • slavap

    How to insert code blocks in comments? I’m stuck 🙁

    • Jason Lemay

      To publish code (no spaces after [ and bedore ]) : [sourcecode][ sourcecode language="java" ] your code [ /sourcecode ][/sourcecode]

    • Jason Lemay

      Markdown has been activated for comments. It should be working for you now 🙂

  • slavap

    Instead of using ui:with you’d better use ui:import in UiBinder templates.
    [sourcecode language=”java”]
    public interface AppResources extends ClientBundle {

    public static final AppResources r = GWT.create(AppResources.class);

    interface Style extends CssResource {
    String my_first_class();
    String my_second_class();
    }

    @Source("css/style.gss")
    Style style();
    }
    [/sourcecode]

    Then in ui.xml you can get more efficient and shorter code:
    [sourcecode language=”xml”]
    <ui:import field="com.company.project.client.resources.AppResources.r" />

    <p class="{r.style.my_first_class}">This is my first paragraph.</p>
    <p class="{r.style.my_second_class}">This is my second paragraph.</p>
    [/sourcecode]

  • Ian

    Hi Jason,

    I have been using the gwt-maven-plugin to generate my java interfaces from my .css files.
    Your ‘multiple gss files’ approach does not make use of that automation, and so the clientbundle files has to be maintained manually.

    As I write this email, I have just realised that Codehaus has closed down. Do you know what the implications of this will be for us GWT maven developers ?

    When GWT 2.8 or 3.0 arrive, who will update the maven plugin ?

    Ian

    • jdramaix

      The plugin uses the class from the sdk in order to generate the resource interface. This class will be updated in GWT 2.8 in order to support GSS

  • Dani V.T.

    Great tutorial, straight to the point and very helpful !

    P.S: I think there is a typo in the file ContactResources.java snippets. The interface declared there has a wrong name as AppResources.

    • Jason Lemay

      There was a typo indeed, it should be fixed now, thanks 🙂

  • Ankit Gajiwala

    Hi…! How can I import gss in my current html page from external location? Currently, I am using the link tag of html as following:

    However, above code is not working and it is not applying the style to my page.

    Am I doing something wrong?

    • Jason Lemay

      Hi Ankit,

      GSS file are not meant to be parsed by the browser. They are like LESS or SASS file that need to be converted into CSS file. In the process of converting GSS file into CSS file, GWT will obfuscate class names, so you probably can’t use that file outside of the native project. Best solution would be to copy this GSS file into your new project, or manually convert the GSS file into a compatible CSS file.

      Hope that helped!

  • Zdeněk Braun

    I have @provide ‘colors’; in colors.gss, I have @require “colors”; in style.gss. I am getting error “style.gss[line: 1 column: 1]: Missing provide for: colors”. Why when I provide it? I even have it in “@Source({ “css/colors.gss”, “css/style.gss” })
    Style style();” on a first place.

    • Jason Lemay

      Hi Zdeněk! For what I see, I think it should work. One of the common mistake is in the declaration ordre but yours is good (css/colors.gss before css/style.gss). Have you solved it?

      • Zdeněk Braun

        Yes, sorry, my bad… I was using UIBinder and using with path to the main gss file… See my question and answer here: http://stackoverflow.com/questions/37749048/gwt-gss-provide-and-require?noredirect=1#comment62975997_37749048 if u want.

        • Howard Yeh

          I ended up having to do this to fix all compilation issues after upgrading to gwt 2.8
          @Source({“com/arcbees/gsss/mixin/client/mixins.gss”,
          “com/arcbees/chosen/client/resources/icons/icons.gss”,
          “com/arcbees/chosen/client/resources/css/colors.gss”,
          “com/arcbees/chosen/client/resources/css/chosen.gss”,
          “css/chosenOverride.gss”})