
🔘 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.phpmotywu potomnego - Krok 2: Proszę zarejestrować tag
[button]przezadd_shortcode()na hakuinit - 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 |
|
Paleta | Dziewięć reguł CSS na każdy kolor | Jeden wiersz z nadpisaniem |
Prefiksy |
| Nie są potrzebne: własności od dawna w standardzie |
Zagnieżdżanie | Tylko przez Sass lub Less | Natywne CSS nesting |
Fokus |
|
|
Ciemny motyw | Osobny arkusz stylów |
|
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 */ 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 }
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().
1 add_action( 'init', 'myprefix_register_button_shortcode' ); 2 3 function 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.

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.

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 przezregister_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ę
@supportsi 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.phpzapisał się bez błędów składniowych i czy hakinitzadziałał. Drugi wariant: wstawili Państwo tag w pliku szablonu, a tam potrzebne jest jawne wywołanieecho do_shortcode( '[button ...]' ). Proszę włączyćWP_DEBUGi 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 samsprintf. Wariant z zestawem Dashicons też jest działający: pseudoelement::beforeplusfont-family: dashiconsw 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.



