
🔘 Button-Shortcode in WordPress: einbaufertiger PHP-Code und modernes CSS 2026
Sie benötigen einen „Download"-Button mitten in einem Artikel, aber Ihr Theme zeigt nur einen blau unterstrichenen Link. Kommt Ihnen das bekannt vor? Im Block-Editor fügen Sie einen Button mit einem Klick ein, aber im klassischen Editor, in Widgets und in individuellen Themes müssen Sie jedes Mal HTML mit Klassen von Hand schreiben.
Das Kopieren von Markup von Beitrag zu Beitrag endet vorhersehbar: Sie vergessen eine Klasse an einer Stelle, verlieren rel="noopener" an einer anderen, und an einer dritten hat der Button plötzlich einen anderen Farbton. Je mehr Inhalte Ihre Website hat, desto teurer wird jede Stiländerung.
Die Lösung dauert etwa zehn Minuten. Nachfolgend finden Sie einen fertigen [button]-PHP-Shortcode, eine OKLCH-Palette, Dark-Theme-Unterstützung mittels light-dark() und WCAG-2.2-Barrierefreiheit. Alles wurde in aktuellen Browsern des Jahres 2026 getestet.
So fügen Sie einen Button per Shortcode hinzu: Aktionsplan
💡 Kurzüberblick:
- Schritt 1: Fügen Sie die Button-PHP-Funktion in die
functions.phpIhres Child-Themes ein - Schritt 2: Registrieren Sie den
[button]-Tag mitadd_shortcode()aminit-Hook - Schritt 3: Binden Sie CSS mit allen Zuständen ein: default, hover, active, focus
- Schritt 4: Definieren Sie Farbschemata mit einer einzigen OKLCH-Zeile pro Farbe
- Schritt 5: Fügen Sie
[button url="..." color="blue"]Text[/button]in einen Beitrag ein und testen Sie den Tastaturfokus
Jeder Schritt unten enthält kopierfertigen Code. Platzieren Sie den Code in einem Child-Theme, damit ein Update des Parent-Themes Ihre Änderungen nicht überschreibt. Falls Sie noch kein Child-Theme haben, erstellen Sie zunächst eines mithilfe des offiziellen WordPress-Leitfadens zu Child-Themes; das dauert nur wenige Minuten.
Doch bevor Sie kopieren, werfen Sie einen Blick darauf, was sich beim Button-Styling selbst geändert hat. In den letzten Jahren wurde CSS für Buttons nahezu vollständig neu geschrieben.
Was sich bei Button-CSS bis 2026 geändert hat
Kurz gesagt: Sie bauen Buttons nicht mehr aus Vendor-Präfixen und drei Sätzen handverlesener Hover-Farbtöne. Custom Properties, natives Nesting, das OKLCH-Farbmodell und die Funktion light-dark() halbieren einen typischen Stilblock in etwa und eliminieren Duplikationen.
Diese Techniken finden in enormem Maßstab Anwendung. Laut W3Techs-Daten vom Juli 2026 betreibt WordPress 41,5% aller Websites und hält 59,2% des CMS-Marktes. Jedes Muster aus diesem Artikel lässt sich über Jahre hinweg von Projekt zu Projekt übertragen.
Technik | Wie es früher gemacht wurde | Wie es 2026 gemacht wird |
|---|---|---|
Farbe | HEX plus manuelle Farbtöne für hover und active |
|
Palette | Neun CSS-Regeln pro Farbe | Eine Zeile, die |
Präfixe |
| Nicht nötig: Eigenschaften sind längst standardisiert |
Nesting | Nur über Sass oder Less | Natives CSS-Nesting |
Fokus |
|
|
Dark Theme | Separates Stylesheet |
|
Beginnen wir mit der Serverseite: Solange wir keine PHP-Funktion haben, gibt es nichts zu stylen.
Button-PHP-Funktion
Die Funktion akzeptiert Attribute aus dem Editor und gibt einen fertigen <a>-Tag mit Klassen, einem Link und Text zurück. Shortcodes gibt es seit WordPress 2.5, und sie sind nach wie vor der schnellste Weg, beliebiges Markup in Inhalte einzufügen: add_shortcode() aus der offiziellen Referenz registriert den Tag, und ein Callback setzt das HTML zusammen.
1 /** 2 * Generates button HTML via the [button] shortcode. 3 * 4 * @param array|string $atts Shortcode attributes. 5 * @param string|null $content Text inside the paired [button]...[/button] tag. 6 * @return string Button HTML markup. 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 // Button text: text attribute takes priority, then tag content 22 $label = $atts['text'] ? $atts['text'] : $content; 23 24 // URL provided: build <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 // No URL: wrap in <span> 40 return sprintf( 41 '<span class="myprefix-button color-%s">%s</span>', 42 esc_attr( $atts['color'] ), 43 do_shortcode( $label ) 44 ); 45 }
Beachten Sie drei Details. shortcode_atts() führt übergebene Attribute mit Standardwerten zusammen, sodass kein extract() oder undeklarierte Variablen im Scope vorkommen. Alle dynamischen Werte durchlaufen esc_url() und esc_attr(): WordPress escapt Shortcode-Ausgaben nicht für Sie. Und do_shortcode() innerhalb des Labels erlaubt das Verschachteln eines Shortcodes in einem anderen (zum Beispiel ein Icon innerhalb des Buttons).
Den Shortcode registrieren und im Editor verwenden
Die Registrierung hängt sich in init ein: Zu diesem Zeitpunkt ist der Kern vollständig geladen, und andere Plugins können den Tag bei Bedarf über remove_shortcode() überschreiben.
1 add_action( 'init', 'myprefix_register_button_shortcode' ); 2 3 function myprefix_register_button_shortcode() { 4 add_shortcode( 'button', 'myprefix_button_shortcode' ); 5 }
Öffnen Sie nun einen Beitrag und fügen Sie den Tag ein. Im klassischen Editor setzen Sie ihn direkt in den Text; im Block-Editor verwenden Sie den Block „Shortcode":
1 [button url="https://example.com/download" target="blank" text="Download free"] 2 3 [button url="https://example.com" color="blue"]Learn more[/button]
Die erste Variante ist selbstschließend mit dem Text in einem Attribut. Die zweite ist paarig: Das Label steht zwischen öffnendem und schließendem Tag. Das Ergebnis ist identisch; wählen Sie die Syntax, die für Ihre Autoren bequemer ist.
Ohne Styles sieht der Button immer noch wie ein gewöhnlicher Link aus. Die Mechanik funktioniert jedoch bereits: Die Klasse myprefix-button color-green ist im Markup enthalten, und es bleibt nur noch, sie zu stylen.
Basis-Styles: Custom Properties und Nesting
Das gesamte Erscheinungsbild ruht auf einer einzigen Variable, --btn-bg. color-mix() berechnet daraus Farbtöne für hover und active, sodass Sie dunklere Varianten nicht mehr von Hand auswählen müssen. Verschachtelte Regeln funktionieren nativ, ohne 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 }
Die Verschiebung translate: 0 1px im aktiven Zustand imitiert einen physischen Tastendruck subtiler als die alte Technik mit Innen-Schatten. transition legt die Sanftheit fest, und die Textfarbe wird bei :hover explizit wiederholt, damit Theme-Stile sie nicht überschreiben.
Kopieren Sie den Block in die style.css Ihres Child-Themes oder in den Bereich „Zusätzliches CSS" des Customizers. Nun zum interessanten Teil: die Farbschemata.
OKLCH-Palette: eine neue Farbe in einer Zeile
Jedes Schema benötigt jetzt genau eine Zeile: Nur die Variable ändert sich, und alle Zustände werden automatisch neu berechnet.
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); }
Warum OKLCH statt des vertrauten HEX? In der oklch()-Beschreibung auf MDN ist der erste Parameter die wahrgenommene Helligkeit: Zwei Farben mit derselben ersten Zahl wirken gleich hell. Die blauen und roten Buttons oben sind visuell gleichwertig; HEX bietet keine solche Garantie. Neue Schemata lassen sich einfach erstellen, indem Sie nur den dritten Parameter (Farbton) ändern.
Die Verwendung im Editor bleibt gleich: color="red" aktiviert das rote Schema, color="orange" das orange. Das Standardattribut bleibt Grün, wie in der ursprünglichen Funktion.

Barrierefreiheit: Was am häufigsten scheitert
Die direkte Antwort: Ein Button benötigt einen sichtbaren Fokusring, eine ausreichende Zielgröße und die Berücksichtigung von Animationspräferenzen. Das sind keine optionalen Anforderungen. Ein Audit von 17,2 Millionen Websites im Web Almanac 2025 zeigte, dass 67% der Seiten die Fokusumrandung entfernen und nur 30% die WCAG-Kontraststandards erfüllen.
Auch der rechtliche Rahmen hat sich verschärft: Seit dem 28. Juni 2025 gilt der European Accessibility Act, und Barrierefreiheitsanforderungen für digitale Produkte in der EU sind nun eine rechtliche Norm und keine bloße Empfehlung mehr.
Das Kriterium 2.5.8 Zielgröße (Minimum) auf Stufe AA der WCAG 2.2 verlangt, dass ein interaktives Ziel mindestens 24 mal 24 CSS-Pixel misst oder einen gleichwertigen freien Raum darum herum aufweist.
Unser Button mit padding: 12px 24px erfüllt das Minimum mit Spielraum, aber zwei Regeln sind es wert, separat hinzugefügt zu werden:
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 }
Die erste Regel bringt die Höhe auf eine komfortable Touch-Zone auf Mobilgeräten, wo verpasste Berührungen bei kleinen Zielen besonders frustrierend sind. Die zweite deaktiviert Animationen für Personen, die dies in ihren Systemeinstellungen angefordert haben. Den Fokusring haben wir bereits über :focus-visible definiert: Er erscheint bei der Tastaturnavigation und stört Mausnutzer nicht.

Dark-Theme mit light-dark()
Eine einzige Funktion ersetzt die gesamte prefers-color-scheme-Media-Query. Sie geben zwei Werte an (hell und dunkel), und der Browser wählt anhand des aktiven Schemas den passenden aus. Laut MDN hat die light-dark()-Funktion seit Mai 2024 den Baseline-Status „Newly available", funktioniert also in allen aktuellen Browsern.
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 }
Die Zeile color-scheme: light dark ist erforderlich: Ohne sie wird die Funktion nicht aktiv. Für das dunkle Schema wird der Hintergrund heller und der Text dunkler gemacht: Auf einer dunklen Leinwand gehen gesättigte dunkle Schaltflächen unter, ein häufiger Fehler. Eine detaillierte Aufschlüsselung des Theming mit allen Fallstricken finden Sie im web.dev-Artikel zu Farbthemen.
Wenn Ihre Zielgruppe ältere Unternehmensbrowser nutzt, verpacken Sie die neuen Funktionen in @supports und behalten Sie einfaches HEX als Fallback: Die Schaltfläche wird sauber degradiert und verliert lediglich an Farbpräzision.
Sicherheit: Drei Zeilen, die man vergisst
Zuallererst: target="_blank" ohne rel="noopener noreferrer" öffnet eine Tabnabbing-Schwachstelle. Die Seite, auf die die Schaltfläche verlinkt, erhält Zugriff auf window.opener und kann den Tab mit Ihrer Website ersetzen. In unserer Funktion wird das Attribut automatisch hinzugefügt, aber bei Änderungen geht es leicht verloren.
Escaping ist ebenso wichtig. esc_url() blockiert gefährliche Protokolle wie javascript:, und esc_attr() verhindert das Ausbrechen aus einem Attribut. Diese Aufrufe dürfen in keinem Shortcode, der Daten aus dem Editor entgegennimmt, aus Platzgründen entfernt werden.
Ein letzter Punkt: $content wird bewusst nicht durch wp_kses_post() geleitet, damit verschachtelte Shortcodes funktionieren. Wenn Sie jedoch das Einfügen von Schaltflächen über Frontend-Formulare erlauben, verpacken Sie $label vor der Ausgabe in wp_kses_post().
So testen Sie eine Schaltfläche vor der Veröffentlichung
Ein kurzer Test dauert ein paar Minuten und fängt fast jedes Problem ab, das Nutzer später melden. Gehen Sie diese Liste durch, bevor Sie die Schaltfläche in produktiven Beiträgen platzieren:
- Klicken Sie die Schaltfläche mit der Maus an und prüfen Sie, ob der Link im richtigen Tab öffnet.
- Navigieren Sie mit der Tabulatortaste durch die Seite: Der Fokusring sollte auf den ersten Blick deutlich erkennbar sein.
- Aktivieren Sie die Dark-Scheme-Emulation in den DevTools (Rendering-Panel, Option prefers-color-scheme) und prüfen Sie beide Hintergrundvarianten.
- Aktivieren Sie die prefers-reduced-motion-Emulation im selben Panel und stellen Sie sicher, dass die Schaltfläche nicht mehr animiert.
- Öffnen Sie die Seite im Mobilmodus und versuchen Sie, die Schaltfläche mit dem Daumen anzutippen.
Besteht sie alle Prüfungen, ist der Shortcode bereit für den breiten Einsatz. Machen Sie es sich zur Gewohnheit, diese Liste nach jeder Stiländerung durchzugehen: Regressionen bei Fokuszuständen und Dark-Theme sind unsichtbar, bis man gezielt danach sucht. Die häufigsten Fragen zum Shortcode-Verhalten sind im Folgenden zusammengestellt.
⁉️🤔 Häufig gestellte Fragen
Funktioniert dieser Shortcode im Block-Editor?
Ja, vollständig. Fügen Sie einen „Shortcode"-Block ein und geben Sie darin
[button ...]ein. Das Markup wird beim Rendern des Beitrags serverseitig zusammengesetzt, daher ist es dem Editor egal, wie der Tag in den Inhalt gelangt ist. Für häufig verwendete Elemente lohnt es sich irgendwann, einen nativen Block überregister_block_type()zu registrieren, aber das ist ein separates Projekt.
Was passiert, wenn der Browser eines Besuchers oklch() oder light-dark() nicht versteht?
Verpacken Sie moderne Werte in eine
@supports-Direktive und behalten Sie einfaches HEX als Standardwert. Ein alter Browser wendet die Fallback-Farbe an; ein neuer nutzt OKLCH. Die Schaltfläche bleibt in beiden Fällen funktionsfähig: Graceful Degradation betrifft nur die Farbpräzision und die Dark-Theme-Automatisierung, nicht die Funktionalität.
Warum erscheint der Shortcode auf der Seite als Text in eckigen Klammern?
Meistens ist die Funktion nicht registriert: Prüfen Sie, ob
functions.phpohne Syntaxfehler gespeichert wurde und ob derinit-Hook ausgelöst wurde. Eine zweite Möglichkeit: Sie haben den Tag in einer Template-Datei eingefügt, wo Sie einen expliziten Aufrufecho do_shortcode( '[button ...]' )benötigen. Aktivieren SieWP_DEBUGund prüfen Sie das Fehlerprotokoll.
Wie füge ich ein Icon in die Schaltfläche ein?
Der schnellste Weg: ein Emoji direkt im Text, zum Beispiel
text="📥 Download". Für SVG übergeben Sie die Datei-URL als separates Attribut und geben ein<img>-Tag innerhalb des Links über dasselbesprintfaus. Der Dashicons-Ansatz funktioniert ebenfalls: ein::before-Pseudoelement plusfont-family: dashiconsin einer eigenen Klasse.
Sind Vendor-Präfixe für border-radius und transition 2026 noch nötig?
Nein. Diese Eigenschaften sind längst standardisiert und funktionieren in allen aktuellen Browsern ohne Präfixe. Prüfen Sie die Unterstützung für ein bestimmtes Feature in den MDN-Tabellen oder auf caniuse.com, die auch den Baseline-Status anzeigen, der angibt, ab wann ein Feature ohne Fallbacks genutzt werden kann.
💎 Zusammenfassung und Fazit
Für eine Website, die nur ein paar Standardschaltflächen benötigt, schlägt ein eigener Shortcode jedes Plugin: volle Kontrolle über das Markup, null zusätzliche Skripte in der Lade-Warteschlange und keine Abhängigkeiten, die aktuell gehalten werden müssen. Ein visueller Builder mit Dutzenden vorgefertigter Stile wird seltener benötigt, als es scheint, aber wenn Sie wirklich einen brauchen, schauen Sie sich MaxButtons im wordpress.org-Verzeichnis an.
Praxistipp: Beginnen Sie die Implementierung mit der Zeile color-scheme: light dark in :root und Variablen via light-dark(). Das ist der günstigste Weg zu einem ordentlichen Dark-Theme und zahlt sich für jedes weitere UI-Element aus. Und ein Fallstrick zum Schluss: Testen Sie die Schaltfläche nicht nur mit der Maus. Navigieren Sie mit der Tabulatortaste durch die Seite und prüfen Sie, ob der Fokusring sichtbar ist; andernfalls werden manche Besucher Ihre Schaltfläche schlichtweg nicht finden.
Nehmen Sie den Code, fügen Sie ihn in Ihr Child-Theme ein und testen Sie die Schaltfläche noch heute auf Ihrer Website. Hat es funktioniert oder gab es einen Konflikt mit Ihrem Theme? Teilen Sie es in den Kommentaren mit, und wir finden gemeinsam eine Lösung. Und abonnieren Sie die Blog-Updates: Weitere nützliche Shortcode-Analysen sind in Vorbereitung.



