Skip to content

Wszystko o WordPressie, tworzeniu stron — i nie tylko

🔘 Shortcode przycisku w WordPress: gotowy kod PHP i nowoczesny CSS 2026

🔘 Shortcode przycisku w WordPress: gotowy kod PHP i nowoczesny CSS 2026

Potrzebuje Pan przycisku „Pobierz" w środku artykułu, a motyw wyświetla tylko niebieski link z podkreśleniem. Brzmi znajomo? W Block Editorze przycisk dodaje się jednym kliknięciem, ale w klasycznym edytorze, w widgetach i w niestandardowych motywach za każdym razem trzeba ręcznie pisać HTML z klasami.

Kopiowanie znaczników z posta do posta kończy się przewidywalnie: w jednym miejscu zapomniana klasa, w innym zgubione rel="noopener", w trzecim przycisk nagle ma inny odcień. Im więcej materiałów na stronie, tym droższa staje się każda poprawka stylistyczna.

Rozwiązanie zajmuje około dziesięciu minut. Czeka na Pana gotowy PHP-shortcode [button], paleta w OKLCH, ciemny motyw przez light-dark() i dostępność zgodna z WCAG 2.2. Wszystko sprawdzone na aktualnych przeglądarkach z 2026 roku.

Jak dodać przycisk przez shortcode: plan działania

💡 Szybki przegląd:

  • Krok 1: Proszę dodać funkcję PHP przycisku w functions.php motywu potomnego
  • Krok 2: Proszę zarejestrować tag [button] przez add_shortcode() na haku init
  • Krok 3: Proszę podłączyć CSS ze wszystkimi stanami: wygląd bazowy, najechanie, kliknięcie, fokus
  • Krok 4: Proszę zdefiniować schematy kolorów jednym wierszem OKLCH na każdy kolor
  • Krok 5: Proszę wstawić [button url="..." color="blue"]Текст[/button] do wpisu i sprawdzić fokus z klawiatury

Każdy krok poniżej został rozpisany z gotowym kodem, który można skopiować w całości. Kod proszę umieszczać w motywie potomnym: aktualizacja motywu nadrzędnego nie usunie wtedy Pana poprawek. Jeśli nie ma Pan jeszcze motywu potomnego, proszę go najpierw utworzyć według oficjalnego przewodnika WordPressa po child themes, to kwestia kilku minut.

Zanim jednak zacznie Pan kopiować, proszę spojrzeć, co zmieniło się w samej stylizacji. W ostatnich latach CSS dla przycisków został przepisany niemal całkowicie.

Co zmieniło się w CSS dla przycisków do 2026 roku

W skrócie: przycisku nie buduje się już z prefiksów dostawców i trzech zestawów ręcznych odcieni hover. Własności niestandardowe, natywne zagnieżdżanie, model kolorów OKLCH i funkcja light-dark() skracają typowy blok stylów mniej więcej o połowę i eliminują duplikację.

Skala zastosowania tych technik jest ogromna. Według danych W3Techs z lipca 2026 roku WordPress działa na 41,5% wszystkich stron internetowych i posiada 59,2% rynku CMS. Każdy wzorzec z tego artykułu będzie mógł Pan przenosić z projektu na projekt przez lata.

Technika

Jak robiono wcześniej

Jak robi się w 2026

Kolor

HEX plus ręczne odcienie na hover i active

oklch() plus color-mix() sam oblicza odcienie

Paleta

Dziewięć reguł CSS na każdy kolor

Jeden wiersz z nadpisaniem --btn-bg

Prefiksy

-webkit- i -moz- na każdą własność

Nie są potrzebne: własności od dawna w standardzie

Zagnieżdżanie

Tylko przez Sass lub Less

Natywne CSS nesting

Fokus

outline: none i utrata obsługi klawiatury

:focus-visible z widocznym obrysem

Ciemny motyw

Osobny arkusz stylów

light-dark() w jednej własności

Zacznijmy od części serwerowej: dopóki nie ma funkcji PHP, nie ma czego stylizować.

Funkcja PHP przycisku

Funkcja przyjmuje atrybuty z edytora i zwraca gotowy tag <a> z klasami, linkiem i tekstem. Shortcody pojawiły się już w WordPressie 2.5 i nadal pozostają najszybszym sposobem na wstawienie dowolnego znacznika do treści: add_shortcode() z oficjalnego podręcznika rejestruje tag, a callback składa HTML.

1/**
2 * Генерирует HTML кнопки через шорткод [button].
3 *
4 * @param array|string $atts Атрибуты шорткода.
5 * @param string|null $content Текст внутри парного тега [button]...[/button].
6 * @return string HTML разметка кнопки.
7 */
8function 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}

Proszę zwrócić uwagę na trzy szczegóły. shortcode_atts() scala przekazane atrybuty z wartościami domyślnymi, dlatego w zasięgu nie ma ani extract(), ani niezadeklarowanych zmiennych. Wszystkie wartości dynamiczne przechodzą przez esc_url() oraz esc_attr(): WordPress nie eskapuje wyjścia shortcodów za Pana. A do_shortcode() wewnątrz podpisu pozwala zagnieżdżać jeden shortcode w drugim, na przykład ikonę wewnątrz przycisku.

Rejestracja shortcodu i wywołanie w edytorze

Rejestrację podpinamy na hak init: do tego momentu rdzeń jest w pełni załadowany, a inne wtyczki w razie potrzeby będą mogły nadpisać tag przez remove_shortcode().

1add_action( 'init', 'myprefix_register_button_shortcode' );
2
3function myprefix_register_button_shortcode() {
4 add_shortcode( 'button', 'myprefix_button_shortcode' );
5}

Teraz proszę otworzyć wpis i wstawić tag. W klasycznym edytorze bezpośrednio w tekście, w Block Editorze przez blok „Shortcode":

1[button url="https://example.com/download" target="blank" text="Скачать бесплатно"]
2
3[button url="https://example.com" color="blue"]Подробнее[/button]

Pierwszy wariant jest samozamykający, z tekstem w atrybucie. Drugi jest parzysty: podpis znajduje się między tagiem otwierającym a zamykającym. Rezultat jest identyczny, proszę wybrać składnię wygodniejszą dla autorów.

Bez stylów przycisk na razie wygląda jak zwykły link. Mechanika już jednak działa: klasa myprefix-button color-green jest w znaczniku, pozostało ją ostylować.

Podstawowe style: właściwości niestandardowe i zagnieżdżanie

Cały wygląd opiera się na jednej zmiennej --btn-bg. Odcienie dla najechania i kliknięcia oblicza z niej color-mix(), więc ręczne dobieranie ciemniejszych wariantów nie jest już potrzebne. Reguły zagnieżdżone działają natywnie, bez 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}

Przesunięcie translate: 0 1px przy kliknięciu imituje fizyczny przycisk subtelniej niż stara technika z wewnętrznym cieniem. Płynność przejść zapewnia transition, a kolor tekstu został jawnie zduplikowany dla :hover, aby style motywu go nie nadpisały.

Proszę skopiować blok do style.css motywu potomnego lub do sekcji „Dodatkowe style" w konfiguratorze. Dalej najprzyjemniejsza część: schematy kolorów.

Paleta w OKLCH: nowy kolor w jednej linii

Każdy schemat zajmuje teraz dokładnie jedną linię: zmienia się tylko zmienna, wszystkie stany są przeliczane automatycznie.

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); }

Dlaczego właśnie OKLCH, a nie tradycyjny HEX. W opisie oklch() na MDN pierwszym parametrem jest postrzegana jasność: dwa kolory z tą samą pierwszą liczbą wyglądają na jednakowo jasne. Niebieski i czerwony przycisk z powyższego przykładu są wizualnie równoważne, w HEX nie ma takiej gwarancji. Dobieranie nowych schematów jest wygodne, zmieniając tylko trzeci parametr, odcień.

Wywołanie w edytorze nie zmienia się: color="red" włącza czerwony schemat, color="orange" pomarańczowy. Atrybut domyślnie pozostaje zielony, jak w oryginalnej funkcji.

Kod źródłowy stylów na ekranie laptopa programisty

Dostępność: to, co psuje się najczęściej

Prosta odpowiedź: przycisk potrzebuje widocznego fokusu, wystarczającego rozmiaru celu i poszanowania ustawień animacji. To nie są zalecenia „na odczepne". Audyt 17,2 mln stron w Web Almanac 2025 wykazał, że 67% stron usuwa obramowanie fokusu, a kontrast zgodny z WCAG spełnia tylko 30%.

