Banner-Hintergründe CSP-fest: <img> statt Inline-Variable
Beim ersten Deploy blieben die Slides des Banner-Sliders schwarz. Ursache war kein fehlendes Bild, sondern die CSP: public/.htaccess setzt default-src 'self' ohne style-src, der Browser verwirft damit jedes style-Attribut — und die Komponente lieferte Bild und Akzentfarbe genau so (style="--banner-bg: url(…); --banner-accent: #6cbbbc"). Lokal war das unsichtbar, weil php -S keine .htaccess liest. Der Hintergrund ist jetzt ein <img class="ad-banner__bg"> über die bestehende img-Komponente (CSP erlaubt img-src) und bringt srcset mit: das Handy lädt die 640er statt der 1600er, die erste Slide lädt eager mit fetchpriority. Der dunkle Leseverlauf liegt auf ::before statt im background-image. Die Akzentfarbe kann als beliebiger Hex-Wert nicht ohne Inline-Style in die Seite. Sie steht deshalb als Token in tokens.css (wo Farben laut CLAUDE.md hingehören), components.css bildet den Namen darauf ab, und banners.json nennt nur noch "accent": "breadcrumb". bin/preflight.php bricht ab, wenn unter app/ wieder ein style-Attribut auftaucht — der Fehler wäre sonst erneut erst in Produktion sichtbar. Beim Bauen dieser Wache zweimal selbst hineingetappt: ein Muster mit [^>]* bricht an jedem schließenden PHP-Tag ab, und die Zeichenfolge dieses Tags beendet den PHP-Modus auch in einem //-Kommentar (preflight gab ab dort seinen eigenen Quelltext aus, php -l meldete nichts). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NzeVVgMCrzCDJAKeLEdKr7
This commit is contained in:
@@ -2110,21 +2110,49 @@
|
||||
}
|
||||
|
||||
/* Optionaler Hintergrund pro Banner (data: "background").
|
||||
Dunkler Verlauf über dem Bild hält Text & CTA links lesbar. */
|
||||
Das Bild ist ein <img class="ad-banner__bg">, KEIN CSS-Hintergrund: die CSP
|
||||
(default-src 'self', kein style-src) verwirft style-Attribute, eine Inline-Variable
|
||||
--banner-bg kam auf echtem Apache nie an (31.07.2026, Slides blieben schwarz).
|
||||
Der dunkle Verlauf, der Text und CTA links lesbar hält, liegt deshalb auf ::before. */
|
||||
.ad-banner__slide--bg {
|
||||
background-image:
|
||||
linear-gradient(to right, rgb(0 0 0 / 0.82), rgb(0 0 0 / 0.45) 60%, rgb(0 0 0 / 0.3)),
|
||||
var(--banner-bg);
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
/* Bild an der Innenkante kappen, nicht unter den 1px-Rahmen malen
|
||||
(sonst schimmert es an der transparenten Rahmenkante durch). */
|
||||
background-clip: padding-box;
|
||||
position: relative;
|
||||
/* Eigener Stapelkontext: das Bild darf hinter den Inhalt, aber nicht hinter
|
||||
die Slide-Fläche selbst rutschen. */
|
||||
isolation: isolate;
|
||||
border-color: transparent;
|
||||
}
|
||||
|
||||
.ad-banner__bg,
|
||||
.ad-banner__slide--bg::before {
|
||||
position: absolute;
|
||||
/* inset bezieht sich auf die Padding-Box — das Bild endet an der Innenkante und
|
||||
malt nicht unter den 1px-Rahmen (dort schimmerte es sonst durch). */
|
||||
inset: 0;
|
||||
border-radius: inherit;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.ad-banner__bg {
|
||||
z-index: -2;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
object-position: center;
|
||||
}
|
||||
|
||||
.ad-banner__slide--bg::before {
|
||||
content: '';
|
||||
z-index: -1;
|
||||
background-image: linear-gradient(to right, rgb(0 0 0 / 0.82), rgb(0 0 0 / 0.45) 60%, rgb(0 0 0 / 0.3));
|
||||
}
|
||||
|
||||
/* Pro-Slide-Akzentfarbe (data: "accent") — z. B. Sponsor-CI statt Vereins-Rot.
|
||||
--banner-accent kommt als Inline-Variable von der Komponente. */
|
||||
Der Name kommt aus der JSON, die Farbe aus tokens.css: ein Hex-Wert aus der JSON
|
||||
käme nur per Inline-Style in die Seite, und den verwirft die CSP (siehe oben). */
|
||||
.ad-banner__slide--accent-breadcrumb {
|
||||
--banner-accent: var(--clr-banner-accent-breadcrumb);
|
||||
}
|
||||
|
||||
.ad-banner__slide--accent {
|
||||
--clr-accent: var(--banner-accent);
|
||||
--clr-accent-dark: color-mix(in srgb, var(--banner-accent) 82%, #000);
|
||||
@@ -2153,10 +2181,8 @@
|
||||
|
||||
@media (max-width: 768px) {
|
||||
/* Auf Mobil läuft der Verlauf nach unten, damit der gestapelte Text lesbar bleibt. */
|
||||
.ad-banner__slide--bg {
|
||||
background-image:
|
||||
linear-gradient(to bottom, rgb(0 0 0 / 0.82), rgb(0 0 0 / 0.5)),
|
||||
var(--banner-bg);
|
||||
.ad-banner__slide--bg::before {
|
||||
background-image: linear-gradient(to bottom, rgb(0 0 0 / 0.82), rgb(0 0 0 / 0.5));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,14 @@
|
||||
--clr-accent-hsl: 356.7 94.8% 45.5%; /* dasselbe Rot als H S L */
|
||||
--clr-accent-h: 356.7; /* nur der Farbton — die Dateiablage (/dateien)
|
||||
leitet daraus ihre Flächen ab, siehe dateien.css */
|
||||
/* Akzentfarben einzelner Werbe-Banner (Sponsor-CI statt Vereins-Rot).
|
||||
Sie stehen hier und nicht in data/banners.json, weil ein Hex-Wert aus der JSON
|
||||
nur per Inline-Style in die Seite käme — und den verwirft die CSP
|
||||
(default-src 'self', kein style-src). Die JSON nennt nur den Namen
|
||||
("accent": "breadcrumb"), components.css bildet ihn auf dieses Token ab.
|
||||
Neuer Sponsor mit eigener CI = eine Zeile hier plus eine Klasse dort. */
|
||||
--clr-banner-accent-breadcrumb: #6cbbbc;
|
||||
|
||||
--clr-bg: #222222; /* Grund-Hintergrund (mit Textur) */
|
||||
--clr-bg-deep: #161616; /* abgesetzte Sektionen */
|
||||
--clr-bg-footer: #000000;
|
||||
|
||||
Reference in New Issue
Block a user