## Using the CSS file format

The syntax of RC and CSS files formats is obviously different. The CSS-like syntax will hopefully be much more familiar to many people, lowering the barrier for custom theming.

Instead of going through the syntax differences one-by-one, we will present a more or less comprehensive example and discuss how it can be translated into CSS:

Example 12. Sample RC code

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    style "default" {
            xthickness = 1
            ythickness = 1

            GtkButton::child-displacement-x = 1
            GtkButton::child-displacement-y = 1
            GtkCheckButton::indicator-size = 14

            bg[NORMAL]        = @bg_color
            bg[PRELIGHT]      = shade (1.02, @bg_color)
            bg[SELECTED]      = @selected_bg_color
            bg[INSENSITIVE]   = @bg_color
            bg[ACTIVE]        = shade (0.9, @bg_color)

            fg[NORMAL]        = @fg_color
            fg[PRELIGHT]      = @fg_color
            fg[SELECTED]      = @selected_fg_color
            fg[INSENSITIVE]   = darker (@bg_color)
            fg[ACTIVE]        = @fg_color

            text[NORMAL]      = @text_color
            text[PRELIGHT]    = @text_color
            text[SELECTED]    = @selected_fg_color
            text[INSENSITIVE] = darker (@bg_color)
            text[ACTIVE]      = @selected_fg_color

            base[NORMAL]      = @base_color
            base[PRELIGHT]    = shade (0.95, @bg_color)
            base[SELECTED]    = @selected_bg_color
            base[INSENSITIVE] = @bg_color
            base[ACTIVE]      = shade (0.9, @selected_bg_color)

            engine "clearlooks" {
                    colorize_scrollbar = TRUE
                    style = CLASSIC
            }
    }

    style "tooltips" {
            xthickness = 4
            ythickness = 4

            bg[NORMAL]        = @tooltip_bg_color
            fg[NORMAL]        = @tooltip_fg_color
    }

    style "button" {
            xthickness = 3
            ythickness = 3

            bg[NORMAL]        = shade (1.04, @bg_color)
            bg[PRELIGHT]      = shade (1.06, @bg_color)
            bg[ACTIVE]        = shade (0.85, @bg_color)
    }

    style "entry" {
            xthickness = 3
            ythickness = 3

            bg[SELECTED] = mix (0.4, @selected_bg_color, @base_color)
            fg[SELECTED] = @text_color

            engine "clearlooks" {
                    focus_color = shade (0.65, @selected_bg_color)
            }
    }

    style "other" {
            bg[NORMAL] = #fff;
    }

    class "GtkWidget" style "default"
    class "GtkEntry" style "entry"
    widget_class "*<GtkButton>" style "button"
    widget "gtk-tooltip*" style "tooltips"
    widget_class "window-name.*.GtkButton" style "other"

would roughly translate to this CSS:

Example 13. CSS translation

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    * {
      padding: 1;
      -GtkButton-child-displacement-x: 1;
      -GtkButton-child-displacement-y: 1;
      -GtkCheckButton-indicator-size: 14;

      background-color: @bg_color;
      color: @fg_color;

      -Clearlooks-colorize-scrollbar: true;
      -Clearlooks-style: classic;
    }

    *:hover {
      background-color: shade (@bg_color, 1.02);
    }

    *:selected {
      background-color: @selected_bg_color;
      color: @selected_fg_color;
    }

    *:insensitive {
      color: shade (@bg_color, 0.7);
    }

    *:active {
      background-color: shade (@bg_color, 0.9);
    }

    .tooltip {
      padding: 4;

      background-color: @tooltip_bg_color;
      color: @tooltip_fg_color;
    }

    .button {
      padding: 3;
      background-color: shade (@bg_color, 1.04);
    }

    .button:hover {
      background-color: shade (@bg_color, 1.06);
    }

    .button:active {
      background-color: shade (@bg_color, 0.85);
    }

    .entry {
      padding: 3;

      background-color: @base_color;
      color: @text_color;
    }

    .entry:selected {
      background-color: mix (@selected_bg_color, @base_color, 0.4);
      -Clearlooks-focus-color: shade (0.65, @selected_bg_color)
    }

    /* The latter selector is an specification of the first,
       since any widget may use the same classes or names */
    #window-name .button,
    GtkWindow#window-name GtkButton.button {
      background-color: #fff;
    }

One notable difference is the reduction from fg/bg/text/base colors to only foreground/background, in exchange the widget is able to render its various elements with different CSS classes, which can be themed independently.

In the same vein, the light, dark and mid color variants that were available in GtkStyle should be replaced by a combination of symbolic colors and custom CSS, where necessary. text_aa should really not be used anywhere, anyway, and the white and black colors that were available in GtkStyle can just be replaced by literal GdkRGBA structs.

Access to colors has also changed a bit. With GtkStyle, the common way to access colors is:

    1
    2
    3
    4
    5
    GdkColor *color1;
    GdkColor color2;

    color1 = &style->bg[GTK_STATE_PRELIGHT];
    gtk_style_lookup_color (style, "focus_color", &color2);

With GtkStyleContext, you generally use GdkRGBA instead of GdkColor and the code looks like this:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    GdkRGBA *color1;
    GdkRGBA  color2;

    gtk_style_context_get (context, GTK_STATE_FLAG_PRELIGHT,
                           "background-color", &color1,
                           NULL);
    gtk_style_context_lookup_color (context, "focus_color", &color2);

    ...

    gdk_rgba_free (color1);

Note that the memory handling here is different: `gtk_style_context_get()` expects the address of a GdkRGBA* and returns a newly allocated struct, `gtk_style_context_lookup_color()` expects the address of an existing struct, and fills it.

It is worth mentioning that the new file format does not support custom keybindings nor stock icon mappings as the RC format did.