12k
All articles

Что входит в файл theme.json в WordPress

Узнайте, что входит в файл WordPress theme.json, как settings и styles создают CSS-переменные и как работают пресеты, пользовательский CSS и дочерние темы.

OpenReplay Team
OpenReplay Team
Что входит в файл theme.json в WordPress

Файл theme.json — это JSON-файл в корне блочной темы WordPress. В нём один раз объявляются дизайн-токены темы: цвета, размеры шрифтов, семейства шрифтов, отступы и ширина макета. Редактор блоков и фронтенд читают из него одни и те же значения.

Если вы работали с пайплайнами дизайн-токенов, файл покажется знакомым. Вопросы появятся, когда вы начнёте искать сгенерированный из него CSS или выяснять, почему дочерняя тема стёрла половину палитры. В этой статье мы разберём каждую часть файла, покажем CSS, который WordPress из неё генерирует, объясним, как использовать эти переменные в собственной таблице стилей, и расскажем, где без написанного вручную CSS по-прежнему не обойтись. Во всех примерах используется третья версия схемы, появившаяся в WordPress 6.6.

Ключевые выводы

  • У theme.json два основных ключа верхнего уровня. settings определяет, какие элементы управления и пресеты доступны в редакторе. styles задаёт значения по умолчанию для страницы, HTML-элементов и отдельных блоков.
  • Каждый пресет, кроме фильтров duotone, превращается в пользовательское свойство CSS вида --wp--preset--{category}--{slug}. Например, цвет палитры со слагом ink доступен в любой таблице стилей как var(--wp--preset--color--ink).
  • Значения из settings.custom становятся свойствами --wp--custom--*. При этом camelCase преобразуется в kebab-case, а уровни вложенности разделяются двойным дефисом.
  • theme.json дочерней темы объединяется с родительским и переопределяет его, но любой объявленный в нём список пресетов полностью заменяет соответствующий список родительской темы.

Что такое theme.json?

theme.json — это файл дизайн-токенов блочной темы. Цвета, типографика, отступы и ширина макета объявляются в нём один раз. Затем WordPress использует эти значения, чтобы построить элементы управления в редакторе и сгенерировать таблицу стилей для фронтенда. Ключей верхнего уровня немного: $schema, version, settings и styles. Кроме них есть customTemplates, templateParts и patterns для регистрации шаблонов, частей шаблонов и паттернов из каталога паттернов (Pattern Directory).

{
  "$schema": "https://schemas.wp.org/trunk/theme.json",
  "version": 3,
  "settings": {},
  "styles": {}
}

Если указать в $schema ссылку на схему theme.json из trunk, в VS Code заработают автодополнение и валидация.

Зачем нужен theme.json?

theme.json объединяет три вещи, которые раньше постоянно расходились между собой: флаги add_theme_support() в PHP, настройки редактора и CSS для фронтенда. В руководстве по глобальным настройкам из Block Editor Handbook для каждого старого флага add_theme_support указан соответствующий ключ theme.json. Если тема задаёт одно и то же в обоих местах, приоритет получает значение из theme.json.

add_theme_supportЭквивалент в theme.json
editor-color-palettesettings.color.palette
editor-font-sizessettings.typography.fontSizes
disable-custom-colorssettings.color.custom: false
custom-unitssettings.spacing.units
appearance-toolssettings.appearanceTools: true

Что входит в settings?

settings определяет, что предлагает редактор: какие пресеты отображаются в палитрах и меню выбора и какие произвольные элементы управления разрешены. Пресеты — это массивы объектов, у каждого из которых есть slug, значение и отображаемое имя name.

{
  "$schema": "https://schemas.wp.org/trunk/theme.json",
  "version": 3,
  "settings": {
    "appearanceTools": true,
    "color": {
      "custom": false,
      "customGradient": false,
      "defaultPalette": false,
      "palette": [
        { "slug": "ink", "color": "#1b1f24", "name": "Ink" },
        { "slug": "accent", "color": "#3b5bdb", "name": "Accent" }
      ]
    },
    "typography": {
      "customFontSize": false,
      "defaultFontSizes": false,
      "fontSizes": [
        { "slug": "small", "size": "0.875rem", "name": "Small" },
        { "slug": "large", "size": "1.5rem", "name": "Large" }
      ],
      "fontFamilies": [
        { "slug": "system", "fontFamily": "-apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif", "name": "System" }
      ]
    },
    "spacing": { "blockGap": true, "units": ["px", "rem", "%"] },
    "layout": { "contentSize": "720px", "wideSize": "1100px" },
    "custom": { "radius": { "card": "12px" } }
  }
}

Если установить color.custom, customGradient и customFontSize в false, произвольные средства выбора исчезнут, и редакторы смогут выбирать только из ваших пресетов. В версии 3 важен параметр defaultFontSizes: false. В заметке для разработчиков о theme.json версии 3 объясняется, что тема v3 может повторно использовать слаги размеров шрифтов и отступов из ядра, только если defaultFontSizes или defaultSpacingSizes установлены в false. А small и large — как раз слаги ядра. Параметр appearanceTools: true включает набор инструментов оформления, перечисленных в актуальном справочнике по theme.json. Если вы подключаете веб-шрифты для fontFamilies, прочитайте, как разместить Google Fonts на собственном сервере в WordPress.

Каждый тип пресетов даёт свой результат:

КлючЧто генерирует
color.paletteОдно пользовательское свойство и три класса (цвет текста, фона и рамки)
typography.fontSizesОдно пользовательское свойство и один класс
typography.fontFamiliesОдно пользовательское свойство и один класс
spacing.spacingSizesТолько одно пользовательское свойство
customСвойства --wp--custom--*
color.custom, customFontSizeТолько интерфейс редактора, без CSS

В theme.json есть два никак не связанных между собой ключа custom. settings.color.custom: false скрывает палитру выбора цвета. settings.custom — это объект произвольной структуры, значения которого становятся переменными CSS.

Как работают layout.contentSize и wideSize?

layout.contentSize задаёт ширину контента по умолчанию внутри ограниченных макетов (constrained layout). layout.wideSize задаёт ширину блоков с выравниванием «по ширине» (wide). Ядро предоставляет оба значения как --wp--style--global--content-size и --wp--style--global--wide-size на :root: Gutenberg PR #42084 перенёс туда глобальные пользовательские свойства с body. Благодаря этому собственные компоненты можно выравнивать по сетке блоков:

.site-banner {
  max-width: var(--wp--style--global--wide-size);
  margin-inline: auto;
}

Что входит в styles?

styles задаёт значения по умолчанию на трёх уровнях. Свойства верхнего уровня применяются к body. elements применяются к HTML-элементам, например link (соответствует a) и h1–h6. blocks применяются к отдельным блокам по их имени. Каждый уровень описан в разделе Handbook о стилях.

{
  "$schema": "https://schemas.wp.org/trunk/theme.json",
  "version": 3,
  "styles": {
    "color": { "text": "var(--wp--preset--color--ink)" },
    "spacing": { "blockGap": "1.5rem" },
    "blocks": {
      "core/group": {
        "color": { "text": "var(--wp--preset--color--accent)" },
        "elements": {
          "h2": { "typography": { "fontSize": "var(--wp--preset--font-size--large)" } }
        }
      }
    }
  }
}

Результат:

body {
  color: var(--wp--preset--color--ink);
}
:root :where(.wp-block-group) {
  color: var(--wp--preset--color--accent);
}
:root :where(.wp-block-group h2) {
  font-size: var(--wp--preset--font-size--large);
}

Начиная с WordPress 6.6, обёртка :root :where() удерживает специфичность этих правил на уровне 0-1-0, как у одного класса. Любое правило темы с такой же или более высокой специфичностью, загруженное позже, перекрывает их. Элементы link и button также поддерживают ключи псевдосостояний, например ":hover" и ":focus".

Какой CSS WordPress генерирует из theme.json?

Каждый пресет, кроме фильтров duotone, превращается в пользовательское свойство CSS вида --wp--preset--{category}--{slug}. Пресеты, генерирующие классы, следуют шаблону .has-{slug}-{category}. Значения из settings.custom становятся свойствами --wp--custom--. WordPress преобразует ключи в camelCase в kebab-case и разделяет уровни вложенности символами --, так что custom.lineHeight.body превращается в --wp--custom--line-height--body. В разделе FAQ об именовании в Handbook имя разбирается по сегментам.

Для приведённых выше settings и styles глобальная таблица стилей будет содержать примерно такой код. В примерах из Handbook указан body, но в актуальной версии ядра эти свойства объявляются на :root. Это изменение внесено в Gutenberg PR #42084:

:root {
  --wp--preset--color--ink: #1b1f24;
  --wp--preset--color--accent: #3b5bdb;
  --wp--preset--font-size--large: 1.5rem;
  --wp--custom--radius--card: 12px;
  --wp--style--block-gap: 1.5rem;
}
.has-accent-color { color: var(--wp--preset--color--accent) !important; }

Корневое значение styles.spacing.blockGap доступно как --wp--style--block-gap. Смогут ли редакторы его изменять, зависит от settings.spacing.blockGap:

ЗначениеЭлемент управления отступами между блокамиВывод стилей отступов
trueОтображаетсяДа
falseСкрытДа, значения из theme.json по-прежнему применяются
null (по умолчанию)СкрытНет

Это обычные пользовательские свойства, поэтому их можно использовать в любой таблице стилей:

.pricing-card {
  background: var(--wp--preset--color--ink);
  color: #fff;
  border-radius: var(--wp--custom--radius--card);
  padding: var(--wp--style--block-gap);
  font-size: var(--wp--preset--font-size--large);
}

Если изменить токен в theme.json, этот компонент обновится вместе с ним. Вывод theme.json кешируется, поэтому на время разработки установите в wp-config.php значение WP_DEVELOPMENT_MODE равным 'theme'.

