Wordpress

Retro Minimal Blog – Ein WordPress-Theme, entwickelt mit KI-Unterstützung

Retro Minimal Blog – Ein WordPress-Theme, entwickelt mit KI-Unterstützung

Wer diese Seite schon länger kennt, weiß: Jungsi’s Corner läuft seit 2013 auf WordPress. In dieser Zeit habe ich eine ganze Reihe von Themes ausprobiert – von fertigen Lösungen aus dem WordPress-Verzeichnis bis hin zu kommerziellen Premium-Themes. Das Ergebnis war meistens dasselbe: Optisch passabel, aber sobald ich etwas anpassen wollte, begann die eigentliche Arbeit.

Nicht weil WordPress das nicht erlauben würde – sondern weil jedes Theme seine eigene, oft undokumentierte CSS-Struktur mitbringt. Wer kennt das nicht: Man möchte den Abstand zwischen Header und Inhalt um ein paar Pixel verringern, sucht in den Browser-Entwicklertools nach dem zuständigen Selektor, findet .wp-block-post-title__inner-container .has-large-font-size:not(.has-text-color) und fragt sich, ob das wirklich sein muss.


Das Problem mit fertigen Themes

Fertige WordPress-Themes sind Kompromisse. Sie müssen für möglichst viele Anwendungsfälle funktionieren, weshalb sie oft mit einem Ballast aus CSS-Regeln, JavaScript-Bibliotheken und Einstellungsseiten daherkommen, die man zu 80% nie anfasst. Dazu kommt: Wer tiefer in den Code eingreifen möchte, muss erst verstehen, wie der Theme-Entwickler gedacht hat. Welche Klassen verwendet er? Wo überschreibt er WordPress-Standardstyles? Welche Variablen steuern Farben und Abstände?

Bei meinem letzten Theme-Wechsel hatte ich exakt dieses Problem. Das Theme sah gut aus, aber:

  • Die Beitragsvorschau auf der Startseite zeigte nur einen kurzen Excerpt, nicht den vollständigen Text bis zum <!--more-->-Tag
  • Der Header ließ sich zwar per Customizer anpassen, aber das Logo wurde immer zu klein dargestellt weil WordPress width– und height-Attribute direkt ins <img>-Tag schreibt
  • Das Mega-Menü-Plugin erzeugte einen blauen Hintergrund, weil WordPress-eigene Block-Navigation-Styles in den Render-Prozess eingriffen
  • Ein Dark Mode war nicht vorhanden und hätte erheblichen Aufwand bedeutet

An dieser Stelle kam mir die Idee: Was wäre, wenn ich das Theme von Grund auf neu entwickle – diesmal mit Unterstützung einer KI, die den Code selbst schreibt und dabei von Anfang an weiß, wie er strukturiert ist?


Die Idee: KI als Theme-Entwickler

Die Grundüberlegung ist simpel, aber effektiv. Ein KI-Modell wie Claude kann PHP, CSS und JavaScript schreiben. Es kennt die WordPress-Konventionen, versteht Template-Hierarchien und weiß, wie functions.php, wp_enqueue_scripts() und der Customizer zusammenspielen. Der entscheidende Vorteil gegenüber einem fertigen Theme: Die KI hat den gesamten Code selbst geschrieben und kennt daher jeden Selektor, jede Variable und jede Funktion beim Namen.

Wenn ich also sage „Das Logo ist zu klein“, muss sie nicht erst in fremdem Code nachschlagen – sie weiß, dass das Logo per get_custom_logo() ausgegeben wird, dass WordPress dabei feste width– und height-Attribute setzt, und dass der einzige zuverlässige Weg zur Lösung ein PHP-Filter auf get_custom_logo plus ein <style>-Block mit !important-Deklaration im wp_head-Hook ist, der als letzter lädt.

Dieses Wissen ist bei einem fremden Theme mühsam zu erarbeiten. Bei einem selbst generierten Theme ist es einfach vorhanden.


Der Entwicklungsprozess

Die Entwicklung des „Retro Minimal Blog“-Themes lief als iterativer Dialog. Ich beschrieb meine Anforderungen, die KI generierte den Code, ich testete das Ergebnis live auf jungsi.de und gab Feedback. Das ist kein grundlegend anderer Prozess als bei einem menschlichen Entwickler – aber er ist deutlich schneller und ohne Kommunikationsverluste.

Ein paar technische Entscheidungen, die dabei entstanden:

Klassisches PHP-Theme statt Block-Theme

Ich habe mich bewusst für ein klassisches PHP-Theme entschieden. Block-Themes (Full Site Editing) sind die Zukunft von WordPress, aber für eine bestehende Seite mit viel historischem Content und spezifischen Anforderungen ist ein klassisches Theme einfacher zu kontrollieren. Die Template-Hierarchie ist überschaubar: index.php, single.php, archive.php, search.php, page.php, sidebar.php, header.php, footer.php.

CSS Custom Properties als Design-System

Das gesamte Design basiert auf CSS-Variablen in :root. Farben, Abstände, Schriftgrößen, Schatten – alles zentral definiert. Das hat einen entscheidenden Vorteil: Der Dark Mode lässt sich durch eine einzige Attributänderung am <html>-Element aktivieren (data-theme="dark"), die alle Variablen auf dunkle Werte umschaltet. Kein JavaScript muss einzelne Elemente einfärben – außer bei Drittanbieter-Plugins, die eigene Inline-Styles setzen.

:root {
  --color-bg:     #edeae4;
  --color-card:   #ffffff;
  --color-text:   #1a1a1a;
  --color-accent: #c8502a;
}

[data-theme="dark"] {
  --color-bg:     #18181b;
  --color-card:   #27272a;
  --color-text:   #e8e8e4;
  --color-accent: #e8734a;
}
Das Mega-Menü-Problem

Das war die technisch interessanteste Herausforderung. Das Mega-Menü-Plugin schreibt Hintergrundfarben als Inline-Styles direkt in die DOM-Elemente – also style="background-color: #ffffff". CSS-Regeln, selbst mit !important, können Inline-Styles nicht überschreiben. Die Lösung war JavaScript: Ein MutationObserver beobachtete ursprünglich alle DOM-Änderungen und färbte Elemente nach – was auf dem iPad zu erheblichen Performance-Problemen führte, weil das Menü bei jeder Interaktion hunderte Callbacks auslöste.

Die finale Lösung: kein dauerhafter Observer, sondern gezieltes Nacheinfärben beim mouseenter-Event auf Menüpunkten, kombiniert mit element.style.setProperty('background-color', '#27272a', 'important') – dem JavaScript-Äquivalent zu !important.

<!--more-->-Tag und WordPress-Eigenheiten

WordPress‘ the_content()-Funktion ignoriert auf der Blog-Übersichtsseite den als Parameter übergebenen „Weiterlesen“-Link und generiert stattdessen einen eigenen more-link mit eigenen CSS-Klassen. Die Lösung: the_content() komplett umgehen und stattdessen $post->post_content direkt lesen, manuell am <!--more-->-Tag splitten und das Ergebnis durch apply_filters('the_content', ...) jagen. So bleibt Gutenberg-Formatierung erhalten, aber der Button kommt vollständig aus eigenem Code.

$raw      = $post->post_content;
$has_more = strpos( $raw, '<!--more-->' ) !== false;
if ( $has_more ) {
    $before = explode( '<!--more-->', $raw )[0];
} else {
    $before = $raw;
}
echo apply_filters( 'the_content', $before );
Dark Mode ohne Flash

Ein bekanntes Problem bei Dark-Mode-Implementierungen: Wenn das Theme-Attribut erst nach DOMContentLoaded gesetzt wird, sieht der Besucher kurz den hellen Modus bevor der dunkle greift – einen sogenannten FOUC (Flash of Unstyled Content). Die Lösung ist ein winziges Inline-Script direkt im <head>, das synchron ausgeführt wird, bevor der Browser irgendetwas rendert:

