Arrow icons, cascading own CSS, a preload for the hero image, and EB Solar
Built while setting up the redesign of ebsolar.de as the sixth local
installation (scripts/seed-ebsolar.php, reset-ebsolar.sh, ports 8096/8097).
The rebuild surfaced four things in the core:
- The icon set knows three arrows now: arrow-right, arrow-left,
arrow-up-right. The button block and the post navigation render them as
inline SVG inside the same aria-hidden span as before, so a template that
hides the arrow with "& span{display:none}" keeps working. Until now the
arrow was a text glyph that looked different in every font. Umut: "bei
alle Projekte bzw bei allen möchte ich dieses emoji icon weg haben".
- Own CSS with the same nested selector twice kept only the last rule.
"& .post-card{border:0}" followed by "& .post-card{transform:none}" lost
the border - silently, which brought the core's card frame back on the
project grid. The parser now joins the declarations in source order, as
CSS does; the same for "&{…}" next to the element's own properties.
- The eager image over the fold was not preloaded. The background image of
the first section has had a preload link for a while; a plain <img> was
found only after the stylesheet was parsed, and that round trip went
straight into LCP. PageController::heroImage() now writes the same src,
srcset and sizes the block template writes, and page.html.twig emits the
link - unless a background image is already preloaded.
- Measured on the way: an entrance effect on the LCP element costs about
900 ms of render delay. The EB Solar hero image therefore has none.
Tests: 581 green, the icon test accepts quoted keys, two cases for the CSS
cascade, the preload asserted in the big-picture test.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
ab9e6a7ea0
commit
d0019c80af
15 files changed
+1472
-12
No files matched your search
@@ -193,17 +193,34 @@ final class CustomCode
|
||||
if (1 !== preg_match('/^[a-zA-Z0-9 .:>+~_\[\]="\'-]*$/D', $suffix)) {
|
||||
throw new InvalidDocument(sprintf('„&%s“ ist als verschachtelter Selektor nicht erlaubt.', $suffix));
|
||||
}
|
||||
$rules[$suffix] = $this->declarations($match[2][0]);
|
||||
// Zusammenfuegen statt ersetzen: zweimal derselbe Selektor ist in CSS eine Kaskade,
|
||||
// nicht ein Widerruf. Vorher gewann die letzte Regel, und alles, was nur in der
|
||||
// ersten stand, verschwand ohne Meldung - gefunden am Projektraster von EB Solar,
|
||||
// wo `& .post-card{border:0}` und `& .post-card{transform:none}` nebeneinander
|
||||
// standen und der Rahmen des Kerns wieder auftauchte.
|
||||
$rules[$suffix] = $this->verbinden($rules[$suffix] ?? '', $this->declarations($match[2][0]));
|
||||
$rest = substr_replace($rest, '', $match[0][1], strlen($match[0][0]));
|
||||
}
|
||||
if (str_contains($rest, '{') || str_contains($rest, '}')) {
|
||||
throw new InvalidDocument('Eigenes CSS besteht aus Eigenschaften für dieses Element und aus verschachtelten Regeln, die mit & beginnen. Andere Selektoren sind nicht vorgesehen.');
|
||||
}
|
||||
$rules[''] = $this->declarations($rest);
|
||||
// Die Eigenschaften des Elements selbst stehen ueblicherweise vor den verschachtelten
|
||||
// Regeln; eine Regel `&{…}` schreibt sie aber in denselben Schluessel.
|
||||
$rules[''] = $this->verbinden($this->declarations($rest), $rules['']);
|
||||
|
||||
return $rules;
|
||||
}
|
||||
|
||||
/** Zwei Deklarationslisten desselben Selektors, in der Reihenfolge, in der sie standen. */
|
||||
private function verbinden(string $erste, string $zweite): string
|
||||
{
|
||||
if ('' === $erste || '' === $zweite) {
|
||||
return '' === $erste ? $zweite : $erste;
|
||||
}
|
||||
|
||||
return $erste.';'.$zweite;
|
||||
}
|
||||
|
||||
/** @throws InvalidDocument */
|
||||
private function declarations(string $block): string
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user