Styling Widgets With CSS
CSS is the presentation language of the web, allowing to change colors, spacing, fonts, borders, shadows of elements and so much more. And we can use it with GTK too!
However, not all properties are supported. You can find a list of the supported properties in the official documentation.
# Loading a Stylesheet
We start by creating a style.css
file in data/css/
:
1window {
2 background-color: orchid;
3}
For the moment we only put a dummy rule inside, to check when our stylesheet is loaded.
We add it to our data resources:
4<file>css/style.css</file>
Now, we need to load it when our application starts, so we will run code in the startup
virtual method. Styling information in GTK is managed by a Gtk.StyleContext
object, so we will create one for the default display, and then add as a provider a Gtk.CssProvider
object loaded with our stylesheet.
Which gives, translated in code, in src/Application.js
:
1import Gdk from 'gi://Gdk';
10class extends Gtk.Application {
11 vfunc_startup() {
12 super.vfunc_startup();
13 this.#loadStylesheet();
14 }
15
16 /* ... */
17
18 #loadStylesheet() {
19 // Load the stylesheet in a CssProvider
20 const provider = new Gtk.CssProvider();
21 provider.load_from_resource('/org/example/filebrowser/css/style.css');
22
23 // Add the provider to the StyleContext of the default display
24 Gtk.StyleContext.add_provider_for_display(
25 Gdk.Display.get_default(),
26 provider,
27 Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
28 );
29 }
30}
Now, when we run the application, its background should be purple-y.
# Styling Our Welcome Widget
Let’s use CSS to replace the styling information we put in our UI files.
First, we have to give our Welcome widget a CSS name, so that we can target it in our stylesheet. By default, it gets the widget
name, which is not very helpful. To change it, we set the CssName
property of the configuration object of the GObject.registerClass()
function:
4export const WelcomeWidget = GObject.registerClass({
5 GTypeName: 'FbrWelcomeWidget',
6 CssName: 'welcome',
7 Template: 'resource:///org/example/filebrowser/ui/WelcomeWidget.ui',
8 /* ... */
9}, class extends Gtk.Widget {});
We then remove the spacing
property of the layout manager in data/ui/WelcomeWidget.ui
:
5<object class="GtkBoxLayout">
6 <property name="orientation">vertical</property>
7</object>
And all the margin-*
properties of the widget in data/ui/Window.ui
:
5<object class="FbrWelcomeWidget">
6 <property name="welcome-text">Welcome to our new file browser!</property>
7 <property name="valign">center</property>
8</object>
The spacing
property can be replaced by the border-spacing
CSS property. The different margin-*
properties can be replaced by the shorthand margin
CSS property. Remove the rules in the style.css
file and add these ones for the Welcome widget:
1welcome {
2 border-spacing: 18px;
3 margin: 36px;
4}
We can go further, and for instance change the font size and weight of the label inside. The CSS name of each widget can be found in the “CSS Nodes” section of its documentation page. So, for a Gtk.Label
, we can see that the CSS name is label
.
To only change the appearance of the label directly inside our widget (in order to not change other labels such as the one in the button), we use the child combinator selector:
6welcome > label {
7 font-size: 1.4em;
8 font-weight: bold;
9}
# CSS Classes
To give widgets different appearances depending on the context (for example, allowing different font sizes for our Welcome widget), we can use CSS classes.
To give a widget a class in the UI file, we use the style
element, and add a class
element with the name
attribute set to the class we want. A widget can have multiple classes
Let’s add the big
class to the Welcome widget instance of the main window in data/ui/Window.ui
(removing the margins in the meantime):
5<object class="FbrWelcomeWidget">
6 <!-- ... -->
7 <style>
8 <class name="big"/>
9 </style>
10</object>
And update the selector for the label inside our widget in data/css/style.css
:
6welcome.big > label {
7 /* ... */
8}
Now, the text of our widget will only be bigger when it has the big
class.
# Built-In Classes
Some widgets have built-in classes that you can use. They are mentioned in the “CSS Nodes” section of their documentation page.
For instance, we can read that the Gtk.Button
object can have the suggested-action
class. We can use it on the button of our widget to give it more impact.
Let’s add this class to the button in data/ui/WelcomeWidget.ui
:
24<object class="GtkButton">
25 <!-- ... -->
26 <style>
27 <class name="suggested-action"/>
28 </style>
29</object>
The button now has a blue background, inviting the user to click on it.
CSS in GTK is very powerful, it also has some advanced features such as color definitions and expressions and some custom properties, you can read about these in the official documentation. Use it to make your application stand out!