<script>
(function(){
  var t = localStorage.getItem('minimal-blog-theme');
  if (!t) t = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
  document.documentElement.setAttribute('data-theme', t);
})();
</script>

Drei Zeilen, die sicherstellen dass der Besucher niemals einen weißen Aufblitz sieht.

Performance auf Mobile und iPad

Ein MutationObserver der das gesamte DOM beobachtet ist auf Desktop unproblematisch – auf einem iPad mit dem großen Mega-Menü aber ein echtes Performance-Problem. Der Observer feuerte hunderte Callbacks pro Sekunde und blockierte den Browser spürbar. Die Lösung war ein kompletter Umbau der JavaScript-Architektur: kein permanenter Observer mehr, stattdessen requestAnimationFrame für alle Scroll-Events und gezieltes Event-Handling nur dort wo es wirklich gebraucht wird.


Iterative Verfeinerung: Was nach dem ersten Launch kam

Das Theme war nach der initialen Entwicklung funktionsfähig – aber noch lange nicht fertig. Der eigentliche Feinschliff begann danach. Eine Auswahl der interessanteren Probleme:

Plugin-Kompatibilität: TablePress im Dark Mode

TablePress schreibt seine Farben direkt als Inline-Styles in jede Tabellenzelle – und zusätzlich tabellenspezifische CSS-Klassen wie .tablepress-id-37 tbody td { color: #000000; }. Das macht normales CSS-Überschreiben unmöglich, weil tabellenspezifische Klassen spezifischer sind als generische. Die Lösung: ein Attributselektor [class*="tablepress-id-"] der alle Tabellen-IDs auf einmal trifft, kombiniert mit !important und dem [data-theme="dark"]-Prefix.

Alternatives Logo für den Dark Mode

Das normale Logo von Jungsi’s Corner hat dunkle Schrift auf hellem Hintergrund – im Dark Mode kaum zu erkennen. WordPress bietet von Haus aus keine Option für ein alternatives Dark-Mode-Logo. Die Lösung: ein eigenes Customizer-Feld unter „Design → Anpassen → Dark Mode“, das eine separate Bilddatei hinterlegt. Im Template werden beide Logos ausgegeben, aber jeweils das andere per CSS ausgeblendet:

.logo-dark  { display: none !important; }
.logo-light { display: block; }

[data-theme="dark"] .logo-light { display: none !important; }
[data-theme="dark"] .logo-dark  { display: block !important; }
Überschriften-Hierarchie: zwei Kontexte, eine Wahrheit

Ein unerwartetes Problem: Überschriften im Artikeltext (H2–H6) müssen auf der Einzelseite in voller Größe erscheinen – in der Beitragsvorschau auf der Startseite aber nicht. Wer H3 mit 1.75rem definiert und den Artikeltext bis zum <!--more-->-Tag auf der Startseite anzeigt, bekommt dort Zwischenüberschriften die fast so groß sind wie der Beitragstitel selbst. Die Lösung: getrennte CSS-Regeln für .entry-content (Einzelseite) und .post-card__content (Startseite).

/* Einzelseite: volle Größe */
.entry-content h3 { font-size: 1.75rem; }

/* Startseite: kompakt */
.post-card__content h3 { font-size: 1.15rem; }
Editor-Styles: der vergessene Kontext

Der Gutenberg-Editor lädt seine eigene CSS-Datei (editor-style.css) – völlig unabhängig vom Frontend. Wer nur style.css anpasst, sieht im Editor weiterhin die alten Stile. Das betrifft nicht nur Überschriften, sondern auch den Beitragstitel selbst, der eine eigene Klasse .editor-post-title__input hat und nicht von normalen h1-Regeln erfasst wird.


Was das Theme letztlich kann

Nach der gesamten Entwicklung hat das „Retro Minimal Blog“-Theme folgende Funktionen:

  • Responsives Layout mit 1200px-Container, zweispaltig mit Sidebar, Hamburger-Menü ab 1024px (iPad Hochformat)
  • Dark Mode mit System-Präferenz-Erkennung, lokalem Speicher, Mond/Sonne-Toggle im Header und FOUC-Schutz
  • Alternatives Dark-Mode-Logo über den WordPress-Customizer hinterlegbar
  • Permanentes Suchfeld im Header mit Enter-Unterstützung
  • Hero-Beitrag auf der Startseite (angepinnt oder aktuellster Artikel)
  • Volltext bis zum <!--more-->-Tag auf der Startseite mit eigenem Weiterlesen-Link
  • Vollbreites Beitragsbild auf Einzelseiten, Text in komfortabler Lesebreite zentriert
  • Lesefortschrittsbalken auf Einzelseiten
  • Social Media Widget mit SVG-Icons für Facebook, Instagram, YouTube, X/Twitter, Mastodon und RSS
  • Gutenberg-Integration mit eigener Farbpalette, Schriftgrößen und Editor-Styles die das Frontend spiegeln
  • TablePress Dark Mode – tabellenspezifische Plugin-Styles werden per Attributselektor überschrieben
  • Mega Menü Dark Mode – Plugin-Inline-Styles werden per JavaScript beim Hover gezielt überschrieben
  • Globale Option zum Ausblenden von Seitentiteln auf statischen Seiten (nicht auf Beiträgen)
  • Getrennte Überschriften-Größen für Einzelseite und Beitragsvorschau
  • Konsistente Editor-Styles – Frontend und Gutenberg-Editor zeigen identische Typografie
  • Optimierte Performance auf Mobile – kein permanenter MutationObserver, requestAnimationFrame für Scroll-Events
  • Suchergebnisse mit Trefferanzahl und kompaktem Header
  • Theme-Vorschaubild und vollständige Theme-Metadaten (Version 1.4.6)

Fazit: KI als Entwicklungspartner

Was ich an diesem Prozess besonders schätze: Die KI kennt ihren eigenen Code. Das klingt selbstverständlich, ist es aber nicht. Bei einem fremden Theme, das ich von GitHub geklont oder aus dem WordPress-Verzeichnis installiert hätte, wäre jeder Anpassungswunsch mit Recherche verbunden. Bei diesem Theme sage ich „Das Logo ist zu klein“ und bekomme eine Änderung in genau der richtigen Zeile, mit der richtigen Spezifität.

Das bedeutet nicht, dass der Prozess reibungslos war. Der more-link hat uns drei Anläufe gekostet. Der Mega-Menü-Hintergrund sechs. Der Dark Mode auf dem iPad erst recht. Manche WordPress-Eigenheiten sind einfach sperrig – unabhängig davon, wer den Code schreibt. Aber die Iteration ist schnell. Feedback geben, korrigierte Version hochladen, nächsten Punkt angehen.

Was mich dabei am meisten überrascht hat: Es waren nicht die großen Features die aufwendig waren, sondern die kleinen Eigenheiten. Dass WordPress Logo-Dimensionen als Inline-Attribute schreibt. Dass der Gutenberg-Editor eine eigene CSS-Datei braucht. Dass Plugin-Inline-Styles CSS-!important schlagen. Dass ein MutationObserver auf einem iPad den Browser in die Knie zwingt. All das sind Dinge, die man bei einem fremden Theme mühsam dokumentiert findet – oder eben nicht. Bei einem selbst entwickelten Theme lernt man sie im Dialog.

Für jemanden, der wie ich nicht täglich PHP und CSS schreibt, aber weiß was er will, ist das ein erheblicher Gewinn. Das Theme ist kein Kompromiss mehr – es tut genau das, was ich von ihm verlange. Und wenn ich morgen etwas ändern möchte, weiß ich (und die KI), wo der Code steht.


Das Theme steht nicht zur öffentlichen Verfügung, da es spezifisch auf die Anforderungen von Jungsi’s Corner zugeschnitten ist. Fragen zur Entwicklung gerne in den Kommentaren.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert