
🔘 Шорткод кнопки в WordPress: готовый PHP-код и современный CSS 2026
Нужна кнопка «Скачать» посреди статьи, а тема выводит только синюю ссылку с подчёркиванием. Знакомо? В Block Editor кнопка добавляется кликом, но в классическом редакторе, в виджетах и в кастомных темах каждый раз приходится вручную писать HTML с классами.
Копирование разметки из поста в пост заканчивается предсказуемо: в одном месте забыли класс, в другом потеряли rel="noopener", в третьем кнопка внезапно другого оттенка. Чем больше материалов на сайте, тем дороже обходится каждая правка стиля.
Решение занимает минут десять. Дальше вас ждёт готовый PHP-шорткод [button], палитра на OKLCH, тёмная тема через light-dark() и доступность по WCAG 2.2. Всё проверено на актуальных браузерах 2026 года.
Как добавить кнопку через шорткод: план действий
💡 Быстрый обзор:
- Шаг 1: Добавьте PHP-функцию кнопки в
functions.phpдочерней темы - Шаг 2: Зарегистрируйте тег
[button]черезadd_shortcode()на хукеinit - Шаг 3: Подключите CSS со всеми состояниями: базовый вид, наведение, нажатие, фокус
- Шаг 4: Задайте цветовые схемы одной строкой OKLCH на каждый цвет
- Шаг 5: Вставьте
[button url="..." color="blue"]Текст[/button]в запись и проверьте фокус с клавиатуры
Каждый шаг ниже разобран с готовым кодом, который можно копировать целиком. Код кладите в дочернюю тему: обновление родительской тогда не сотрёт ваши правки. Если дочерней темы ещё нет, сначала создайте её по официальному руководству WordPress по child themes, это дело на несколько минут.
Но прежде чем копировать, посмотрите, что изменилось в самой стилизации. За последние годы CSS для кнопок переписали почти полностью.
Что изменилось в CSS для кнопок к 2026 году
Коротко: кнопку больше не собирают из вендорных префиксов и трёх наборов ручных hover-оттенков. Кастомные свойства, нативная вложенность, цветовая модель OKLCH и функция light-dark() сокращают типичный блок стилей примерно вдвое и убирают дублирование.
Масштаб применения у этих приёмов огромный. По данным W3Techs на июль 2026 года WordPress работает на 41,5% всех сайтов и держит 59,2% рынка CMS. Любой паттерн из этой статьи вы сможете переносить с проекта на проект годами.
Приём | Как делали раньше | Как делают в 2026 |
|---|---|---|
Цвет | HEX плюс ручные оттенки на hover и active |
|
Палитра | Девять CSS-правил на каждый цвет | Одна строка с переопределением |
Префиксы |
| Не нужны: свойства давно в стандарте |
Вложенность | Только через Sass или Less | Нативный CSS nesting |
Фокус |
|
|
Тёмная тема | Отдельная таблица стилей |
|
Начнём с серверной части: пока нет PHP-функции, стилизовать нечего.
PHP-функция кнопки
Функция принимает атрибуты из редактора и возвращает готовый тег <a> с классами, ссылкой и текстом. Шорткоды появились ещё в WordPress 2.5 и до сих пор остаются самым быстрым способом вставить произвольную разметку в контент: add_shortcode() из официального справочника регистрирует тег, а callback собирает HTML.
1 /** 2 * Генерирует HTML кнопки через шорткод [button]. 3 * 4 * @param array|string $atts Атрибуты шорткода. 5 * @param string|null $content Текст внутри парного тега [button]...[/button]. 6 * @return string HTML разметка кнопки. 7 */ 8 function myprefix_button_shortcode( $atts, $content = null ) { 9 $atts = shortcode_atts( 10 array( 11 'url' => '', 12 'title' => '', 13 'target' => '', 14 'text' => '', 15 'color' => 'green', 16 ), 17 $atts, 18 'button' 19 ); 20 21 // Текст кнопки: приоритет у атрибута text, затем содержимое тега 22 $label = $atts['text'] ? $atts['text'] : $content; 23 24 // Ссылка задана: формируем <a> 25 if ( $atts['url'] ) { 26 $target_attr = ( 'blank' === $atts['target'] ) ? ' target="_blank" rel="noopener noreferrer"' : ''; 27 $title_attr = $atts['title'] ? ' title="' . esc_attr( $atts['title'] ) . '"' : ''; 28 29 return sprintf( 30 '<a href="%s" class="myprefix-button color-%s"%s%s>%s</a>', 31 esc_url( $atts['url'] ), 32 esc_attr( $atts['color'] ), 33 $target_attr, 34 $title_attr, 35 do_shortcode( $label ) 36 ); 37 } 38 39 // Ссылки нет: оборачиваем в <span> 40 return sprintf( 41 '<span class="myprefix-button color-%s">%s</span>', 42 esc_attr( $atts['color'] ), 43 do_shortcode( $label ) 44 ); 45 }
Обратите внимание на три детали. shortcode_atts() сливает переданные атрибуты с значениями по умолчанию, поэтому в области видимости нет ни extract(), ни необъявленных переменных. Все динамические значения проходят через esc_url() и esc_attr(): WordPress не экранирует вывод шорткодов за вас. А do_shortcode() внутри подписи позволяет вкладывать один шорткод в другой, например иконку внутрь кнопки.
Регистрация шорткода и вызов в редакторе
Регистрацию вешаем на хук init: к этому моменту ядро полностью загружено, и другие плагины при необходимости смогут переопределить тег через remove_shortcode().
1 add_action( 'init', 'myprefix_register_button_shortcode' ); 2 3 function myprefix_register_button_shortcode() { 4 add_shortcode( 'button', 'myprefix_button_shortcode' ); 5 }
Теперь откройте запись и вставьте тег. В классическом редакторе прямо в текст, в Block Editor через блок «Шорткод»:
1 [button url="https://example.com/download" target="blank" text="Скачать бесплатно"] 2 3 [button url="https://example.com" color="blue"]Подробнее[/button]
Первый вариант самозакрывающийся, с текстом в атрибуте. Второй парный: подпись стоит между открывающим и закрывающим тегами. Результат одинаковый, выбирайте тот синтаксис, который удобнее авторам.
Без стилей кнопка пока выглядит как обычная ссылка. Механика при этом уже работает: класс myprefix-button color-green в разметке есть, осталось его оформить.
Базовые стили: кастомные свойства и вложенность
Весь внешний вид держится на одной переменной --btn-bg. Оттенки для наведения и нажатия из неё вычисляет color-mix(), поэтому ручной подбор тёмных вариантов больше не нужен. Вложенные правила работают нативно, без Sass.
1 .myprefix-button { 2 --btn-bg: oklch(58% 0.15 145); 3 --btn-fg: #fff; 4 5 display: inline-block; 6 padding: 12px 24px; 7 background: var(--btn-bg); 8 color: var(--btn-fg); 9 font-weight: 600; 10 text-decoration: none; 11 border-radius: 8px; 12 cursor: pointer; 13 transition: background 0.2s ease, translate 0.15s ease; 14 15 &:hover { 16 background: color-mix(in oklch, var(--btn-bg), black 12%); 17 color: var(--btn-fg); 18 text-decoration: none; 19 } 20 21 &:active { 22 background: color-mix(in oklch, var(--btn-bg), black 20%); 23 translate: 0 1px; 24 } 25 26 &:focus-visible { 27 outline: 3px solid color-mix(in oklch, var(--btn-bg), white 30%); 28 outline-offset: 2px; 29 } 30 }
Сдвиг translate: 0 1px на нажатии имитирует физическую кнопку тоньше, чем старый приём с внутренней тенью. Плавность переходов задаёт transition, а цвет текста продублирован на :hover явно, чтобы стили темы его не перебили.
Скопируйте блок в style.css дочерней темы или в раздел «Дополнительные стили» настройщика. Дальше самое приятное: цветовые схемы.
Палитра на OKLCH: новый цвет одной строкой
Каждая схема теперь занимает ровно одну строку: меняется только переменная, все состояния пересчитываются автоматически.
1 .myprefix-button.color-blue { --btn-bg: oklch(55% 0.17 255); } 2 .myprefix-button.color-red { --btn-bg: oklch(55% 0.19 25); } 3 .myprefix-button.color-orange { --btn-bg: oklch(68% 0.16 60); }
Почему именно OKLCH, а не привычный HEX. В описании oklch() на MDN первым параметром идёт воспринимаемая светлота: два цвета с одинаковым первым числом выглядят одинаково яркими. Синяя и красная кнопки из примера выше визуально равнозначны, у HEX такой гарантии нет. Подбирать новые схемы удобно, меняя только третий параметр, тон.
Вызов в редакторе не меняется: color="red" включает красную схему, color="orange" оранжевую. Атрибут по умолчанию оставлен зелёным, как в исходной функции.

Доступность: то, что чаще всего ломают
Прямой ответ: кнопке нужны видимый фокус, достаточный размер цели и уважение к настройкам анимации. Это не рекомендации «для галочки». Аудит 17,2 млн сайтов в Web Almanac 2025 показал, что 67% сайтов убирают обводку фокуса, а контраст по WCAG выдерживают только 30%.
Правовая рамка тоже ужесточилась: с 28 июня 2025 года применяется European Accessibility Act, и требования доступности для цифровых продуктов в ЕС стали юридической нормой, а не пожеланием.
Критерий 2.5.8 Target Size (Minimum) уровня AA из WCAG 2.2 требует, чтобы интерактивная цель занимала не менее 24 на 24 CSS-пикселя либо имела эквивалентный свободный отступ вокруг.
Наша кнопка с padding: 12px 24px проходит минимум с запасом, но два правила стоит добавить отдельно:
1 .myprefix-button { 2 min-block-size: 44px; 3 align-content: center; 4 } 5 6 @media (prefers-reduced-motion: reduce) { 7 .myprefix-button { 8 transition: none; 9 } 10 }
Первое правило дотягивает высоту до комфортной зоны касания на мобильных, где промахи по мелким целям особенно раздражают. Второе отключает анимации для людей, которые попросили об этом в настройках системы. Обводку фокуса мы уже задали через :focus-visible: она появляется при навигации с клавиатуры и не мешает пользователям мыши.

Тёмная тема через light-dark()
Одна функция заменяет медиазапрос prefers-color-scheme целиком. Указываете два значения, светлое и тёмное, а браузер сам выбирает нужное по активной схеме. По справке MDN функция light-dark() имеет статус Baseline Newly available с мая 2024 года, то есть работает во всех актуальных браузерах.
1 :root { 2 color-scheme: light dark; 3 } 4 5 .myprefix-button { 6 --btn-bg: light-dark(oklch(58% 0.15 145), oklch(70% 0.13 145)); 7 --btn-fg: light-dark(#fff, oklch(22% 0.02 145)); 8 }
Строка color-scheme: light dark обязательна: без неё функция не активируется. Для тёмной схемы фон сделан светлее, а текст тёмным: на тёмном полотне насыщенные тёмные кнопки проваливаются, это типовая ошибка. Подробный разбор темизации со всеми подводными камнями есть в материале web.dev о цветовых темах.
Если ваша аудитория сидит на старых корпоративных браузерах, заверните новинки в @supports и оставьте обычный HEX запасным значением: кнопка деградирует мягко, теряя только точность оттенков.
Безопасность: три строки, о которых забывают
Сначала главное: target="_blank" без rel="noopener noreferrer" открывает tabnabbing-уязвимость. Страница, на которую ведёт кнопка, получает доступ к window.opener и может подменить вкладку с вашим сайтом. В нашей функции атрибут добавляется автоматически, но при доработках его легко потерять.
Экранирование не менее важно. esc_url() отсекает опасные протоколы вроде javascript:, а esc_attr() не даёт вырваться из атрибута. Убирать эти вызовы ради краткости нельзя ни в одном шорткоде, который принимает данные из редактора.
И последнее: содержимое $content намеренно не прогоняется через wp_kses_post(), чтобы работали вложенные шорткоды. Если же вы разрешите вставлять кнопки через формы с фронтенда, оберните $label в wp_kses_post() перед выводом.
Как проверить кнопку перед публикацией
Быстрая проверка занимает пару минут и ловит почти все проблемы, с которыми потом приходят читатели. Пройдитесь по списку до того, как ставить кнопку в рабочие записи:
- Кликните по кнопке мышью и убедитесь, что ссылка открывается в нужной вкладке.
- Пройдите страницу клавишей Tab: обводка фокуса должна быть заметна с первого взгляда.
- Включите эмуляцию тёмной схемы в DevTools (панель Rendering, пункт prefers-color-scheme) и посмотрите оба варианта фона.
- Там же включите эмуляцию prefers-reduced-motion и убедитесь, что кнопка перестала анимироваться.
- Откройте страницу в мобильном режиме и попробуйте попасть по кнопке большим пальцем.
Если все пункты прошли, шорткод готов к массовому использованию. Заведите привычку гонять этот список после каждой правки стилей: регрессии в состояниях фокуса и тёмной темы глазами не видны, пока специально не посмотришь. А самые частые вопросы о работе шорткода собраны ниже.
⁉️🤔 Частые вопросы
Работает ли такой шорткод в Block Editor?
Да, полностью. Вставьте блок «Шорткод» и внутри строку
[button ...]. Разметка собирается на сервере при выводе записи, поэтому редактору всё равно, каким способом тег попал в контент. Для часто используемых элементов со временем имеет смысл зарегистрировать нативный блок черезregister_block_type(), но это отдельный проект.
Что делать, если браузер посетителя не понимает oklch() или light-dark()?
Заверните современные значения в директиву
@supportsи оставьте обычный HEX как значение по умолчанию. Старый браузер применит запасной цвет, новый возьмёт OKLCH. Кнопка останется рабочей в обоих случаях: мягкая деградация затрагивает только точность оттенков и автоматику тёмной темы, а не функциональность.
Почему шорткод выводится на странице как текст в квадратных скобках?
Чаще всего функция не зарегистрирована: проверьте, что
functions.phpсохранился без синтаксических ошибок и хукinitсработал. Второй вариант: вы вставили тег в файл шаблона, а там нужен явный вызовecho do_shortcode( '[button ...]' ). ВключитеWP_DEBUGи посмотрите лог ошибок.
Как добавить иконку внутрь кнопки?
Самый быстрый путь: эмодзи прямо в тексте, например
text="📥 Скачать". Для SVG передайте адрес файла отдельным атрибутом и выведите тег<img>внутри ссылки через тот жеsprintf. Вариант с набором Dashicons тоже рабочий: псевдоэлемент::beforeплюсfont-family: dashiconsв отдельном классе.
Нужны ли в 2026 году вендорные префиксы для border-radius и transition?
Нет. Эти свойства давно в стандарте и работают во всех актуальных браузерах без префиксов. Поддержку конкретной новинки удобно проверять по таблицам MDN или на caniuse.com: там же виден статус Baseline, который подсказывает, когда функцию можно применять без запасных вариантов.
💎 Итоги и выводы
Для сайта, где нужна пара типовых кнопок, свой шорткод выигрывает у любого плагина: полный контроль над разметкой, ноль лишних скриптов в очереди загрузки и ни одной зависимости, которую придётся обновлять. Визуальный конструктор с десятками готовых стилей нужен реже, чем кажется, но если без него никак, смотрите MaxButtons из каталога wordpress.org.
Практический лайфхак: начните внедрение со строки color-scheme: light dark в :root и переменных через light-dark(). Это самый дешёвый способ получить честную тёмную тему, который окупается на каждом следующем элементе интерфейса. И подводный камень напоследок: проверяйте кнопку не только мышью. Пройдите страницу клавишей Tab и убедитесь, что обводка фокуса видна, иначе часть посетителей просто не найдёт вашу кнопку.
Забирайте код, вставляйте в дочернюю тему и проверьте кнопку на своём сайте прямо сегодня. Получилось или упёрлись в конфликт с темой? Расскажите в комментариях, разберём вместе. И подпишитесь на обновления блога: впереди разборы других полезных шорткодов.



