GTK+ CSS
GTK+ CSS — Обзор CSS в GTK+
Обзор CSS в GTK+
В этой главе подробно описано, как GTK+ использует CSS для стилизации и макета.
Мы частично следуем спецификации определений значений CSS value definition при форматировании синтаксических произведений.
| Нетерминалы заключены в угловые скобки (〈〉), все другие строки, которые не перечислены здесь, являются литералами |
| Соположение означает, что все компоненты должны появляться в заданном порядке |
| Двойной амперсанд (&&) означает, что все компоненты должны появиться в любом порядке |
| Двойная черта (||) означает, что один или несколько компонентов должны появиться в любом порядке |
| Одинарная черта (|) указывает альтернативу; ровно один из компонентов должен появиться |
| Скобки ([]) используются для группирования |
| Вопросительный знак (?) означает, что предыдущий компонент является необязательным |
| Звездочка (*) означает ноль или более копий предыдущего компонента |
| Плюс (+) означает одну или более копий предыдущего компонента |
| Число в фигурных скобках ({n}) означает, что предыдущий компонент появляется ровно n раз |
| Два числа в фигурных скобках ({m,n}) означают, что предыдущий компонент появляется не менее m раз и не более n раз |
Узлы CSS
GTK+ применяет информацию о стиле, найденную в таблице стилей, путем сопоставления селекторов с деревом узлов. Каждый узел в дереве имеет имя, состояние и, возможно, классы стилей. Дочерние узлы каждого узла упорядочены линейно.
Каждый виджет имеет один или несколько таких узлов CSS, и определяет их имя, состояние, классы стилей и то, как они выстроены как дочерние и братские элементы в общем дереве узлов. Документация по каждому виджету объясняет, какие узлы CSS у него есть.
Пример 6. Узлы CSS GtkScale
Таблицы стилей
Основная структура таблиц стилей, понятных GTK+, представляет собой серию утверждений, которые являются либо наборами правил, либо «правилами @», разделенными пробелами.
Набор правил состоит из селектора и блока объявлений, который представляет собой серию объявлений, заключенных в фигурные скобки. Объявления разделяются точками с запятой. Несколько селекторов могут использовать один и тот же блок объявлений, поместив все разделители перед блоком, разделенные запятыми.
Пример 7. Набор правил с двумя селекторами
Импортирование таблиц стилей
GTK+ поддерживает правило CSS @import для загрузки другой таблицы стилей в дополнение к текущей разбираемой.
Синтаксис правил @import выглядит следующим образом:
〈import rule〉 = @import [ 〈url〉 | 〈string〉] ;
〈url〉 = url( 〈string〉)
Пример 8. Пример использования правила @import
Чтобы узнать больше о правиле @import, вы можете прочитать модуль Каскадирования спецификации CSS.
Селекторы
Селекторы работают очень похоже на селекторы в CSS.
Все виджеты имеют один или несколько узлов CSS с именами элементов и классами стилей. При использовании классов стилей в селекторах они должны быть префиксрованы точкой. Имена виджетов могут использоваться в селекторах как идентификаторы. При использовании в селекторе имена виджетов должны быть префиксрованы символом #.
В более сложных ситуациях селекторы могут комбинироваться различными способами. Чтобы потребовать, чтобы узел удовлетворял нескольким условиям, объедините несколько селекторов в один, конкатенируя их. Чтобы сопоставить узел только тогда, когда он находится внутри другого узла, запишите два селектора друг за другом, разделив их пробелом. Чтобы ограничить соответствие прямыми дочерними узлами родительского узла, вставьте символ > между двумя селекторами.
Пример 9. Метки темы, являющиеся потомками окна
Пример 10. Блокноты темы и всё, что внутри
Пример 11. Комбобоксы темы и записи, которые являются прямыми потомками блокнота
Пример 12. Тема любого виджета внутри GtkBox
Пример 13. Тема метки с именем title-label
Пример 14. Тема любого виджета с именем main-entry
Пример 15. Тема всех виджетов со стилем класса entry
Пример 16. Тема поля ввода GtkSpinButton
Можно выбрать узлы CSS в зависимости от их положения среди своих братьев и сестёр, применив псевдоклассы к селектору, например, :first-child, :last-child или :nth-child(even). При использовании в селекторах псевдоклассы должны быть префиксрованы символом :.
Пример 17. Тема меток на первой вкладке блокнота
Другое применение псевдоклассов — соответствие виджетам в зависимости от их состояния. Доступные псевдоклассы для состояний виджетов — :active, :hover, :disabled, :selected, :focus, :indeterminate, :checked и :backdrop. Кроме того, следующие псевдоклассы не имеют прямого эквивалента в виде состояния виджета: :dir(ltr) и :dir(rtl) (для направления текста), :link и :visited (для ссылок) и :drop(active) (для выделения целевых элементов перетаскивания). Псевдоклассы состояния виджета могут применяться только к последнему элементу в селекторе.
Пример 18. Тема нажатых кнопок
Пример 19. Тема кнопок с указателем мыши над ними
Пример 20. Тема нечувствительных виджетов
Пример 21. Тема отмеченных флажков
Пример 22. Тема выделенных меток
Пример 23. Тема несогласованных флажков
Для определения эффективного стиля для виджета объединяются все соответствующие наборы правил. Как и в CSS, правила применяются по специфичности, поэтому правила, селекторы которых более точно соответствуют узлу, будут иметь приоритет над другими.
Полный синтаксис селекторов, поддерживаемых GTK+, представлен в таблице ниже. Основное отличие от CSS заключается в том, что GTK+ в настоящее время не поддерживает селекторы атрибутов.
Таблица 1. Синтаксис селекторов
| Шаблон | Сопоставляемые элементы | Ссылка | Примечания |
|---|---|---|---|
| * | любой узел | CSS | |
| E | любой узел с именем E | CSS | |
| E.class | любой узел E с заданным классом стиля | CSS | |
| E#id | любой узел E с заданным идентификатором | CSS | GTK+ использует имя виджета как идентификатор |
| E:nth‑child(〈nth‑child〉) | любой узел E, который является n-ым потомком своего родительского узла | CSS | |
| E:nth‑last‑child(〈nth‑child〉) | любой узел E, который является n-ым потомком своего родительского узла, считая с конца | CSS | |
| E:first‑child | любой узел E, который является первым потомком своего родительского узла | CSS | |
| E:last‑child | любой узел E, который является последним потомком своего родительского узла | CSS | |
| E:only‑child | любой узел E, который является единственным потомком своего родительского узла | CSS | Эквивалентно E:first-child:last-child |
| E:link, E:visited | любой узел E, который представляет собой гиперссылку, ещё не посещённую (:link) или уже посещённую (:visited) | CSS | Соответствует GTK_STATE_FLAG_LINK и GTK_STATE_FLAGS_VISITED |
| E:active, E:hover, E:focus | любой узел E, являющийся частью виджета с соответствующим состоянием | CSS | Соответствует GTK_STATE_FLAG_ACTIVE, GTK_STATE_FLAG_PRELIGHT и GTK_STATE_FLAGS_FOCUSED; GTK+ также допускает E:prelight и E:focused |
| E:disabled | любой узел E, являющийся частью неактивного виджета | CSS | Соответствует GTK_STATE_FLAG_INSENSITIVE; GTK+ также допускает E:insensitive |
| E:checked | любой узел E, являющийся частью виджета (например, радио- или флажков), который отмечен | CSS | Соответствует GTK_STATE_FLAG_CHECKED |
| E:indeterminate | любой узел E, являющийся частью виджета (например, радио- или флажков), который находится в несогласованном состоянии | CSS3, CSS4 | Соответствует GTK_STATE_FLAG_INCONSISTENT; GTK+ также допускает E:inconsistent |
| E:backdrop, E:selected | любой узел E, являющийся частью виджета с соответствующим состоянием | Соответствует GTK_STATE_FLAG_BACKDROP, GTK_STATE_FLAG_SELECTED | |
| E:not(〈selector〉) | любой узел E, который не соответствует простому селектору 〈selector〉 | CSS | |
| E:dir(ltr), E:dir(rtl) | любой узел E, имеющий соответствующее направление текста | CSS4 | |
| E:drop(active) | любой узел E, являющийся активной целью перетаскивания для текущей операции перетаскивания и放下 | CSS4 | |
| E F | любой узел F, который является потомком узла E | CSS | |
| E > F | любой узел F, который является потомком узла E | CSS | |
| E ~ F | любой узел F, который предшествует узлу E | CSS | |
| E + F | любой узел F, который непосредственно предшествует узлу E | CSS |
〈nth-child〉 = even | odd | 〈integer〉 | 〈integer〉n | 〈integer〉n [ + | - ] 〈integer〉
Чтобы узнать больше о селекторах в CSS, прочтите модуль «Селекторы» спецификации CSS.
Цвета
CSS позволяет задавать цвета различными способами, используя числовые значения или имена из предварительно определённого списка цветов.
〈color〉 = currentColor | transparent | 〈color name〉 | 〈rgb color〉 | 〈rgba color〉 | 〈hex color〉 | 〈gtk color〉
〈rgb color 〉 = rgb( 〈number〉, 〈number〉, 〈number〉 ) | rgb( 〈percentage〉, 〈percentage〉, 〈percentage〉 )
〈rgba color 〉 = rgba(〈number〉, 〈number〉, 〈number〉, 〈alpha value〉) | rgba( 〈percentage〉, 〈percentage〉, 〈percentage〉, 〈alpha value〉 )
〈hex color〉 = #〈hex digits〉
〈alpha value〉 = 〈number〉, ограниченные значениями от 0 до 1
Ключевое слово currentColor разрешает текущее значение свойства color при использовании в другом свойстве, а при использовании в самом свойстве color разрешает унаследованное значение свойства color.
Ключевое слово transparent можно рассматривать как сокращение для rgba(0,0,0,0).
Список допустимых имён цветов и дополнительную информацию о цветах в CSS см. в модуле «Цвет» спецификации CSS.
Пример 24. Задание цветов различными способами
GTK+ добавляет несколько дополнительных способов задания цветов.
〈gtk color〉 = 〈symbolic color〉 | 〈color expression〉| 〈win32 color〉
Первый — ссылка на цвет, определённый с помощью правила @define-color. Синтаксис правил @define-color следующий:
〈define color rule〉 = @define-color 〈name〉 〈color〉
Для ссылки на цвет, определённый с помощью правила @define-color, используйте имя из правила, префикс которого является @.
〈symbolic color〉 = @〈name〉
Пример 25. Пример определения цветов
GTK+ также позволяет формировать выражения цветов, которые могут быть вложенными и обеспечивают богатый язык для определения цветов, которые выводятся из набора основных цветов.
〈color expression〉 = lighter(〈color〉) | darker(〈color〉) | shade(〈number〉,〈color〉) | alpha(〈number〉,〈color〉) | mix(〈number〉,〈color〉,〈color〉)
В Windows GTK+ позволяет ссылаться на системные цвета следующим образом:
〈win32 color〉 = -gtk-win32-color( 〈name〉, 〈integer〉)
Изображения
CSS позволяет задавать изображения различными способами, для фона и границ.
〈image〉 = 〈url〉 | 〈crossfade〉 | 〈alternatives〉 | 〈gradient〉 | 〈gtk image〉
〈crossfade〉 = cross-fade( 〈percentage〉, 〈image〉, 〈image〉)
〈alternatives〉 = image([ 〈image〉, ]* [ 〈image〉 | 〈color〉 ])
〈gradient〉 = 〈linear gradient〉 | 〈radial gradient〉
〈linear gradient〉 = [ linear-gradient | repeating-linear-gradient ] (
[ [ 〈angle〉 | to 〈side or corner〉 ] , ]?
〈color stops〉 )
〈radial gradient〉 = [ radial‑gradient | repeating‑radial‑gradient ] (
[ [ 〈shape〉 || 〈size〉 ] [ at 〈position〉 ]? , | at 〈position〉, ]?
〈color stops〉 )
〈side or corner〉 = [ left | right ] || [ top | bottom ]
〈color stops〉 = 〈color stop〉 [ , 〈color stop〉]+
〈color stop〉 = 〈color〉 [ 〈percentage〉 | 〈length〉 ]?
〈shape〉 = circle | ellipse
〈size〉 = 〈extent keyword〉 | 〈length〉 | [ 〈length〉 | 〈percentage〉 ]{1,2} 〈extent keyword〉 = closest-size | farthest-side | closest-corner | farthest-corner
Наиболее простой способ задать изображение в CSS — это загрузить файл изображения из URL. CSS не определяет какие форматы файлов поддерживаются; в GTK+ вы можете ожидать, что будут работать форматы PNG, JPEG и SVG. Полный список поддерживаемых форматов изображений определяется доступными загрузчиками изображений gdk-pixbuf и может отличаться в зависимости от системы.
Пример 26. Загрузка файла изображения
Переход с плавным затемнением позволяет задать изображение как промежуточное значение между двумя изображениями. Переходы с плавным затемнением определяются в черновике модуля изображений уровня 4 Image спецификации CSS.
Пример 27. Переход с плавным затемнением двух изображений
Синтаксис image() предоставляет способ задать резервные варианты в случае, если формат изображения может не поддерживаться. Можно указать несколько резервных изображений, и они будут перебираться по очереди до тех пор, пока одно из них не будет успешно загружено. Последний резервный вариант может быть цветом, который будет отображен как изображение сплошного цвета.
Пример 28. Резервное изображение
Градиенты — это изображения, которые плавно переходят от одного цвета к другому. CSS предоставляет способы задать повторяющиеся и не повторяющиеся линейные и радиальные градиенты. Радиальные градиенты могут быть круговыми или ориентированными вдоль осей эллипсами. В дополнение к градиентам CSS, GTK+ имеет собственные расширения -gtk-gradient.
Линейный градиент создается путем указания линии градиента и затем нескольких цветов, размещенных вдоль этой линии. Линия градиента может быть задана с помощью угла или с помощью ключевых слов направления.
Пример 29. Линейные градиенты
Радиальный градиент создается путем указания центральной точки и одного или двух радиусов. Радиусы могут быть заданы явно как длины или проценты или косвенно, с помощью ключевых слов, которые определяют, как конечная окружность или эллипс должны быть размещены относительно области, в которой они отрисовываются.
Пример 30. Радиальные градиенты
Чтобы узнать больше о градиентах в CSS, включая подробности о том, как размещаются точки цвета на линии градиента и ключевые слова для задания размеров радиусов, вы можете прочитать модуль Image спецификации CSS.
GTK+ расширяет синтаксис CSS для изображений и также использует его для задания иконок.
〈gtk image〉 = 〈gtk gradient〉 | 〈themed icon〉 | 〈scaled image〉 | 〈recolored image〉 | 〈win32 theme part〉
GTK+ поддерживает альтернативный синтаксис для линейных и радиальных градиентов (который был реализован до поддержки градиентов CSS).
〈gtk gradient〉 = 〈gtk linear gradient〉 | 〈gtk radial gradient〉
〈gtk linear gradient〉 = -gtk-gradient(linear,
[ 〈x position〉 〈y position〉 , ]{2} 〈gtk color stops〉 )
〈gtk radial gradient〉 = -gtk-gradient(radial,
[ 〈x position〉 〈y position〉 , 〈radius〉 , ]{2} 〈gtk color stops〉 )
〈x position〉 = left | right | center | 〈number〉
〈y position〉 = top | bottom | center | 〈number〉
〈radius 〉 = 〈number〉
〈gtk color stops〉 = 〈gtk color stop〉 [ , 〈gtk color stop〉 ]+
〈gtk color stop〉 = color-stop( 〈number〉 , 〈color〉 ) | from( 〈color〉 ) | to( 〈color〉 )
Числа, используемые для задания позиций x и y, радиусов, а также позиций точек цвета, должны находиться в диапазоне от 0 до 1. Ключевые слова для позиций x и y (left, right, top, bottom, center) соответствуют числовым значениям 0, 1 и 0,5 в очевидном порядке. Точки цвета, использующие синтаксис from() и to(), являются сокращениями для точек цвета с числовыми позициями 0 и 1 соответственно.
Пример 31. Линейные градиенты
Пример 32. Радиальные градиенты
GTK+ имеет широкую поддержку загрузки иконок из тем иконок. К ней можно обратиться из CSS с помощью синтаксиса -gtk-icontheme.
〈themed icon〉 = -gtk-icontheme( 〈icon name〉 )
Указанное имя иконки используется для поиска тематической иконки, при этом учитываются значения свойств -gtk-icon-theme и -gtk-icon-palette. Этот тип изображения используется в основном как значение свойства -gtk-icon-source.
Пример 33. Использование тематических иконок в CSS
GTK+ поддерживает масштабирование при отображении на дисплеях с высоким разрешением. Это работает наилучшим образом, если изображения могут указывать варианты для обычного и высокого разрешения. Из CSS это можно сделать с помощью синтаксиса -gtk-scaled.
〈scaled image〉 = -gtk-scaled( 〈image〉[, 〈image〉]* )
Хотя -gtk-scaled принимает несколько вариантов более высокого разрешения, на практике он в основном будет использоваться для указания обычного изображения и одного варианта для масштаба 2.
Пример 34. Масштабируемые изображения в CSS
〈recolored image〉 = -gtk-recolored( 〈url〉[, 〈color palette〉] )
Символьные иконки из темы иконок перекрашиваются в соответствии со свойством -gtk-icon-palette. Перекраска иногда необходима для изображений, которые не являются частью темы иконок, и синтаксис -gtk-recolor делает это доступным. -gtk-recolor требует URL в качестве первого аргумента. Остальные аргументы задают цветовую палитру для использования. Если палитра не указана явно, используется текущее значение свойства -gtk-icon-palette.
Пример 35. Перекраска изображения
В Windows GTK+ позволяет ссылаться на части системной темы как на изображения следующим образом:
〈win32 theme part〉 = -gtk-win32-theme-part( 〈name〉, 〈integer〉 〈integer〉
[, [ over( 〈integer〉 〈integer〉 [ , 〈alpha value〉]? ) | margins( 〈integer〉{1,4} ) ] ]* ) Переходы
CSS определяет механизм, посредством которого изменения значений свойств CSS могут быть выполнены постепенно, а не сразу. GTK+ также поддерживает эти переходы.
Чтобы включить переход для свойства, когда набор правил вступает в силу, его необходимо перечислить в свойстве transition-property в этом наборе правил. Только анимируемые свойства могут быть перечислены в transition-property.
Подробности перехода можно изменить с помощью свойств transition-duration, transition-timing-function и transition-delay.
Чтобы узнать больше о переходах, вы можете прочитать модуль Переходы спецификации CSS.
Анимации
Помимо переходов, которые запускаются изменениями базового дерева узлов, CSS также поддерживает определенные анимации. В то время как переходы задают, как значения свойств изменяются от одного значения к новому, анимации явно определяют промежуточные значения свойств в ключевых кадрах.
Ключевые кадры определяются с помощью правила @-rule, которое содержит один или несколько наборов правил со специальными селекторами. Декларации свойств для неанимируемых свойств игнорируются в этих наборах правил (за исключением свойств анимации).
〈keyframe rule〉 = @keyframes 〈name〉 { 〈animation rule〉 } 〈animation rule〉 = 〈animation selector〉 { 〈declaration〉* } 〈animation selector〉 = 〈single animation selector〉 [ , 〈single animation selector ]*
〈single animation selector〉 = from | to | 〈percentage〉
Чтобы включить анимацию, имя ключевых кадров должно быть задано как значение свойства animation-name. Подробности анимации можно изменить с помощью свойств animation-duration, animation-timing-function, animation-iteration-count и других свойств анимации.
Пример 36. Анимация CSS
Чтобы узнать больше об анимациях, вы можете прочитать модуль Анимации спецификации CSS.
Связывание клавиш
Для расширения связывания клавиш, влияющих на различные виджеты, GTK+ поддерживает правило @binding-set для анализа набора директив bind/unbind. Обратите внимание, что для того, чтобы они подействовали, наборы связей, определенные таким образом, должны быть связаны с наборами правил путем задания свойства -gtk-key-bindings.
Синтаксис правил @binding-set следующий:
〈binding set rule〉 = @binding-set 〈binding name〉{ [ [ 〈binding〉 | 〈unbinding〉] ; ]* } 〈binding〉 = bind "〈accelerator〉" { 〈signal emission〉* } 〈signal emission〉 = "〈signal name〉" ( [ 〈argument〉[ , 〈argument〉]* ]? }
〈unbinding〉 = unbind "〈accelerator〉" ;
где 〈accelerator〉 — это строка, которую можно проанализировать с помощью gtk_accelerator_parse(), 〈имя сигнала〉 — это имя сигнала связывания клавиш интересующего виджета, а список 〈аргумент〉 должен соответствовать декларации сигналов.
Пример 37. Пример использования правила @binding-set
scale[.fine-tune]
├── marks.top
│ ├── mark
┊ ┊
│ ╰── mark
├── trough
│ ├── slider
│ ├── [highlight]
│ ╰── [fill]
╰── marks.bottom
├── mark
┊
╰── mark
© 2005–2020 The GNOME Project
Licensed under the GNU Lesser General Public License version 2.1 or later.
https://developer.gnome.org/gtk3/3.22/chap-css-overview.html