Gtk application CSS based on light/dark theme

Is there a way to have the CSS class change on whether the user has a light or dark theme?

I have GtkLabel with the font in darkblue that looks good on a light theme but is hard to read on a dark theme. When the user has chosen a dark theme I want to use ‘lightblue’ instead.

Google suggests the following but it is not working for me..

.fontblue {
     color: darkblue;
}

@media (prefers-color-scheme: dark) {
    .fontblue {
        color: lightblue;
    }
}

If you’re using GTK4 by itself, then you will need to set the appropriate properties on the GtkCssProvider instance you’re using to load your CSS fragment, because GTK won’t do that for you. In this specific case, you want to set GtkCssProvider:prefers-color-scheme. You will need to deal with the detection of the dark color scheme on your OS; for instance, you can query the Settings desktop portal.

I’m using the following to detect if we are in the dark …

    // Detect if we are using a dark theme
    GSettings *settings = g_settings_new("org.gnome.desktop.interface");
    gchar *color_scheme = g_settings_get_string(settings, "color-scheme");
    gboolean bDarkTheme = (g_strcmp0(color_scheme, "prefer-dark") == 0);
    
    g_free(color_scheme);
    g_object_unref(settings);

which works (on Wayland at least .. and I presume on X11 since its gnome specific).

I’m loading the css from a resource with gtk_css_provider_load_from_resource

Using the code below seems to do the trick.

thanks!

Michael

    GValue value = G_VALUE_INIT;
    g_value_init(&value, G_TYPE_INT);
    g_value_set_int(&value, bDarkTheme 
        ? GTK_INTERFACE_COLOR_SCHEME_DARK : GTK_INTERFACE_COLOR_SCHEME_LIGHT);
    g_object_set_property( G_OBJECT( cssProvider ), "prefers-color-scheme", &value);
    g_value_unset(&value);

This will work in GNOME only, of course; if you want it to work elsewhere, then you should use the Settings portal, for instance through libportal’s XdpSettings API.

This is kind of overblown; you can use:

GtkInterfaceColorScheme color_scheme = pGlobal->flags.bDarkTheme
  ? GTK_INTERFACE_COLOR_SCHEME_DARK
  : GTK_INTERFACE_COLOR_SCHEME_LIGHT;
g_object_set (cssProvider,
              "prefers-color-scheme", color_scheme,
              NULL);
1 Like

Much nicer than my “dog’s breakfast” !