Ramy prawne również się zaostrzyły: od 28 czerwca 2025 roku obowiązuje European Accessibility Act, a wymogi dostępności dla produktów cyfrowych w UE stały się normą prawną, a nie życzeniem.

Kryterium 2.5.8 Target Size (Minimum) poziomu AA z WCAG 2.2 wymaga, aby interaktywny cel zajmował co najmniej 24 na 24 piksele CSS lub miał równoważny wolny odstęp wokół.

Nasz przycisk z padding: 12px 24px spełnia minimum z zapasem, ale dwie reguły warto dodać osobno:

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}

Pierwsza reguła zwiększa wysokość do komfortowej strefy dotyku na urządzeniach mobilnych, gdzie pudłowanie w małe cele jest szczególnie irytujące. Druga wyłącza animacje dla osób, które poprosiły o to w ustawieniach systemu. Obramowanie fokusu już zdefiniowaliśmy przez :focus-visible: pojawia się ono podczas nawigacji klawiaturą i nie przeszkadza użytkownikom myszy.

Programista sprawdza dostępność interfejsu w nowoczesnym biurze

Ciemny motyw przez light-dark()

Jedna funkcja całkowicie zastępuje zapytanie mediów prefers-color-scheme. Podaje się dwie wartości, jasną i ciemną, a przeglądarka sama wybiera odpowiednią według aktywnego schematu. Zgodnie z dokumentacją MDN funkcja light-dark() ma status Baseline Newly available od maja 2024 roku, czyli działa we wszystkich aktualnych przeglądarkach.

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}

Wiersz color-scheme: light dark jest obowiązkowy: bez niego funkcja nie zostanie aktywowana. Dla ciemnego schematu tło zrobiono jaśniejszym, a tekst ciemnym: na ciemnym płótnie nasycone ciemne przyciski znikają, to typowy błąd. Szczegółowe omówienie tematyzacji ze wszystkimi pułapkami znajduje się w materiale web.dev o motywach kolorystycznych.

Jeśli Państwa odbiorcy korzystają ze starych przeglądarek korporacyjnych, proszę opakować nowości w @supports i zostawić zwykły HEX jako wartość zapasową: przycisk degraduje się łagodnie, tracąc jedynie precyzję odcieni.

Bezpieczeństwo: trzy linijki, o których się zapomina

Na początek najważniejsze: target="_blank" bez rel="noopener noreferrer" otwiera podatność typu tabnabbing. Strona, do której prowadzi przycisk, uzyskuje dostęp do window.opener i może podmienić kartę z Pana/Pani witryną. W naszej funkcji atrybut jest dodawany automatycznie, ale podczas poprawek łatwo go zgubić.

Escapowanie jest nie mniej ważne. esc_url() odcina niebezpieczne protokoły, takie jak javascript:, a esc_attr() nie pozwala wyrwać się z atrybutu. Usuwanie tych wywołań dla zwięzłości jest niedopuszczalne w żadnym shortkodzie, który przyjmuje dane z edytora.

I ostatnia rzecz: zawartość $content celowo nie jest przepuszczana przez wp_kses_post(), aby działały zagnieżdżone shortkody. Jeśli jednak pozwolą Państwo wstawiać przyciski przez formularze z frontendu, proszę opakować $label w wp_kses_post() przed wypisaniem.

Jak sprawdzić przycisk przed publikacją

Szybkie sprawdzenie zajmuje parę minut i wyłapuje prawie wszystkie problemy, z którymi potem zgłaszają się czytelnicy. Proszę przejść listę przed umieszczeniem przycisku w roboczych wpisach:

  • Proszę kliknąć przycisk myszą i upewnić się, że odnośnik otwiera się w odpowiedniej karcie.
  • Proszę przejść stronę klawiszem Tab: obrys fokusa powinien być zauważalny od pierwszego rzutu oka.
  • Proszę włączyć emulację ciemnego schematu w DevTools (panel Rendering, opcja prefers-color-scheme) i obejrzeć oba warianty tła.
  • Tamże proszę włączyć emulację prefers-reduced-motion i upewnić się, że przycisk przestał się animować.
  • Proszę otworzyć stronę w trybie mobilnym i spróbować trafić w przycisk kciukiem.

Jeśli wszystkie punkty są zaliczone, shortkod jest gotowy do masowego użycia. Proszę wyrobić sobie nawyk przechodzenia tej listy po każdej poprawce stylów: regresji w stanach fokusa i ciemnego motywu nie widać gołym okiem, dopóki nie spojrzy się celowo. A najczęstsze pytania o działanie shortkoda zebrano poniżej.

⁉️🤔 Często zadawane pytania

Czy taki shortkod działa w Block Editorze?

Tak, w pełni. Proszę wstawić blok „Shortcode" i wewnątrz ciąg [button ...]. Znaczniki są składane na serwerze podczas wyświetlania wpisu, więc edytorowi jest obojętne, w jaki sposób tag trafił do treści. Dla często używanych elementów z czasem warto zarejestrować natywny blok przez register_block_type(), ale to osobny projekt.

Co zrobić, jeśli przeglądarka odwiedzającego nie rozumie oklch() ani light-dark()?

Proszę opakować nowoczesne wartości w dyrektywę @supports i zostawić zwykły HEX jako wartość domyślną. Stara przeglądarka zastosuje zapasowy kolor, nowa weźmie OKLCH. Przycisk pozostanie sprawny w obu przypadkach: miękka degradacja dotyczy tylko precyzji odcieni i automatyki ciemnego motywu, nie funkcjonalności.

Dlaczego shortkod wyświetla się na stronie jako tekst w nawiasach kwadratowych?

Najczęściej funkcja nie jest zarejestrowana: proszę sprawdzić, czy functions.php zapisał się bez błędów składniowych i czy hak init zadziałał. Drugi wariant: wstawili Państwo tag w pliku szablonu, a tam potrzebne jest jawne wywołanie echo do_shortcode( '[button ...]' ). Proszę włączyć WP_DEBUG i zajrzeć do logu błędów.

Jak dodać ikonę do środka przycisku?

Najszybsza droga: emoji bezpośrednio w tekście, na przykład text="📥 Скачать". Dla SVG proszę przekazać adres pliku osobnym atrybutem i wypisać tag <img> wewnątrz odnośnika przez ten sam sprintf. Wariant z zestawem Dashicons też jest działający: pseudoelement ::before plus font-family: dashicons w osobnej klasie.

Czy w 2026 roku potrzebne są prefiksy dostawców dla border-radius i transition?

Nie. Te właściwości od dawna są w standardzie i działają we wszystkich aktualnych przeglądarkach bez prefiksów. Wsparcie konkretnej nowości wygodnie sprawdzać w tabelach MDN lub na caniuse.com: tam widać też status Baseline, który podpowiada, kiedy funkcję można stosować bez wariantów zapasowych.

💎 Podsumowanie i wnioski

Dla witryny, gdzie potrzeba pary typowych przycisków, własny shortkod wygrywa z każdą wtyczką: pełna kontrola nad znacznikami, zero zbędnych skryptów w kolejce ładowania i żadnej zależności, którą trzeba będzie aktualizować. Wizualny konstruktor z dziesiątkami gotowych stylów jest potrzebny rzadziej, niż się wydaje, ale jeśli nie da się bez niego obejść, proszę spojrzeć na MaxButtons z katalogu wordpress.org.

Praktyczny lifehack: proszę zacząć wdrożenie od linijki color-scheme: light dark w :root i zmiennych przez light-dark(). To najtańszy sposób na uzyskanie uczciwego ciemnego motywu, który zwraca się przy każdym kolejnym elemencie interfejsu. I pułapka na koniec: proszę sprawdzać przycisk nie tylko myszą. Proszę przejść stronę klawiszem Tab i upewnić się, że obrys fokusa jest widoczny, w przeciwnym razie część odwiedzających po prostu nie znajdzie Pana/Pani przycisku.

Proszę zabrać kod, wstawić do motywu potomnego i sprawdzić przycisk na swojej stronie jeszcze dziś. Wyszło czy utknęli Państwo w konflikcie z motywem? Proszę opowiedzieć w komentarzach, rozbierzemy to razem. I proszę zapisać się na aktualizacje bloga: przed nami analizy innych przydatnych shortkodów.