Copper: an experiment with CSS

CopperFurther to our previous discussion of CSS, Thomas spent a few hours on sketching out a possible design for a CSS-based theme format, and on representing Daniel Borgmann‘s Human theme using it. This is an experiment, all very blue-sky and unofficial, and is quite likely never to lead anywhere.

The first question to resolve is how the interplay of element names, classes, and identifiers applies to us. For example, when styling the close button, is it:

  • a button with id=”close”, or
  • a box with class=”button” and id=”close”, or
  • a close with no class or id attributes?

For simplicity, we went with the last option.  We represent the decorations of a window frame using a set of unique element names arranged into a particular hierarchy.  Almost every element is a simple box; the exception is title which is textual.

We use libccss to parse the theme and also to apply certain of the box styles; this means that this experiment is drawn using Cairo.  (It would have been possible but more complicated to use nbtk for styling, which would have meant this experiment used Clutter.  This is more probably what a final working result would be like.  An attempt was made to use nbtk but some of the more complicated styling options appeared to be currently unsupported.)

libccss supported background images and reasonably complex border drawing.  There were two things we needed which it did not (yet) support, so we had to kludge those in:

  • text styling, for the title; we only bothered to implement justification.  Our approach here is to use a simple text label for the title and to style it, rather than using explicit vector graphics as in v2.  Effects like Human‘s shadowing would be implemented by something like CSS3’s text-shadow.  More complicated arrangements like Atlanta‘s centred icons would be impossible.
  • the complete CSS box model; only borders were supported.  We made a half-hearted attempt to support margin, and did not even touch padding.  However, in so doing, we made…

A useful discovery: In doing this it became clear that there are two possible ways for a file format to describe vector graphics.  Either the position of everything can be represented using arithmetic expressions, which is how the current Metacity theme format works, or it can use a hierarchical box model, as HTML and CSS do.  One of our stated aims for v3 is ease of editing, and the box model appears to be a better fit for humans to understand in a drag-and-drop editor (as seen, for example, in Inkscape).  Therefore, if we do not adopt SVG or CSS for v3, it may be worthwhile to look into box-based layout models even in a custom format.

Here’s one draft of the CSS for Human, and the results of processing it with this hacky and experimental code are shown on the right (with the real thing around it for comparison). Example of CSS-based approximation to the Human theme

Problems and challenges:

  • New properties. We are certainly going to need to invent properties which are unheard of in real CSS. (For example, corners will need to indicate the degree of rounding.) These properties should probably be marked in some way. Mozilla marks its new properties with a leading -moz; perhaps we should do something similar.
  • Dublin Core metadata. This could be implemented using custom properties on the toplevel “theme” element, representing the author, licence, and so on.
  • Named colours (especially those which refer to the GTK theme).  libccss does not allow new colour names to be defined; perhaps we should ask for this.  On the other hand, it does allow new callback functions to be created, so that you can write color: gtk("bg-selected") or something.  This allows us to get the same effect at least within the CSS.  However…
  • Pixmaps.  This system is well-suited to defining pixmap themes, which are at least fast, easy to understand, and simple to manipulate.  However, they are generally discouraged because they scale badly and don’t recolour well when the GTK colours change.  There are two possible workarounds:
    • Introduce custom properties to scale and colourise the pixmaps as appropriate.  v2 is already capable of pixmap colourisation (it’s used quite heavily in Crux, since that is a pixmap theme, but rarely elsewhere).
    • Use SVG images instead.  This immediately brings up the problem of how to style these images: we could of course use this very CSS to style them, but then our custom callback functions to get GTK colours would still need to be honoured somehow.


  • CSS has possibilities as a window border format: it is a standard and well-understood format and there are plenty of tools around to edit and parse it. However, it is certainly not as powerful as v2 and probably cannot be.  That may not be a problem, as we said before.
  • As somebody mentioned earlier, research is needed to discover which features of v2 are commonly used, and therefore necessary in any possible v3.  We need to make a big collection of themes and score each feature with how heavily it is used.
  • Box-based layout is simpler for humans to edit (and perhaps to understand in general) than expression-based layout.

Photo © rogdorf, cc-by-nc-sa.

Published by

Thomas Thurman

Mostly themes, triaging, and patch review.

11 thoughts on “Copper: an experiment with CSS”

  1. I’d love to see the theme format switch to CSS. With the CSS v3 draft, it has become a candidate for versatile layouting (e.g. no need for “-moz-border-radius” … rounded borders are RIGHT THERE!). Especially with all the css editing tools out there, this might really ease the creation of themes (just my 2 cents, as one who never liked the old format)

  2. When parsing those CSS files, there should be some available constants (I do not know how to implement this, but it has been discussed for inclusion in CSS3; ).

    Some constants should be used for standard colors; but other one used for file names. For example, the application icon should be stored in a variable. so that specifying it as some background, or pixmap border is possible (and then, you may implement the Atlanta theme).

    Also, border rounding is defined in CSS3, and supported by modern browsers through extensions (ex: -moz-border radius)

  3. I think the css format is a great idea.

    Just some thoughts and suggestions:
    – Consider the border-image rule [1]
    – And webkit gradients too [2]
    – I think it makes more sense edges as the padding or/and the border of the window instead being boxes by themselves, but this would be a little limiting.
    – I agree with the others, border-radius is there, so I think is the same as the previous point, it is necessary that edges being represented as boxes?


  4. @Jorge:

    You’re entirely right: having explicit topleft, topright, etc., boxes was a mistake. If I do more work on this I’ll just have the frame element and allow you to set border-images on it to get the same results far more simply.

  5. One (not so) crazy idea could be the use of WebKit’s WebView as the drawing area. This way the theme could just be a standard HTML file with its CSS companion. And why not some JS for some graphical logic.
    The benefits are numerous : standard, lots of authoring tools, very capable graphical system (ex : see css transformation/transition recent work) etc…

    The challenge is to plumb such a ui to the GObject/native code. this could be achieved using Seed to expose the GObjects in the webview’s javascript context or using the Webkit DOM bindings, exposing divs and stuff to the native word (see webkit bug #16401).
    This approach could even be used for applications ui ala webos or chrome os :)

Leave a Reply

Your email address will not be published. Required fields are marked *

Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported.