Karten-Titel
Dieser Text bleibt normal dunkel-auf-weiß, unabhängig von der Tile-Farbe.
Vier Bausteine für typische Marketing-/Landingpage-Abschnitte: .ncss-split (Text neben Bild), .ncss-tile (volle-Breite Farbflächen, bekannt aus UIkit), .ncss-accordion-split (transformierendes Akkordeon, bekannt von apple.com) und .ncss-marginnote (Randnotizen, bekannt von Tufte CSS). Split und Tile lassen sich kombinieren - eine Tile als Hintergrundfläche, darin ein Split-Layout.
.ncss-split-container erzeugt den Container-Query-Kontext (ein Element kann per Spec nicht seine eigene Breite abfragen, siehe Karten, Abschnitt 6 für dieselbe Einschränkung), .ncss-split ist das eigentliche zweispaltige Layout. Ab 36rem CONTAINER-Breite stehen Media und Content nebeneinander, darunter stapeln sie sich automatisch.
<div class="ncss-split-container">
<div class="ncss-split">
<div class="ncss-split-media"><img src="foto.jpg" alt="..."></div>
<div class="ncss-split-content">
<h3>Titel</h3>
<p>Text ...</p>
</div>
</div>
</div>
Fenster/Panel schmaler ziehen, um das Stapeln unter 36rem zu sehen.
Kein Modifier nötig - reine Dokumentreihenfolge, genau wie bei Karten (.ncss-card-media oben/unten). .ncss-split-media als ERSTES Kind = links (und beim Stapeln oben), als LETZTES Kind = rechts (und beim Stapeln unten). Kein row-reverse-Trick, der die Vorlese-/Fokus-Reihenfolge vom visuellen Layout entkoppeln würde.
<!-- Bild rechts: .ncss-split-media einfach als LETZTES Kind -->
<div class="ncss-split">
<div class="ncss-split-content">...</div>
<div class="ncss-split-media">...</div>
</div>
Dieselbe Klasse, nur die Kindreihenfolge im Markup ist getauscht.
--ncss-split-align (Default center) steuert, wie die beiden Spalten zueinander ausgerichtet sind, sobald sie nebeneinander stehen - kein Effekt im gestapelten Zustand. Bequemlichkeits-Klassen für die häufigsten Werte:
| Klasse | Wirkung |
|---|---|
.ncss-split--align-start | Beide Spalten oben ausgerichtet |
.ncss-split--align-end | Beide Spalten unten ausgerichtet |
.ncss-split--align-stretch | Beide Spalten gleich hoch gestreckt |
Für ein asymmetrisches Breiten-Verhältnis (statt 50/50) --ncss-split-media-width direkt auf .ncss-split-media setzen - die Content-Spalte füllt automatisch den Rest, ergibt immer zusammen 100%:
<div class="ncss-split ncss-split--align-start">
<div class="ncss-split-media" style="--ncss-split-media-width: 40%;">...</div>
<div class="ncss-split-content">...</div>
</div>
Media schmaler als die Content-Spalte, beide oben bündig statt zentriert.
Bekannt aus UIkit (uk-tile-default/-muted/-primary/-secondary) - volle-Breite Blöcke zum Gliedern einer langen Seite in klar unterscheidbare Abschnitte. .ncss-tile allein (ohne Modifier) ist die normale Seitenfläche, kein sichtbarer Unterschied zur Umgebung außer dem eigenen Innenabstand.
| Klasse | Entspricht UIkit | Wirkung |
|---|---|---|
.ncss-tile | uk-tile-default | Normale Seitenfläche |
.ncss-tile--muted | uk-tile-muted | --ncss-color-bg-subtle als Hintergrund |
.ncss-tile--brand | uk-tile-primary | Markenfarbe, Text kippt automatisch auf hell |
.ncss-tile--brand-2 | uk-tile-secondary | Zweitfarbe, Text kippt automatisch auf hell |
<section class="ncss-tile ncss-tile--brand">
<h2>Titel</h2>
<p>Text ...</p>
</section>
--brand)Heller Text automatisch, keine eigene Klasse nötig.
--brand-2)Dieselbe automatische Textumschaltung, andere Markenfarbe.
Der automatische helle Text von --brand/--brand-2 ist eine reine Nachfahren-Selektor-Vererbung - ohne Gegenmaßnahme würde er auch in eine verschachtelte weiße .ncss-card hineinlaufen und dort unlesbar werden (derselbe Fallstrick, der zuerst an product.html gefunden wurde, hier von vornherein generisch mitgelöst). .ncss-tile setzt .ncss-card und <pre> DARIN deshalb automatisch auf den normalen dunklen Text zurück:
Dieser Text ist hell.
Dieser Text bleibt normal dunkel-auf-weiß, unabhängig von der Tile-Farbe.
Beide Bausteine sind bewusst unabhängig voneinander - eine Tile als Hintergrundfläche, darin ganz normal ein Split-Layout. Ohne weiteres Zutun bleibt eine Tile innerhalb ihres umgebenden Containers - für volle Bildschirmbreite bis zum Bildschirmrand zusätzlich .ncss-full-bleed auf die Tile kombinieren, das bleibt bewusst eine separate Entscheidung.
<section class="ncss-tile ncss-tile--muted ncss-full-bleed">
<div class="ncss-container">
<div class="ncss-split-container">
<div class="ncss-split">
<div class="ncss-split-media">...</div>
<div class="ncss-split-content">...</div>
</div>
</div>
</div>
</section>
Zwei unabhängige Bausteine, frei kombinierbar.
Bekannt von apple.com - ein Text-Akkordeon, dessen zugehöriges Bild rechts automatisch mit dem gerade geöffneten Punkt wechselt. Komplett nativ, KEIN JavaScript nötig: exklusives Öffnen/Schließen über <details name="..."> (Baseline seit September 2025), das passende Bild wird per :has() ausgewählt - dieselbe Technik, die schon pre:has(> code[class*="language-"]) in den Code-Blöcken auf dieser Seite nutzt. Öffnen/Schließen selbst ist bereits sanft animiert (::details-content). Für einen weichen Übergang beim BILDWECHSEL selbst (statt eines harten Schnitts) optional js/view-transitions.js einbinden - siehe unten.
Komponenten reagieren auf ihren eigenen Platz, nicht auf den Viewport.
Reihenfolge statt Spezifitäts-Kämpfe - kein !important nötig.
Ein Wert pro Token deckt Hell und Dunkel ab - kein zweites Stylesheet.
<div class="ncss-accordion-split-container">
<div class="ncss-accordion-split">
<div class="ncss-accordion-split-list">
<details name="mein-akkordeon" class="ncss-accordion-split-item" open>
<summary>Punkt eins</summary>
<div class="ncss-accordion-split-body">
<p>Text ...</p>
<!-- fürs Stapeln auf Mobile, dasselbe Bild wie unten -->
<div class="ncss-accordion-split-media-mobile"><img src="bild-1.jpg" alt="..."></div>
</div>
</details>
<!-- weitere Punkte, immer dasselbe name="..." -->
</div>
<div class="ncss-accordion-split-media">
<img src="bild-1.jpg" alt="...">
<!-- ein Bild pro Punkt, gleiche Reihenfolge -->
</div>
</div>
</div>
name="..." muss pro Akkordeon-Instanz auf der Seite eindeutig sein (wie eine Radio-Button-Gruppe), sonst gruppieren sich mehrere Akkordeons ungewollt miteinander. Jedes Bild steht bewusst ZWEIMAL im Markup (Desktop-Spalte + mobile Inline-Kopie) - ohne JS lässt sich ein DOM-Knoten nicht zwischen zwei entfernten Containern verschieben. Dieselbe Bild-URL wird trotzdem nur einmal geladen (normales HTTP-Caching), pro Breakpoint ist immer nur eine der beiden Kopien im Layout. Unterstützt bis zu 6 Punkte (mehr wären für dieses Muster ohnehin unüblich).
js/view-transitions.js nutzt Same-Document View Transitions (Chrome/Edge 111+, Safari 18+, Firefox 133+), um den Bildwechsel statt eines harten Schnitts weich zu animieren - Kreuzblende ist der Default (kein Markup nötig), data-transition="slide"/"3d" auf .ncss-accordion-split-container schalten auf Verschieben bzw. einen 3D-Flip um. Ohne Skript oder in Browsern ohne View-Transitions-Unterstützung bleibt der native, sofortige Wechsel erhalten - kein Funktionsverlust. Das Beispiel oben nutzt bereits die Kreuzblende live.
<script src="js/view-transitions.js" defer></script>
<div class="ncss-accordion-split-container" data-transition="slide">
<!-- ... -->
</div>
Technischer Hintergrund (u.a. warum <details> den Klick auf <summary> statt eines beforetoggle-Events abfängt, und wie view-transition-class mehrere Instanzen auf derselben Seite unterscheidet) im Quellcode-Kommentar.
Bild ODER Text bricht aus der Textspalte aus, landet aber NICHT am Bildschirmrand (das leistet bereits .ncss-bleed-start/-end, siehe Layout), sondern in der Randspalte NEBEN dem Fließtext - Sidenote-Muster, bekannt von Tufte CSS, hier unabhängig davon nachgebaut: reines CSS Grid statt fester Pixel-Ränder. .ncss-marginnote-layout ist ein 3-Spalten-Grid (Randspalte / Textspalte / Randspalte); die Textspalte deckelt bei --ncss-container-max-narrow, die beiden Randspalten schrumpfen auf schmalen Containern von selbst auf 0 - normale Kinder (Absätze) bleiben immer in der mittleren Spalte, nur .ncss-marginnote-start/-end springen erst AB einer Mindestbreite des Grids (60rem) in die jeweilige Randspalte, darunter bleiben sie ein normaler Block im Textfluss.
Warum eine Randnotiz automatisch neben dem passenden Absatz landet, ohne ihre Position selbst zu kennen: CSS Grids Auto-Placement platziert Elemente in Dokumentreihenfolge und nutzt dabei dieselbe Zeile weiter, solange die eigene Spalte darin noch frei ist. Das ergibt eine einfache, aber wichtige Markup-Regel (per echtem Test bestätigt, die beiden Randspalten verhalten sich NICHT symmetrisch):
| Klasse | Randspalte | Steht im Markup ... |
|---|---|---|
.ncss-marginnote-end | danach (meist rechts) | DIREKT NACH dem Absatz, zu dem sie gehört |
.ncss-marginnote-start | davor (meist links) | DIREKT VOR dem Absatz, zu dem sie gehört |
Container Queries lassen Komponenten auf ihren eigenen Platz reagieren statt auf den Viewport - dieselbe Idee, die auch dieses Marginnote-Layout selbst nutzt.
Zweiter Absatz, mit einer Notiz links daneben.
Dritter Absatz ganz ohne Randnotiz - der Platz daneben bleibt einfach leer, keine eigene Regel nötig dafür.
<div class="ncss-marginnote-container">
<div class="ncss-marginnote-layout">
<p>Text, zu dem die Randnotiz gehört ...</p>
<aside class="ncss-marginnote-end"><img src="foto.jpg" alt="..."></aside>
<p>Nächster Absatz ...</p>
<aside class="ncss-marginnote-start"><p>Eine reine Text-Randnotiz.</p></aside>
</div>
</div>
Funktioniert genauso mit einem Bild statt Text in der Randnotiz (<aside class="ncss-marginnote-end"><img ...></aside>) - die Randspalte bekommt dann automatisch width:100%; height:auto;. Panel schmaler als 60rem ziehen, um den Fallback zu sehen: darunter stapelt jede Randnotiz einfach an ihrer Stelle im normalen Textfluss, kein kaputter/leerer Zustand.