Warum hat mein Critical CSS mein Menü / Overlay kaputtgemacht (es erscheint beim Laden offen)?
Die Kurzfassung: Critical-CSS-Generatoren behalten nur die Styles für das, was beim Laden im oberen Seitenbereich sichtbar ist. Ihre standardmäßig ausgeblendeten und per Klick geöffneten Elemente (mobiles Menü, Such-Overlay, Modal, Drawer) werden als nutzlos eingestuft und entfernt. Das Ergebnis: Beim Laden erscheinen sie offen, kaputt, ungestylt.
Sie aktivieren Critical CSS (nur die Styles für den ersten Bildaufbau werden eingefügt) oder die Option „Remove unused CSS“, um bei PageSpeed Punkte zu sammeln. Der Score steigt. Und plötzlich: Ihr Such-Overlay erscheint beim Laden weit geöffnet, Ihr mobiles Menü ist aufgeklappt, ein Button bekommt seinen hässlichen grauen Standardrahmen zurück. Sie laden neu, leeren den Cache… nichts hilft.
Das Verwirrendste: Wenn Sie den Code inspizieren, ist die CSS-Regel genau da im HTML. Aber der Browser wendet sie nicht an. Hier die vollständige Erklärung und die Lösung, die hält.
Was ein Critical-CSS-Generator wirklich tut
Die Idee hinter Critical CSS ist legitim und wirksam: Statt Ihr komplettes Stylesheet vor dem ersten Rendering zu laden (was die Anzeige blockiert), extrahieren Sie nur das CSS, das für den sichtbaren oberen Seitenbereich nötig ist, fügen es inline in den <head>, und laden den Rest später (defer).
Um zu entscheiden, was „nötig“ ist, rendert das Tool die Seite und schaut sich an, was beim Laden im viewport sichtbar ist. Alles, was in diesem Moment nicht sichtbar ist, gilt als nicht kritisch, oder im „Remove unused CSS“-Modus schlicht als nutzlos und entfernbar.
Und genau da liegt die Falle.
Die eigentliche Ursache: „standardmäßig ausgeblendet“ = „als nutzlos eingestuft“
Überlegen Sie, wie Ihre interaktiven Komponenten aussehen, beim Laden der Seite:
- das mobile Menü: geschlossen (
display:noneodertransformaußerhalb des Bildschirms); - das Such-Overlay: ausgeblendet (
opacity:0; visibility:hidden); - das Modal, der Drawer, das Mega-Menü: ausgeblendet;
- eingeklappte Tabs und Akkordeons: Inhalt maskiert.
All diese Elemente sind in dem Moment unsichtbar, in dem der Generator die Seite beobachtet. Er schließt daraus, logisch, aber falsch, dass ihr Style nutzlos ist, und entfernt ihn aus dem Critical CSS.
Das Problem: Diese Elemente sollen später, per Klick, via JavaScript erscheinen. Aber ihr Style ist weg. Zwei klassische Symptome:
Was kaputtgeht
Die Regel, die sie versteckt hat, ist weg. Ein
.overlay { opacity:0; visibility:hidden }entfernt → nichts verbirgt das Overlay mehr → es erscheint beim Laden offen.Die Look-Regel ist weg. Eine
button { border:0; background:none }nicht behalten → der Button bekommt den Browser-Standardstil zurück (grauer Rahmen, System-Füllung).
Das nervenaufreibende Symptom: „die Regel ist da, wird aber ignoriert“
Das ist der Punkt, der Stunden kostet. Sie inspizieren, sehen deutlich .overlay { visibility:hidden } irgendwo im minifizierten HTML. Warum wendet der Browser sie dann nicht an?
Weil es in einer Critical-CSS-Pipeline zwei Stylesheets gibt:
- das inline eingefügte Critical CSS (im
<head>, sofort angewendet), bereinigt um Ihre interaktiven Regeln; - das vollständige Stylesheet, das verzögert ankommen soll.
Drei Dinge gehen schief, oft gleichzeitig:
- Das vollständige Stylesheet kommt zu spät an (nachdem das JS bereits versucht hat, das Element zu öffnen/zu schließen), oder bei manchen Render-Pfaden gar nicht.
- Im „Remove unused CSS“-Modus wurde die Regel aus BEIDEN Stylesheets entfernt: Sie existiert nirgendwo mehr.
- Die Kaskade wendet sich gegen Sie: Eine Regel, die zwar vorhanden, aber weniger spezifisch ist (oder erst danach geladen wird), unterliegt dem Inline- oder Standardstil.
„Die Regel steht im HTML“ bedeutet also nicht „die Regel gewinnt“. Sie kann vorhanden sein und trotzdem von der Kaskade verworfen werden, oder in einem Stylesheet stehen, das im entscheidenden Moment noch nicht geladen ist.
Die Fallen bei der Diagnose (warum Cache-Leeren nicht reicht)
Bevor Sie etwas reparieren, müssen Sie das echte Rendering beobachten, und dabei lauern drei Fallen:
- Getrennte Caches für Mobil und Desktop. Viele Engines erzeugen ein unterschiedliches Critical CSS für Mobil und Desktop. Sie reparieren, testen auf dem Desktop, alles gut… aber der Mobil-Cache liefert weiterhin die alte kaputte Version. Testen und „wärmen“ Sie beide, mit dem richtigen User-Agent (der Kennung, die der Browser sendet, um anzuzeigen, ob er mobil oder Desktop ist).
- „Cache leeren“ leert nicht immer das pro Seite gespeicherte Critical CSS. Das Critical CSS wird oft pro URL gespeichert, getrennt vom HTML-Cache. Ein „clear all“ kann veraltete Critical-Dateien stehen lassen. Sie müssen das generierte CSS gezielt ansprechen.
- Das Critical CSS stammt aus einer zwischengespeicherten Quelle. Wird es aus einer veralteten Version Ihres Quell-Stylesheets neu generiert, taucht Ihre Korrektur nie auf. Sie müssen die Neugenerierung erzwingen, ausgehend von der aktuellen Quelle.
Um das echte Rendering zu sehen, ohne vom Cache getäuscht zu werden: Fügen Sie der URL einen Dummy-Parameter hinzu (?cb=123) um ein frisches Rendering zu erzwingen, und vergleichen Sie mit der normalen URL.
Die Lösung, die hält (und mit Ihrem Theme mitwandert)
Die Versuchung ist groß, die Selektoren in eine „safelist“ (Ausschlussliste) eines Plugins einzutragen. Das funktioniert… solange Sie dieses Plugin mit dieser Konfiguration behalten. Sobald Sie das Tool wechseln oder die Seite neu aufbauen, geht es wieder kaputt.
Die robuste, portable Lösung besteht darin, Ihre wirklich kritischen Regeln aus dem optimierbaren CSS herauszunehmen und sie selbst geschützt inline einzufügen:
a. Die „niemals anfassen“-Regeln identifizieren
- den standardmäßig ausgeblendeten Zustand jedes interaktiven Elements (
display:none,opacity:0; visibility:hidden…); - den Reset von Buttons/Steuerelementen (
border:0; background:none…); - die vollständige Gestaltung des Elements, sobald es geöffnet ist (damit sie beim allerersten Öffnen bereits korrekt ist);
- machen Sie diese Komponenten eigenständig: Ein Button muss seinen eigenen Style mitbringen, ohne von einer Utility-Klasse abzuhängen, die selbst optimiert werden könnte.
b. Sie inline einfügen, nachdem der head gerendert wurde
Platzieren Sie diese Regeln in einem <style> Block nach dem Aufruf, der den <head> erzeugt (in WordPress: nach wp_head(), meist in header.php). So kommen sie zuletzt an und gewinnen die Kaskade gegenüber dem weiter oben inline eingefügten Critical CSS.
c. Den Block als nicht optimierbar markieren
Teilen Sie der Optimierungs-Engine mit, dass sie ihn nicht anfassen soll. Die meisten respektieren dedizierte Attribute:
<style data-no-optimize="1" data-no-minify="1" data-no-defer="1">
/* hidden state + button reset + full overlay style, hard-coded values */
.search-overlay { opacity: 0; visibility: hidden; /* ... */ }
.search-overlay.is-open { opacity: 1; visibility: visible; }
.search-toggle { border: 0; background: none; color: #1a1a1a; }
</style>d. Die Werte hart kodieren
Verwenden Sie keine CSS-Variablen (var(--gold)) in diesem Block: Wenn Ihr :root selbst durch den Optimizer läuft, kann die Variable undefiniert enden und Ihr Style bricht zusammen. Kodieren Sie die Farbe hart.
Entscheidender Vorteil: Diese Lösung lebt im Theme. Sie funktioniert mit dem Optimizer, ohne den Optimizer, und übersteht einen Tool-Wechsel.
Wo Mantys Core den Unterschied macht
Jede Critical-CSS-Engine steht vor diesem Dilemma: Sie kann nicht erraten, dass ein ausgeblendetes Element per Klick geöffnet wird. Die eigentliche Frage lautet also nicht „passiert das?“ (das passiert bei allen), sondern „gibt Ihnen das Tool saubere Hebel, um damit umzugehen?“.
Mantys Core ist genau dafür gebaut:
es respektiert Blöcke, die markiert sind mit
data-no-optimize/data-no-minify/data-no-defer(genau der oben beschriebene portable Fix-Mechanismus) und behandelt seinen eigenen Critical-Block genauso;es lässt Sie die Neugenerierung gezielt steuern des Critical CSS Seite für Seite, ausgehend von der aktuellen Quelle, ohne in einem veralteten Critical CSS gefangen zu sein;
und es behandelt explizit die Trennung von Mobil / Desktop, statt Sie raten zu lassen, welcher Cache was ausliefert.
Anders gesagt: Es übernimmt die Schwerarbeit des Verschlankens, während es Ihnen chirurgische Kontrolle über die interaktiven Komponenten lässt, statt alles zu entfernen und Ihnen die Reparatur zu überlassen.
Zusammengefasst
- Critical CSS behält nur den Style des beim Laden Sichtbaren. Ihre standardmäßig ausgeblendeten Elemente (Menü, Overlay, Modal) werden als nutzlos eingestuft und entfernt.
- Irreführendes Symptom: Die Regel steht im HTML, wird aber ignoriert: zwei Stylesheets, eine Kaskade, die sich wendet, oder eine schlichte Entfernung.
- Diagnose: Vorsicht bei getrennten Mobil-/Desktop-Caches, dem pro URL gespeicherten Critical CSS, das „clear all“ nicht löscht, und der veralteten Quelle.
- Dauerhafte Lösung: Fügen Sie den ausgeblendeten Zustand + den vollständigen Style der interaktiven Komponenten inline ein, nach
wp_head(), in einem nicht optimierbaren Block, hart kodierten Werten. Sie wandert mit dem Theme mit.