CSS-like styling for GTK+

Lately, I’ve been intermitently working on the gtk-style-context branch, which is meant to supersede GtkStyle and get rid of all its limitations in creating contemporary UIs, to name a few:

  • Cairo as a first class citizen: This means elements may be rendered on any surface, not only on X resources.
  • No more widget peeping: There is now a GtkWidgetPath abstraction, which fully defines the widget in a styling point of view.
  • Widget is no longer a plain area: Widgets may define named regions, which can be styled independently.
  • Animation support: Theming engines no longer have to hack their way to animate some UI element, there is built in support for animations on state changes.
  • No more detail string: GtkStyleContext may contain several classes, which can be checked by the theming engine.

As a consequence, the GtkRC parser has been replaced as well by a CSS-like parser, the property names aren’t currently fully following the CSS spec (Selectors do), and there are some semantics that don’t apply, but OTOH there is support for symbolic colors. The format is enough for people into web development to get the gist of it:


@named-color: #01a4f9;

/* Set background on GtkCheckButton
* and other types inheriting from
* it
*/
GtkCheckButton {
  background-color: #14a414;
}

/* Theme buttons inside a table,
* not necessarily a direct child
*/
GtkTable GtkButton {
  foreground-color: #f01df4;
  text-color: #f01df4;
}

/* Theme scale widgets that are
* direct children of a GtkTable
*/
GtkTable > GtkScale {
  foreground-color: #01ab39;
}

/* Widget states may be defined */
GtkButton:active {
  background-color: #f01;
}

/* Generic classes may be used as well */
.button:prelight {
  background-color: #10f;
}

/* any widget with this name will be themed */
*#some-widget-name {
  font-color: #e0a;
}

/* This will apply if both states happen on the
* widget, such as a pressed checkbox button with
* the pointer on it.
*/
GtkButton:active:prelight {
  background-color: shade (#f01, 1.3);
}

/* Set bg color on odd rows */
GtkTreeView row:nth-child(even) {
  background-color: #f00f10;
}

/* Theme first notebook tab differently */
GtkNotebook tab:nth-child(first) {
  background-color: @named-color;
}

/* And paint a bit darker if active */
GtkNotebook tab:nth-child(first):active {
  background-color: shade (@named-color, 0.7);
}

/* Animate checkbutton transitions */
GtkCheckButton:active {
  transition: 200ms ease-in-out;
}

If you compile the gtk-style-context branch and put this into ~/.gtk-2.0.css, you should see something like this:
(Disclaimer: this is the default engine, I know it’s ugly, let’s leave art for artists)

At the moment, widgets have been roughly ported to this new code indirectly through making GtkStyle rely on GtkStyleContext, so they could be a lot more talkative about the elements they render and contain. If you’re a theme engine developer try out the GtkThemingEngine API, this is what theming engines must implement and use in order to render UI elements, constructive feedback is most welcome.

35 Responses to “CSS-like styling for GTK+”

  1. Ignacius says:

    Impresive work. Thank you for all the hard work!

  2. tuXXX says:

    Very nice!

  3. mmonreal says:

    When will this be available in a GTK release?

  4. Stéphane says:

    You rock, thanks!

  5. Miguel de Icaza says:

    Wow, this is incredible!

    This alone will do wonders for the future of Gtk+!

    This has got to be one of the /most/ requested features in Gtk, and having this code is the single most important work that Gtk+ needs to help developers.

    Thanks a lot for the work Carlos!

  6. Amazing. I’m looking forward to play with this on mono.

  7. Jeff Waugh says:

    ZOMGWTFBBQ! You are a legend. :-)

  8. Mathias Hasselmann says:

    The way to go! Rock on!

  9. OMG! Finally! You’re my hero.

  10. oll says:

    Great. I’m looking forward to play with this in vala.

  11. Alex says:

    Might this help GTK+ and Qt theming converge? It would be really nice if my Qt theme could “just work” with my GTK+ applications (i.e. Firefox) and vice versa.

  12. Bob Bobson says:

    Why would you ever want to do this? Doesn’t the theme engine do the rendering of widgets for you? Why would you want a single widget to be a different colour to the rest, which will potentially clash with the theme.

  13. […] Andrea Cimitan: My hero for today by Gnarc on August 23rd, 2010 Carlos Garnacho is definitely my hero for today. […]

  14. Juanjo Marin says:

    Lo has petao :)

  15. Fizzy says:

    Meh. We should be getting rid of gtk styling altogether and concentrating on one, beautiful theme that shouts ‘gtk’ or ‘GNOME to the world’. Not encouraging Joe Web Hacker to add to the thousands of half-assed, half-finished themes we have already.

  16. We’ve been waiting for this. :)

  17. TualatriX says:

    It’s great!

    Thank you!

  18. ikbear says:

    it is amazing!

  19. says:

    Yes yes yes yes yes yes yes.

  20. nona says:

    any chance of using $XDG_CONFIG_HOME for gtk-2.0.css ?

  21. […] para la configuración y personalización de interfaces de usuario con GTK+: el uso de archivos de estilo tipo CSS.GTK+ es un kit de herramientas para la creación de interfaces gráficas de usuario; que además […]

  22. […] Hace unas horas Carlos Garnacho, programador para el Proyecto GNOME, dio a conocer en su blog lo que promete ser un paso gigantesco para la configuración y personalización de interfaces de usuario con GTK+: el uso de archivos de estilo tipo CSS. […]

  23. […] Hace unas horas Carlos Garnacho, programador para el Proyecto GNOME, dio a conocer en su blog lo que promete ser un paso gigantesco para la configuración y personalización de interfaces de usuario con GTK+: el uso de archivos de estilo tipo CSS. […]

  24. carlosg says:

    Thanks all for the positive comments :)

    @mmonreal: I’m aiming to have this ready for GTK+ 3.0

    @alex: Maybe not converge, but nothing would stop Qt and others to mimic GTK+ appearance without resorting to hacks such as keeping a widget pointer, AFAICS QGtkStyle could do wonders with this.

    @nona: That is certainly a possibility, I’ll keep it in mind, thanks :)

    @bob: well, it is up for themes to do something sensible with this, in the same way they ship a gtkrc file, they’d need a css file. And users have been always able to mess things up through ~/.gtkrc-2.0 :)

    @Fizzy: GTK+ works on different platforms, where it should fit in just fine, and there is also a need for a accessible themes, I’m afraid you can’t get rid of theming like that

  25. Thura says:

    Wow, awesome … can’t wait to play with it ;)

  26. Props for named colors. Having CSS stylesheets is great for suddenly opening doors to hundreds of designers familiar with it. I also like the cascading – defining basic style with a generic selector and then diving in for specific widget. What I expect from the theming to provide for me:

    – padding, border, margin per widget
    – linear gradients for strokes (border) and fill, allowing RGBA colors. Radial gradients if I can have Christmas.
    – named colors [yay!]. Some color functions would be sweet — gtk’s shade, invert, saturate, complement
    – rounded corners / border-radius
    – specific widgets like a checkbox I don’t really want to paint manually so some svg>cairo convertor or just having SVG/images not be slow would be nice.
    – if images aren’t slow, some more complex widgets might benefit from 9slicing ala border-image in css3 http://www.w3.org/TR/css3-background/#border-images

  27. Wow! it’s awesome!

  28. Fcastanedo says:

    Carlos, you Rock! :). Its always nice to see your stuff, Fede.

  29. […] interfaces gráficas en lo referente a GTK+. Si quereis saber más, no os olvideis de pasar por el blog de Carlos Garnacho, desarrollador de GNOME que ha dado a conocer dicha […]

  30. eboyjr says:

    This is great! :)

    I would suggest supporting many of the CSS3 features (like border-image as Jakub was saying).

    And I think the property names should really follow the CSS spec e.g. ‘font-color’ and ‘foreground-color’ should be changed to ‘color’.

    Also a really really nice feature to have is the ‘inherit’ property and have a default style-sheet (like a user-agent stylesheet) that sets inherit properties on certain properties, e.g. color, font-family, etc (the ones that CSS currently has)

    Anyway this is really really great and I like it a lot!

  31. luc says:

    WOW. Congrats Carlos!