GTK 3.0 style stack pages with CSS

, ,

I am working on a GTK application using C. I’ve split the app into multiple Stack pages. Now I want to style them accordingly. I would like to assign one CSS file to one Stack page but using one single CSS would also do the job. My biggest problem is that I can’t figure out how to style individually Widgets in CSS.

main.c

    int main(int argc, char **argv){
      
          gtk_init (&argc, &argv);
          GtkWidget *window;
          window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
          gtk_window_set_default_size(GTK_WINDOW(window), 280,800);
      
          GtkWidget *stack = gtk_stack_new();
          gtk_container_add(GTK_CONTAINER(window), stack);
     
          GtkWidget *page_start = create_page_start(window, stack);
          gtk_stack_add_named(GTK_STACK(stack), page_start, "page_start");
          GtkWidget *page_game = create_page_game(window, stack);
          gtk_stack_add_named(GTK_STACK(stack), page_game, "page_game");
      
          g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit),NULL);
          gtk_widget_show_all(window);
          gtk_main();
      
          return 0;
      }

page_start.c:

    static void start_game(GtkWidget *widget, gpointer data){
             GtkStack *stack = GTK_STACK(data);
             gtk_stack_set_visible_child_name(stack, "page_game");
    }
    
    GtkWidget *create_page_start(GtkWidget *window, GtkWidget *stack){
             GtkWidget *grid = gtk_grid_new();
             GtkWidget *label;
             GtkWidget *btn_start;
        
             GtkWidget *label = gtk_label_new("Label1");
             btn_start = gtk_button_new_with_label("Start");
             g_signal_connect(btn_start, "clicked", G_CALLBACK(start_game),stack);
             gtk_grid_attach(GTK_GRID(grid), label, 0, 0, 1,1);
             gtk_grid_attach(GTK_GRID(grid), btn_start, 0, 1,1,);
             return grid;
           }

I would like to have a page_start.css and a page_game.css for the two stack pages I have. In those CSS files I need to be able to get the label and btn_start for example.
Is using CSS even best practice? Are there other options?

Hi!

Using per-page CSS files is not recommended, because CSS doesn’t properly cascade when attached to a specific widget.
Better attach the CSS provider to the GdkScreen.

Then, for theming a specific page or button, get its style context with gtk_widget_get_style_context and give it a CSS class name with gtk_style_context_add_class.

In your CSS file, you can then refer to the class name with something like this:

.myclassname {
    color: red;
}

(see the reference)

There are a few old topics about theming on this forum, if you search a little you can find some interesting bits.

  1. In page_start.c

    GtkWidget* create_page_start (GtkWidget *window, GtkWidget *stack) {
        GtkWidget *grid = gtk_grid_new();
        GtkStyleContext *grid_style_context = gtk_widget_get_style_context (grid);
        
        gtk_style_context_add_class (grid_style_context, "startpage");
        
        /* Other code */
    
  2. Do the same for the main widget in create_page_game()

  3. In page_start.css

    .startpage /* child selectors here */ {
      /* properties here */
    }
    
    .startpage /* other child selectors here */ {
      /* their properties here */
    }
    
  4. Similarly, in page_game.css

    .gamepage /* child selectors here */ {
      /* properties here */
    }
    
    .gamepage /* other child selectors here */ {
      /* their properties here */
    }
    
  5. In the main style.css

    @import "page_start.css";
    @import "page_game.css";
    
  6. In your application::startup handler/override

    GtkCssProvider *css_provider = gtk_css_provider_new ();
    GdkScreen *screen = gdk_screen_get_default ();
    
    gtk_css_provider_load_from_resource (css_provider, "/your/app/id/style.css");
    gtk_style_context_add_provider_for_screen (screen,
                                               GTK_STYLE_PROVIDER (css_provider),
                                               GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
    
2 Likes

This topic was automatically closed 45 days after the last reply. New replies are no longer allowed.