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 (&&) 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 91 ┊ 92 ╰── 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 # 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 > 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