1<?xml version="1.0"?>
2<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
3               "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
4]>
5<refentry id="chap-css-overview">
6<refmeta>
7<refentrytitle>GTK+ CSS Overview</refentrytitle>
8<manvolnum>3</manvolnum>
9<refmiscinfo>GTK Library</refmiscinfo>
10</refmeta>
11
12<refnamediv>
13<refname>GTK+ CSS Overview</refname>
14<refpurpose>
15Overview of CSS in GTK+
16</refpurpose>
17</refnamediv>
18
19
20<!--
21Formatting conventions:
22We use
23
24〈 U+2329 Left-pointing Angle Bracket
25〉 U+232A Right-pointing Angle Bracket
26
27for indicating non-terminals in syntax productions.
28
29We use <literallayout> for syntax productions, and each line is put in a <code>
30(the latter is a workaround for deficiences in the developer.gnome.org post-processing).
31-->
32
33<refsect1 id="css-overview">
34  <title>Overview of CSS in GTK+</title>
35
36  <para>
37    This chapter describes in detail how GTK+ uses CSS for styling
38    and layout.
39  </para>
40
41  <para>
42    We loosely follow the CSS
43    <ulink url="https://www.w3.org/TR/css-values/#value-defs">value definition</ulink>
44    specification in the formatting of syntax productions.
45    <simplelist>
46      <member>Nonterminals are enclosed in angle backets (〈〉), all other strings that are not listed here are literals</member>
47      <member>Juxtaposition means all components must occur, in the given order</member>
48      <member>A double ampersand (&amp;&amp;) means all components must occur, in any order</member>
49      <member>A double bar (||) means one or more of the components must occur, in any order</member>
50      <member>A single bar (|) indicates an alternative; exactly one of the components must occur</member>
51      <member>Brackets ([]) are used for grouping</member>
52      <member>A question mark (?) means that the preceding component is optional</member>
53      <member>An asterisk (*) means zero or more copies of the preceding component</member>
54      <member>A plus (+) means one or more copies of the preceding component</member>
55      <member>A number in curly braces ({n}) means that the preceding component occurs exactly n times</member>
56      <member>Two numbers in curly braces ({m,n}) mean that the preceding component occurs at least m times and at most n times</member>
57    </simplelist>
58  </para>
59
60  <refsect2>
61    <title>CSS nodes</title>
62
63    <para>
64      GTK+ applies the style information found in style sheets by matching
65      the selectors against a tree of nodes. Each node in the tree has a
66      name, a state and possibly style classes. The children of each node
67      are linearly ordered.
68    </para>
69
70    <para>
71      Every widget has one or more of these CSS nodes, and determines their
72      name, state, style classes and how they are layed out as children and
73      siblings in the overall node tree. The documentation for each widget
74      explains what CSS nodes it has.
75    </para>
76
77    <example>
78      <title>The CSS nodes of a GtkScale</title>
79      <programlisting><![CDATA[
80scale[.fine-tune]
81├── marks.top
82│   ├── mark
83┊   ┊
84│   ╰── mark
85├── trough
86│   ├── slider
87│   ├── [highlight]
88│   ╰── [fill]
89╰── marks.bottom
90    ├── mark
9192    ╰── mark
93]]></programlisting>
94    </example>
95
96  </refsect2>
97
98  <refsect2>
99    <title>Style sheets</title>
100
101    <para>
102      The basic structure of the style sheets understood by GTK+ is
103      a series of statements, which are either rule sets or “@-rules”,
104      separated by whitespace.
105    </para>
106
107    <para>
108      A rule set consists of a selector and a declaration block, which is
109      a series of declarations enclosed in curly braces. The declarations
110      are separated by semicolons. Multiple selectors can share the same
111      declaration block, by putting all the separators in front of the block,
112      separated by commas.
113    </para>
114
115    <example>
116      <title>A rule set with two selectors</title>
117      <programlisting><![CDATA[
118button, entry {
119  color: #ff00ea;
120  font: 12px "Comic Sans";
121}
122]]></programlisting>
123    </example>
124
125  </refsect2>
126
127  <refsect2>
128    <title>Importing style sheets</title>
129
130    <para>
131      GTK+ supports the CSS @import rule, in order to load another
132      style sheet in addition to the currently parsed one.
133    </para>
134
135    <para>
136      The syntax for @import rules is as follows:
137    </para>
138
139<literallayout><code>〈import rule〉 = @import [ 〈url〉 | 〈string〉 ]</code>
140<code>〈url〉 = url( 〈string〉 )</code>
141</literallayout>
142
143    <example><title>An example for using the @import rule</title>
144      <programlisting><![CDATA[
145@import url("path/to/common.css");
146]]></programlisting>
147    </example>
148
149    <para>
150      To learn more about the @import rule, you can read the
151      <ulink url="https://www.w3.org/TR/css3-cascade/#at-import">Cascading</ulink>
152      module of the CSS specification.
153    </para>
154
155  </refsect2>
156
157  <refsect2>
158    <title>Selectors</title>
159
160    <para>
161      Selectors work very similar to the way they do in CSS.
162    </para>
163
164    <para>
165      All widgets have one or more CSS nodes with element names and style
166      classes. When style classes are used in selectors, they have to be prefixed
167      with a period. Widget names can be used in selectors like IDs. When used
168      in a selector, widget names must be prefixed with a &num; character.
169    </para>
170
171    <para>
172      In more complicated situations, selectors can be combined in various ways.
173      To require that a node satisfies several conditions, combine several selectors
174      into one by concatenating them. To only match a node when it occurs inside some
175      other node, write the two selectors after each other, separated by whitespace.
176      To restrict the match to direct children of the parent node, insert a &gt;
177      character between the two selectors.
178    </para>
179
180    <example>
181      <title>Theme labels that are descendants of a window</title>
182      <programlisting><![CDATA[
183window label {
184  background-color: #898989;
185}
186]]></programlisting>
187    </example>
188
189    <example>
190      <title>Theme notebooks, and anything within</title>
191      <programlisting><![CDATA[
192notebook {
193  background-color: #a939f0;
194}
195]]></programlisting>
196    </example>
197
198    <example>
199      <title>Theme combo boxes, and entries that are direct children of a notebook</title>
200      <programlisting><![CDATA[
201combobox,
202notebook > entry {
203  color: @fg_color;
204  background-color: #1209a2;
205}
206]]></programlisting>
207    </example>
208
209    <example>
210      <title>Theme any widget within a GtkBox</title>
211      <programlisting><![CDATA[
212box * {
213  font: 20px Sans;
214}
215]]></programlisting>
216    </example>
217
218    <example>
219      <title>Theme a label named title-label</title>
220      <programlisting><![CDATA[
221label#title-label {
222  font: 15px Sans;
223}
224]]></programlisting>
225    </example>
226
227    <example>
228      <title>Theme any widget named main-entry</title>
229      <programlisting><![CDATA[
230#main-entry {
231  background-color: #f0a810;
232}
233]]></programlisting>
234    </example>
235
236    <example>
237      <title>Theme all widgets with the style class entry</title>
238      <programlisting><![CDATA[
239.entry {
240  color: #39f1f9;
241}
242]]></programlisting>
243    </example>
244
245    <example>
246      <title>Theme the entry of a GtkSpinButton</title>
247      <programlisting><![CDATA[
248spinbutton entry {
249  color: #900185;
250}
251]]></programlisting>
252    </example>
253
254    <para>
255      It is possible to select CSS nodes depending on their position amongst
256      their siblings by applying pseudo-classes to the selector, like :first-child,
257      :last-child or :nth-child(even). When used in selectors, pseudo-classes
258      must be prefixed with a : character.
259    </para>
260
261    <example>
262      <title>Theme labels in the first notebook tab</title>
263      <programlisting><![CDATA[
264notebook tab:first-child label {
265  color: #89d012;
266}
267]]></programlisting>
268    </example>
269
270    <para>
271      Another use of pseudo-classes is to match widgets depending on their
272      state. The available pseudo-classes for widget states are :active, :hover
273      :disabled, :selected, :focus, :indeterminate, :checked and :backdrop.
274      In addition, the following pseudo-classes don't have a direct equivalent
275      as a widget state: :dir(ltr) and :dir(rtl) (for text direction), :link and
276      :visited (for links) and :drop(active) (for highlighting drop targets).
277      Widget state pseudo-classes may only apply to the last element in a selector.
278    </para>
279
280    <example>
281      <title>Theme pressed buttons</title>
282      <programlisting><![CDATA[
283button:active {
284  background-color: #0274d9;
285}
286]]></programlisting>
287    </example>
288
289    <example>
290      <title>Theme buttons with the mouse pointer over it</title>
291      <programlisting><![CDATA[
292button:hover {
293  background-color: #3085a9;
294}
295]]></programlisting>
296    </example>
297
298    <example>
299      <title>Theme insensitive widgets</title>
300      <programlisting><![CDATA[
301*:disabled {
302  background-color: #320a91;
303}
304]]></programlisting>
305    </example>
306
307    <example>
308      <title>Theme checkbuttons that are checked</title>
309      <programlisting><![CDATA[
310checkbutton:checked {
311  background-color: #56f9a0;
312}
313]]></programlisting>
314    </example>
315
316    <example>
317      <title>Theme focused labels</title>
318        <programlisting><![CDATA[
319label:focus {
320  background-color: #b4940f;
321}
322]]></programlisting>
323    </example>
324
325    <example>
326      <title>Theme inconsistent checkbuttons</title>
327      <programlisting><![CDATA[
328checkbutton:indeterminate {
329  background-color: #20395a;
330}
331]]></programlisting>
332    </example>
333
334    <para>
335      To determine the effective style for a widget, all the matching rule
336      sets are merged. As in CSS, rules apply by specificity, so the rules
337      whose selectors more closely match a node will take precedence
338      over the others.
339    </para>
340
341    <para>
342      The full syntax for selectors understood by GTK+ can be found in the
343      table below. The main difference to CSS is that GTK+ does not currently
344      support attribute selectors.
345    </para>
346
347    <table>
348      <title>Selector syntax</title>
349      <tgroup cols="4">
350        <thead>
351          <row><entry>Pattern</entry><entry>Matches</entry><entry>Reference</entry><entry>Notes</entry></row>
352        </thead>
353        <tbody>
354          <row>
355            <entry><phrase role="nowrap">*</phrase></entry>
356            <entry>any node</entry>
357            <entry><ulink url="https://www.w3.org/TR/css3-selectors/#universal-selector">CSS</ulink></entry>
358            <entry></entry>
359          </row>
360          <row>
361            <entry><phrase role="nowrap">E</phrase></entry>
362            <entry>any node with name E</entry>
363            <entry><ulink url="https://www.w3.org/TR/css3-selectors/#type-selectors">CSS</ulink></entry>
364            <entry></entry>
365          </row>
366          <row>
367            <entry><phrase role="nowrap">E.class</phrase></entry>
368            <entry>any E node with the given style class</entry>
369            <entry><ulink url="https://www.w3.org/TR/css3-selectors/#class-html">CSS</ulink></entry>
370            <entry></entry>
371          </row>
372          <row>
373            <entry><phrase role="nowrap">E#id</phrase></entry>
374            <entry>any E node with the given ID</entry>
375            <entry><ulink url="https://www.w3.org/TR/css3-selectors/#id-selectors">CSS</ulink></entry>
376            <entry>GTK+ uses the widget name as ID</entry>
377          </row>
378          <row>
379            <entry><phrase role="nowrap">E:nth-child(〈nth-child〉)</phrase></entry>
380            <entry>any E node which is the n-th child of its parent node</entry>
381            <entry><ulink url="https://www.w3.org/TR/css3-selectors/#structural-pseudos">CSS</ulink></entry>
382            <entry></entry>
383          </row>
384          <row>
385            <entry><phrase role="nowrap">E:nth-last-child(〈nth-child〉)</phrase></entry>
386            <entry>any E node which is the n-th child of its parent node, counting from the end</entry>
387            <entry><ulink url="https://www.w3.org/TR/css3-selectors/#structural-pseudos">CSS</ulink></entry>
388            <entry></entry>
389          </row>
390          <row>
391            <entry><phrase role="nowrap">E:first-child</phrase></entry>
392            <entry>any E node which is the first child of its parent node</entry>
393            <entry><ulink url="https://www.w3.org/TR/css3-selectors/#structural-pseudos">CSS</ulink></entry>
394            <entry></entry>
395          </row>
396          <row>
397            <entry><phrase role="nowrap">E:last-child</phrase></entry>
398            <entry>any E node which is the last child of its parent node</entry>
399            <entry><ulink url="https://www.w3.org/TR/css3-selectors/#structural-pseudos">CSS</ulink></entry>
400            <entry></entry>
401          </row>
402          <row>
403            <entry><phrase role="nowrap">E:only-child</phrase></entry>
404            <entry>any E node which is the only child of its parent node</entry>
405            <entry><ulink url="https://www.w3.org/TR/css3-selectors/#structural-pseudos">CSS</ulink></entry>
406            <entry>Equivalent to E:first-child:last-child</entry>
407          </row>
408          <row>
409            <entry><phrase role="nowrap">E:link, E:visited</phrase></entry>
410            <entry>any E node which represents a hyperlink, not yet visited (:link) or already visited (:visited)</entry>
411            <entry><ulink url="https://www.w3.org/TR/css3-selectors/#link">CSS</ulink></entry>
412            <entry>Corresponds to GTK_STATE_FLAG_LINK and GTK_STATE_FLAGS_VISITED</entry>
413          </row>
414          <row>
415            <entry><phrase role="nowrap">E:active, E:hover, E:focus</phrase></entry>
416            <entry>any E node which is part of a widget with the corresponding state</entry>
417            <entry><ulink url="https://www.w3.org/TR/css3-selectors/#useraction-pseudos">CSS</ulink></entry>
418            <entry>Corresponds to GTK_STATE_FLAG_ACTIVE, GTK_STATE_FLAG_PRELIGHT and GTK_STATE_FLAGS_FOCUSED; GTK+ also allows E:prelight and E:focused</entry>
419          </row>
420          <row>
421            <entry><phrase role="nowrap">E:disabled</phrase></entry>
422            <entry>any E node which is part of a widget which is disabled</entry>
423            <entry><ulink url="https://www.w3.org/TR/css3-selectors/#UIstates">CSS</ulink></entry>
424            <entry>Corresponds to GTK_STATE_FLAG_INSENSITIVE; GTK+ also allows E:insensitive</entry>
425          </row>
426          <row>
427            <entry><phrase role="nowrap">E:checked</phrase></entry>
428            <entry>any E node which is part of a widget (e.g. radio- or checkbuttons) which is checked</entry>
429            <entry><ulink url="https://www.w3.org/TR/css3-selectors/#UIstates">CSS</ulink></entry>
430            <entry>Corresponds to GTK_STATE_FLAG_CHECKED</entry>
431          </row>
432          <row>
433            <entry><phrase role="nowrap">E:indeterminate</phrase></entry>
434            <entry>any E node which is part of a widget (e.g. radio- or checkbuttons) which is in an indeterminate state</entry>
435            <entry><ulink url="https://www.w3.org/TR/css3-selectors/#indeterminate">CSS3</ulink>,
436                   <ulink url="https://drafts.csswg.org/selectors/#indeterminate">CSS4</ulink></entry>
437            <entry>Corresponds to GTK_STATE_FLAG_INCONSISTENT; GTK+ also allows E:inconsistent</entry>
438          </row>
439          <row>
440            <entry><phrase role="nowrap">E:backdrop, E:selected</phrase></entry>
441            <entry>any E node which is part of a widget with the corresponding state</entry>
442            <entry></entry>
443            <entry>Corresponds to GTK_STATE_FLAG_BACKDROP, GTK_STATE_FLAG_SELECTED</entry>
444          </row>
445          <row>
446            <entry><phrase role="nowrap">E:not(〈selector〉)</phrase></entry>
447            <entry>any E node which does not match the simple selector 〈selector〉</entry>
448            <entry><ulink url="https://www.w3.org/TR/css3-selectors/#negation">CSS</ulink></entry>
449            <entry></entry>
450          </row>
451          <row>
452            <entry><phrase role="nowrap">E:dir(ltr), E:dir(rtl)</phrase></entry>
453            <entry>any E node that has the corresponding text direction</entry>
454            <entry><ulink url="https://drafts.csswg.org/selectors/#the-dir-pseudo">CSS4</ulink></entry>
455            <entry></entry>
456          </row>
457          <row>
458            <entry><phrase role="nowrap">E:drop(active)</phrase></entry>
459            <entry>any E node that is an active drop target for a current DND operation</entry>
460            <entry><ulink url="https://drafts.csswg.org/selectors/#drag-pseudos">CSS4</ulink></entry>
461            <entry></entry>
462          </row>
463          <row>
464            <entry><phrase role="nowrap">E F</phrase></entry>
465            <entry>any F node which is a descendent of an E node</entry>
466            <entry><ulink url="https://www.w3.org/TR/css3-selectors/#descendent-combinators">CSS</ulink></entry>
467            <entry></entry>
468          </row>
469          <row>
470            <entry><phrase role="nowrap">E > F</phrase></entry>
471            <entry>any F node which is a child of an E node</entry>
472            <entry><ulink url="https://www.w3.org/TR/css3-selectors/#child-combinators">CSS</ulink></entry>
473            <entry></entry>
474          </row>
475          <row>
476            <entry><phrase role="nowrap">E ~ F</phrase></entry>
477            <entry>any F node which is preceded by an E node</entry>
478            <entry><ulink url="https://www.w3.org/TR/css3-selectors/#general-sibling-combinators">CSS</ulink></entry>
479            <entry></entry>
480          </row>
481          <row>
482            <entry><phrase role="nowrap">E + F</phrase></entry>
483            <entry>any F node which is immediately preceded by an E node</entry>
484            <entry><ulink url="https://www.w3.org/TR/css3-selectors/#adjacent-sibling-combinators">CSS</ulink></entry>
485            <entry></entry>
486          </row>
487        </tbody>
488      </tgroup>
489    </table>
490
491<literallayout><code>〈nth-child〉 = even | odd | 〈integer〉 | 〈integer〉n | 〈integer〉n [ + | - ] 〈integer〉</code>
492</literallayout>
493
494    <para>
495      To learn more about selectors in CSS, read the
496      <ulink url="https://www.w3.org/TR/css3-selectors/">Selectors</ulink>
497      module of the CSS specification.
498    </para>
499
500  </refsect2>
501
502  <refsect2>
503    <title>Colors</title>
504
505    <para>
506      CSS allows to specify colors in various ways, using numeric
507      values or names from a predefined list of colors.
508    </para>
509
510<literallayout><code>〈color〉 = currentColor | transparent | 〈color name〉 | 〈rgb color〉 | 〈rgba color〉 | 〈hex color〉 | 〈gtk color〉</code>
511<code>〈rgb color〉 = rgb( 〈number〉, 〈number〉, 〈number〉 ) | rgb( 〈percentage〉, 〈percentage〉, 〈percentage〉 )</code>
512<code>〈rgba color〉 = rgba( 〈number〉, 〈number〉, 〈number〉, 〈alpha value〉 ) | rgba( 〈percentage〉, 〈percentage〉, 〈percentage〉, 〈alpha value〉 )</code>
513<code>〈hex color〉 = #〈hex digits〉</code>
514<code>〈alpha value〉 = 〈number〉</code>, clamped to values between 0 and 1
515</literallayout>
516
517    <para>
518      The keyword currentColor resolves to the current value of the
519      color property when used in another property, and to the inherited value
520      of the color property when used in the color property itself.
521    </para>
522
523    <para>
524      The keyword transparent can be considered a shorthand for rgba(0,0,0,0).
525    </para>
526
527    <para>
528      For a list of valid color names and for more background on colors in
529      CSS, see the <ulink url="https://www.w3.org/TR/css3-color/#svg-color">Color</ulink>
530      module of the CSS specification.
531    </para>
532
533    <example>
534      <title>Specifying colors in various ways</title>
535      <programlisting><![CDATA[
536  color: transparent;
537  background-color: red;
538  border-top-color: rgb(128,57,0);
539  border-left-color: rgba(10%,20%,30%,0.5);
540  border-right-color: #ff00cc;
541  border-bottom-color: #ffff0000cccc;
542]]></programlisting>
543    </example>
544
545    <para>
546      GTK+ adds several additional ways to specify colors.
547    </para>
548
549<literallayout><code>〈gtk color〉 = 〈symbolic color〉 | 〈color expression〉 | 〈win32 color〉</code>
550</literallayout>
551
552    <para>
553      The first is a reference to a color defined via a @define-color rule.
554      The syntax for @define-color rules is as follows:
555    </para>
556
557<literallayout><code>〈define color rule〉 = @define-color 〈name〉 〈color〉</code>
558</literallayout>
559
560    <para>
561      To refer to the color defined by a @define-color rule,
562      use the name from the rule, prefixed with @.
563    </para>
564
565<literallayout><code>〈symbolic color〉 = @〈name〉</code>
566</literallayout>
567
568    <example><title>An example for defining colors</title>
569      <programlisting><![CDATA[
570@define-color bg_color #f9a039;
571
572* {
573  background-color: @bg_color;
574}
575]]></programlisting>
576    </example>
577
578    <para>
579      GTK+ also supports color expressions, which allow colors to be transformed
580      to new ones and can be nested, providing a rich language to define colors.
581      Color expressions resemble functions, taking 1 or more colors and in some
582      cases a number as arguments.
583    </para>
584    <para>
585      shade() leaves the color unchanged when the number is 1 and transforms it
586      to black or white as the number approaches 0 or 2 respectively. For mix(),
587      0 or 1 return the unaltered 1st or 2nd color respectively; numbers between
588      0 and 1 return blends of the two; and numbers below 0 or above 1 intensify
589      the RGB components of the 1st or 2nd color respectively. alpha() takes a
590      number from 0 to 1 and applies that as the opacity of the supplied color.
591    </para>
592
593<literallayout><code>〈color expression〉 = lighter( 〈color〉 ) | darker( 〈color〉 ) | shade( 〈color〉, 〈number〉 ) |</code>
594<code>                     alpha( 〈color〉, 〈number〉 ) | mix( 〈color〉, 〈color〉, 〈number〉 )</code>
595</literallayout>
596
597    <para>
598      On Windows, GTK+ allows to refer to system colors, as follows:
599    </para>
600
601<literallayout><code>〈win32 color〉 = -gtk-win32-color( 〈name〉, 〈integer〉 )</code>
602</literallayout>
603
604  </refsect2>
605
606  <refsect2>
607    <title>Images</title>
608
609    <para>
610      CSS allows to specify images in various ways, for backgrounds
611      and borders.
612    </para>
613
614<literallayout><code>〈image〉 = 〈url〉 | 〈crossfade〉 | 〈alternatives〉 | 〈gradient〉 | 〈gtk image〉</code>
615<code>〈crossfade〉 = cross-fade( 〈percentage〉, 〈image〉, 〈image〉 )</code>
616<code>〈alternatives〉 = image([ 〈image〉, ]* [ 〈image〉 | 〈color〉 ] )</code>
617<code>〈gradient〉 = 〈linear gradient〉 | 〈radial gradient〉</code>
618<code>〈linear gradient〉 = [ linear-gradient | repeating-linear-gradient ] (</code>
619<code>                      [ [ 〈angle〉 | to 〈side or corner〉 ] , ]?</code>
620<code>                      〈color stops〉 )</code>
621<code>〈radial gradient〉 = [ radial-gradient | repeating-radial-gradient ] (</code>
622<code>                      [ [ 〈shape〉 || 〈size〉 ] [ at 〈position〉 ]? , | at 〈position〉, ]?</code>
623<code>                      〈color stops〉 )</code>
624<code>〈side or corner〉 = [ left | right ] || [ top | bottom ]</code>
625<code>〈color stops〉 =  〈color stop〉 [ , 〈color stop〉 ]+</code>
626<code>〈color stop〉 = 〈color〉 [ 〈percentage〉 | 〈length〉 ]?</code>
627<code>〈shape〉 = circle | ellipse</code>
628<code>〈size〉 = 〈extent keyword〉 | 〈length〉 | [ 〈length〉 | 〈percentage〉 ]{1,2}</code>
629<code>〈extent keyword〉 = closest-size | farthest-side | closest-corner | farthest-corner</code>
630</literallayout>
631
632    <para>
633      The simplest way to specify an image in CSS is to load an image
634      file from a URL. CSS does not specify anything about supported file
635      formats; within GTK+, you can expect at least PNG, JPEG and SVG to
636      work. The full list of supported image formats is determined by the
637      available gdk-pixbuf image loaders and may vary between systems.
638    </para>
639
640    <example>
641      <title>Loading an image file</title>
642      <programlisting><![CDATA[
643button {
644  background-image: url("water-lily.png");
645}
646]]></programlisting>
647    </example>
648
649    <para>
650      A crossfade lets you specify an image as an intermediate between two
651      images. Crossfades are specified in the draft of the level 4
652      <ulink url="https://www.w3.org/TR/css4-images">Image</ulink>
653      module of the CSS specification.
654    </para>
655
656    <para>
657    </para>
658
659    <example>
660      <title>Crossfading two images</title>
661      <programlisting><![CDATA[
662button {
663  background-image: cross-fade(50%, url("water-lily.png"), url("buffalo.jpg"));
664}
665]]></programlisting>
666    </example>
667
668    <para>
669      The image() syntax provides a way to specify fallbacks in case an image
670      format may not be supported. Multiple fallback images can be specified,
671      and will be tried in turn until one can be loaded successfully. The
672      last fallback may be a color, which will be rendered as a solid color
673      image.
674    </para>
675
676    <example>
677      <title>Image fallback</title>
678      <programlisting><![CDATA[
679button {
680  background-image: image(url("fancy.svg"), url("plain.png"), green);
681}
682]]></programlisting>
683    </example>
684
685    <para>
686      Gradients are images that smoothly fades from one color to another. CSS
687      provides ways to specify repeating and non-repeating linear and radial
688      gradients. Radial gradients can be circular, or axis-aligned ellipses.
689      In addition to CSS gradients, GTK+ has its own -gtk-gradient extensions.
690    </para>
691
692    <para>
693      A linear gradient is created by specifying a gradient line and then several
694      colors placed along that line. The gradient line may be specified using
695      an angle, or by using direction keywords.
696    </para>
697
698    <example>
699      <title>Linear gradients</title>
700      <programlisting><![CDATA[
701button {
702  background-image: linear-gradient(45deg, yellow, blue);
703}
704label {
705  background-image: linear-gradient(to top right, blue 20%, #f0f 80%);
706}
707]]></programlisting>
708    </example>
709
710    <para>
711      A radial gradient is created by specifying a center point and one or two
712      radii. The radii may be given explicitly as lengths or percentages or
713      indirectly, by keywords that specify how the end circle or ellipsis
714      should be positioned relative to the area it is derawn in.
715    </para>
716
717    <example>
718      <title>Radial gradients</title>
719      <programlisting><![CDATA[
720button {
721  background-image: radial-gradient(ellipse at center, yellow 0%, green 100%);
722}
723label {
724  background-image: radial-gradient(circle farthest-side at left bottom, red, yellow 50px, green);
725}
726]]></programlisting>
727    </example>
728
729    <para>
730      To learn more about gradients in CSS, including details of how color stops
731      are placed on the gradient line and keywords for specifying radial sizes,
732      you can read the
733      <ulink url="https://www.w3.org/TR/css3-images/#gradients">Image</ulink>
734      module of the CSS specification.
735    </para>
736
737    <para>
738      GTK+ extends the CSS syntax for images and also uses it for specifying icons.
739    </para>
740
741<literallayout><code>〈gtk image〉 = 〈gtk gradient〉 | 〈themed icon〉 | 〈scaled image〉 | 〈recolored image〉 | 〈win32 theme part〉</code>
742</literallayout>
743
744    <para>
745      GTK+ supports an alternative syntax for linear and radial gradients (which
746      was implemented before CSS gradients were supported).
747    </para>
748
749<literallayout><code>〈gtk gradient〉 = 〈gtk linear gradient〉 | 〈gtk radial gradient〉</code>
750<code>〈gtk linear gradient〉 = -gtk-gradient(linear,</code>
751<code>                          [ 〈x position〉 〈y position〉 , ]{2}</code>
752<code>                          〈gtk color stops〉 )</code>
753<code>〈gtk radial gradient〉 = -gtk-gradient(radial,</code>
754<code>                          [ 〈x position〉 〈y position〉 , 〈radius〉 , ]{2}</code>
755<code>                          〈gtk color stops〉 )</code>
756<code>〈x position〉 = left | right | center | 〈number〉</code>
757<code>〈y position〉 = top | bottom | center | 〈number〉</code>
758<code>〈radius 〉 = 〈number〉</code>
759<code>〈gtk color stops〉 = 〈gtk color stop〉 [ , 〈gtk color stop〉 ]+</code>
760<code>〈gtk color stop〉 = color-stop( 〈number〉 , 〈color〉 ) | from( 〈color〉 ) | to( 〈color〉 )</code>
761</literallayout>
762
763    <para>
764      The numbers used to specify x and y positions, radii, as well as the
765      positions of color stops, must be between 0 and 1. The keywords for for
766      x and y positions (left, right, top, bottom, center), map to numeric
767      values of 0, 1 and 0.5 in the obvious way. Color stops using the from() and
768      to() syntax are abbreviations for color-stop with numeric positions of
769      0 and 1, respectively.
770    </para>
771
772    <example>
773      <title>Linear gradients</title>
774      <programlisting><![CDATA[
775button {
776  background-image: -gtk-gradient (linear,
777                                   left top, right bottom,
778                                   from(@yellow), to(@blue));
779}
780label {
781  background-image: -gtk-gradient (linear,
782                                   0 0, 0 1,
783                                   color-stop(0, @yellow),
784                                   color-stop(0.2, @blue),
785                                   color-stop(1, #0f0));
786}
787]]></programlisting>
788    </example>
789
790    <example>
791      <title>Radial gradients</title>
792      <programlisting><![CDATA[
793button {
794  background-image: -gtk-gradient (radial,
795                                   center center, 0,
796                                   center center, 1,
797                                   from(@yellow), to(@green));
798}
799label {
800  background-image: -gtk-gradient (radial,
801                                   0.4 0.4, 0.1,
802                                   0.6 0.6, 0.7,
803                                   color-stop(0, #f00),
804                                   color-stop(0.1, $a0f),
805                                   color-stop(0.2, @yellow),
806                                   color-stop(1, @green));
807}
808]]></programlisting>
809    </example>
810
811    <para>
812      GTK+ has extensive support for loading icons from icon themes. It is
813      accessible from CSS with the -gtk-icontheme syntax.
814    </para>
815
816<literallayout><code>〈themed icon〉 = -gtk-icontheme( 〈icon name〉 )</code>
817</literallayout>
818
819    <para>
820      The specified icon name is used to look up a themed icon, while taking
821      into account the values of the -gtk-icon-theme and -gtk-icon-palette
822      properties. This kind of image is mainly used as value of the
823      -gtk-icon-source property.
824    </para>
825
826    <example>
827      <title>Using themed icons in CSS</title>
828      <programlisting><![CDATA[
829spinner {
830  -gtk-icon-source: -gtk-icontheme('process-working-symbolic');
831  -gtk-icon-palette: success blue, warning #fc3, error magenta;
832}
833arrow.fancy {
834  -gtk-icon-source: -gtk-icontheme('pan-down');
835  -gtk-icon-theme: 'Oxygen';
836}
837]]></programlisting>
838    </example>
839
840    <para>
841      GTK+ supports scaled rendering on hi-resolution displays. This works
842      best if images can specify normal and hi-resolution variants. From
843      CSS, this can be done with the -gtk-scaled syntax.
844    </para>
845
846<literallayout><code>〈scaled image〉 = -gtk-scaled( 〈image〉[ , 〈image〉 ]* )</code>
847</literallayout>
848
849    <para>
850      While -gtk-scaled accepts multiple higher-resolution variants, in
851      practice, it will mostly be used to specify a regular image and one
852      variant for scale 2.
853    </para>
854
855    <example>
856      <title>Scaled images in CSS</title>
857      <programlisting><![CDATA[
858arrow {
859  -gtk-icon-source: -gtk-scaled(url('my-arrow.png'),
860                                url('my-arrow@2.png'));
861}
862]]></programlisting>
863    </example>
864
865<literallayout><code>〈recolored image〉 = -gtk-recolor( 〈url〉 [ , 〈color palette〉 ] )</code>
866</literallayout>
867
868    <para>
869      Symbolic icons from the icon theme are recolored according to the
870      -gtk-icon-palette property. The recoloring is sometimes needed for images
871      that are not part of an icon theme, and the -gtk-recolor syntax makes
872      this available. -gtk-recolor requires a url as first argument. The
873      remaining arguments specify the color palette to use. If the palette
874      is not explicitly specified, the current value of the -gtk-icon-palette
875      property is used.
876    </para>
877
878    <example>
879      <title>Recoloring an image</title>
880      <programlisting><![CDATA[
881arrow {
882  -gtk-icon-source: -gtk-recolor(url('check.svg'), success blue, error rgb(255,0,0));
883}
884]]></programlisting>
885    </example>
886    <para>
887      On Windows, GTK+ allows to refer to system theme parts as images, as follows:
888    </para>
889
890<literallayout><code>〈win32 theme part〉 = -gtk-win32-theme-part( 〈name〉, 〈integer〉 〈integer〉</code>
891<code>                                              [ , [ over( 〈integer〉 〈integer〉 [ , 〈alpha value〉 ]? ) | margins( 〈integer〉{1,4} ) ] ]* )</code>
892</literallayout>
893
894  </refsect2>
895
896  <refsect2>
897    <title>Transitions</title>
898
899    <para>
900      CSS defines a mechanism by which changes in CSS property values can
901      be made to take effect gradually, instead of all at once. GTK+ supports
902      these transitions as well.
903    </para>
904
905    <para>
906      To enable a transition for a property when a rule set takes effect, it
907      needs to be listed in the transition-property property in that rule set.
908      Only animatable properties can be listed in the transition-property.
909    </para>
910
911    <para>
912      The details of a transition can modified with the transition-duration,
913      transition-timing-function and transition-delay properties.
914    </para>
915
916    <para>
917      To learn more about transitions, you can read the
918      <ulink url="www.w3.org/TR/css3-transitions/">Transitions</ulink>
919      module of the CSS specification.
920    </para>
921
922  </refsect2>
923
924  <refsect2>
925    <title>Animations</title>
926
927    <para>
928      In addition to transitions, which are triggered by changes of the underlying
929      node tree, CSS also supports defined animations. While transitions specify how
930      property values change from one value to a new value, animations explicitly
931      define intermediate property values in keyframes.
932    </para>
933
934    <para>
935      Keyframes are defined with an @-rule which contains one or more of rule sets
936      with special selectors. Property declarations for nonanimatable properties
937      are ignored in these rule sets (with the exception of animation properties).
938    </para>
939
940<literallayout><code>〈keyframe rule〉 = @keyframes 〈name〉 { 〈animation rule〉 }</code>
941<code>〈animation rule〉 = 〈animation selector〉 { 〈declaration〉* }</code>
942<code>〈animation selector〉 = 〈single animation selector〉 [ , 〈single animation selector〉 ]*</code>
943<code>〈single animation selector〉 = from | to | 〈percentage〉</code>
944</literallayout>
945
946    <para>
947      To enable an animation, the name of the keyframes must be set as the value
948      of the animation-name property. The details of the animation can modified
949      with the animation-duration, animation-timing-function, animation-iteration-count
950      and other animation properties.
951    </para>
952
953    <example>
954      <title>A CSS animation</title>
955      <programlisting><![CDATA[
956@keyframes spin {
957  to { -gtk-icon-transform: rotate(1turn); }
958}
959
960spinner {
961  animation-name: spin;
962  animation-duration: 1s;
963  animation-timing-function: linear;
964  animation-iteration-count: infinite;
965}
966]]></programlisting>
967    </example>
968
969    <para>
970      To learn more about animations, you can read the
971      <ulink url="www.w3.org/TR/css3-animations/">Animations</ulink>
972      module of the CSS specification.
973    </para>
974
975  </refsect2>
976
977  <refsect2>
978    <title>Key bindings</title>
979
980    <para>
981      In order to extend key bindings affecting different widgets,
982      GTK+ supports the @binding-set rule to parse a set of bind/unbind
983      directives. Note that in order to take effect, the binding sets
984      defined in this way must be associated with rule sets by setting
985      the -gtk-key-bindings property.
986    </para>
987
988    <para>
989      The syntax for @binding-set rules is as follows:
990    </para>
991
992<literallayout><code>〈binding set rule〉 = @binding-set 〈binding name〉 { [ [ 〈binding〉 | 〈unbinding〉 ] ; ]* }</code>
993<code>〈binding〉 = bind "〈accelerator〉" { 〈signal emission〉* }</code>
994<code>〈signal emission〉 = "〈signal name〉" ( [ 〈argument〉 [ , 〈argument〉 ]* ]? }</code>
995<code>〈unbinding〉 = unbind "〈accelerator〉"</code>
996</literallayout>
997
998    <para>
999      where 〈accelerator〉 is a string that can be parsed by gtk_accelerator_parse(),
1000      〈signal name〉 is the name of a keybinding signal of the widget in question,
1001      and the 〈argument〉 list must be according to the signals declaration.
1002    </para>
1003
1004    <example>
1005      <title>An example for using the @binding-set rule</title>
1006      <programlisting><![CDATA[
1007@binding-set binding-set1 {
1008  bind "<alt>Left" { "move-cursor" (visual-positions, -3, 0) };
1009  unbind "End";
1010};
1011
1012@binding-set binding-set2 {
1013  bind "<alt>Right" { "move-cursor" (visual-positions, 3, 0) };
1014  bind "<alt>KP_space" { "delete-from-cursor" (whitespace, 1)
1015                         "insert-at-cursor" (" ") };
1016};
1017
1018entry {
1019  -gtk-key-bindings: binding-set1, binding-set2;
1020}
1021]]></programlisting>
1022    </example>
1023
1024  </refsect2>
1025
1026</refsect1>
1027</refentry>
1028