Чего не умеет theme.json и как объединяются дочерние темы?

theme.json охватывает только свойства, описанные в его схеме стилей. Всё остальное пишется на CSS:

  • Макет для разметки, которая не является блоком, например вывода плагинов или сторонних сервисов
  • Анимации, переходы и ключевые кадры
  • Произвольные селекторы, не привязанные к блоку или элементу
  • Стилизация компонентов, выходящая за рамки доступных свойств стилей (подход «сначала CSS» показан в руководстве по созданию адаптивной темы WordPress на Bootstrap)

Файл style.css по-прежнему обязателен, потому что в нём находится заголовок темы. В дочерней теме поле Template указывает на родительскую тему по имени её папки внутри wp-content/themes, написанному точно так же, как объясняется на странице об основной таблице стилей в Theme Handbook:

/*
Theme Name: Studio Child
Template: studio
*/

theme.json дочерней темы объединяется с родительским и переопределяет его, но любой объявленный в нём список пресетов полностью заменяет список родительской темы. После подключения такого дочернего файла в палитре останется только один цвет:

{
  "$schema": "https://schemas.wp.org/trunk/theme.json",
  "version": 3,
  "settings": {
    "color": {
      "palette": [
        { "slug": "accent", "color": "#c2255c", "name": "Accent" }
      ]
    }
  }
}

Чтобы изменить только accent, скопируйте палитру целиком и отредактируйте нужную запись:

{
  "$schema": "https://schemas.wp.org/trunk/theme.json",
  "version": 3,
  "settings": {
    "color": {
      "palette": [
        { "slug": "ink", "color": "#1b1f24", "name": "Ink" },
        { "slug": "accent", "color": "#c2255c", "name": "Accent" }
      ]
    }
  }
}

Ключи объектов, которые не объявлены в theme.json дочерней темы, по-прежнему наследуются от родительской. Если дочерняя тема задаёт только styles.spacing.padding.top и bottom, левый и правый отступы родительской темы сохраняются. Бывает, что из-за удалённого слага контент на рабочем сайте отображается с другим цветом, хотя в предпросмотре редактора всё в порядке. В таком случае запись сессии (session replay) фронтенда покажет, какой элемент и какой шаблон потеряли пресет.

Заключение

theme.json — это файл токенов, который WordPress компилирует в пользовательские свойства, служебные классы и правила по умолчанию с низкой специфичностью. Храните пресеты в settings, значения по умолчанию — в styles, а всё остальное — в CSS, который использует сгенерированные переменные --wp--. Следующий шаг: откройте global-styles-inline-css в инструментах разработчика браузера на странице с вашей темой и сравните объявленные свойства с содержимым файла. Отсутствующий токен указывает на ошибку в слаге или схеме, которую можно исправить до того, как её заметят пользователи.

Часто задаваемые вопросы

Почему значение, изменённое в theme.json, не отображается на сайте?

Его переопределяет сохранённая настройка из редактора сайта. Когда пользователь меняет стили в разделе «Внешний вид → Редактор», WordPress сохраняет этот JSON в базе данных сайта. Согласно Theme Handbook, пользовательская конфигурация имеет приоритет над значениями ядра по умолчанию, theme.json родительской темы и theme.json дочерней темы. Проверьте, не был ли токен изменён на панели «Стили», сбросьте его там и перезагрузите фронтенд.

Можно ли писать чистый CSS внутри theme.json?

Да. Начиная с WordPress 6.2, theme.json принимает строки CSS в styles.css для глобальных правил и в свойстве css блока внутри styles.blocks для правил отдельных блоков. CSS отдельного блока отображается для этого блока на панели «Стили», где пользователи могут его редактировать. Пользовательский CSS может переопределить или удалить CSS темы, добавленный таким способом, поэтому правила, от которых зависит дизайн, размещайте в подключаемой таблице стилей.

Может ли классическая PHP-тема использовать theme.json?

Да. Классическая тема может включать theme.json, чтобы настраивать параметры и пресеты редактора блоков без вызовов add_theme_support. В сообществе такую конфигурацию называют гибридной темой. Добавление файла не превращает тему в блочную: WordPress считает тему блочной, только если в ней есть templates/index.html. Если тема сохраняет часть вызовов add_theme_support, соответствующие настройки в theme.json имеют над ними приоритет.

Как прочитать значения theme.json в PHP?

Вызовите wp_get_global_settings() для настроек и wp_get_global_styles() для стилей. Обе функции принимают массив пути, поэтому wp_get_global_settings( array( 'color', 'palette', 'theme' ) ) вернёт только записи палитры темы. Массив контекста с ключом block_name ограничивает выборку одним блоком. По умолчанию результат включает пользовательские настройки. Чтобы получить только значения ядра и темы, укажите в массиве контекста origin со значением 'base'.

DevTools for the frontend

Gain Debugging Superpowers

Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers.

Star on GitHub12k

We use cookies to improve your experience. By using our site, you accept cookies.