branch-coexist: 3 neue decks 223015b-2026 / 223015c-2026 / dhbw-2026 daneben main

per user-request einen branch der main-content UND rewrite-content trägt — saubere separierung statt symlink/merge-conflict.

struktur:
- slides/<course>/ → main-content restored, eigene assets (kein new-demo-leak)
- slides/<course>-2026/ → rewrite-content, eigene assets (komplett kopiert + new demos)

Makefile: COURSES += 223015b-2026 223015c-2026 dhbw-2026 mit eigenen NAME/KAPITEL/DEPLOY/KLAUSUR-konfig. Klausur für b+c=1, dhbw=leer. Deploy-paths /hdm/223015b-2026 etc.

make build durchlaufen für alle 6 decks, 0 fehler.

dedup: 223015c+dhbw assets identisch in beiden ordnern (kein neu-demos auf b ergänzt). 223015b 86 → 120 files in -2026 (= +34 neue eroeffner/usb-c-drei-achsen/container-vs-codec/etc).
This commit is contained in:
2026-05-14 21:54:15 +02:00
parent 6209f9f3a0
commit 351e3dfc23
467 changed files with 32391 additions and 4701 deletions
+204 -365
View File
@@ -8,373 +8,217 @@ footer: "Michael Czechowski – SoSe 2026"
---
<style>
:root { --color-foreground: #1a1a2e; --color-highlight: #d63384; --color-dimmed: #4a4a6a; }
section.invert { --color-foreground: #fff; }
section { font-size: 1.4rem; }
h1 { color: #a02060; }
section.invert h1 { color: #fff; }
h2 { color: #1f2937; }
section.invert h2 { color: #f48fb1; }
pre { background: #0f0f23; color: #f48fb1; border-radius: 8px; border-left: 3px solid #d63384; }
pre code { background: transparent; color: inherit; }
code { background: #1a1a2e; color: #f48fb1; padding: 0.15em 0.4em; border-radius: 4px; }
a { color: var(--color-highlight); }
:root {
--color-foreground: #1a1a2e;
--color-highlight: #d63384;
--color-dimmed: #4a4a6a;
}
section.invert {
--color-foreground: #fff;
}
section {
font-size: 1.4rem;
}
h1 {
color: #a02060;
}
section.invert h1 {
color: #fff;
}
h2 {
color: #1f2937;
}
section.invert h2 {
color: #f48fb1;
}
pre {
background: #0f0f23;
color: #f48fb1;
border-radius: 8px;
border-left: 3px solid #d63384;
}
pre code {
background: transparent;
color: inherit;
}
code {
background: #1a1a2e;
color: #f48fb1;
padding: 0.15em 0.4em;
border-radius: 4px;
}
a {
color: var(--color-highlight);
}
</style>
<!-- _class: lead -->
<!-- _class: invert -->
<!-- _header: '' -->
<!-- _backgroundColor: #000 -->
# Kapitel 2 — CSS Extended
## Box-Model · Flexbox · Grid · Responsive · Animations
# Web Engineering
**DHBW Stuttgart** · Informatik / Wirtschaftsinformatik
**Sommersemester 2026** · Sitzung 2 — HTML & CSS (Frameworks)
---
# Recap Kap 1
# Ressourcen zum Selbstlernen
| Bereich | Was wir kennen |
|---------|----------------|
| Anatomie | `selector { property: value }` |
| Selektoren | element, `.class`, `#id`, `:hover` |
| Spezifizität | inline > id > class > element |
| Farben | hex, rgb, hsl, oklch |
| Einheiten | px, rem, em, %, vw, vh |
**Heute:** Layout + Animation in Tiefe.
- **CODE CRISPIES** — [codecrispi.es](https://codecrispi.es/)
- **Online Code-Editor** — [codepen.io](https://codepen.io/pen/)
- **MDN** (Mozilla Developer Network) — [developer.mozilla.org/de/](https://developer.mozilla.org/de/)
- **Flexbox-Spiel** — [flexboxfroggy.com](https://flexboxfroggy.com/)
- **Grid-Spiel** — [cssgridgarden.com](https://cssgridgarden.com/)
---
# Box-Model — die Erinnerung
# Inhalt
```
┌──────────────────┐
│ margin │
│ ┌────────────┐ │
│ │ border │ │
│ │ ┌────────┐ │ │
│ │ │padding │ │ │
│ │ │content │ │ │
│ │ └────────┘ │ │
│ └────────────┘ │
└──────────────────┘
```
Aufbauend auf den Grundlagen aus Sitzung 1.
`box-sizing: border-box` global setzen.
1. Attribut-Selektoren
2. Combinators (vertieft)
3. Pseudo-Klassen — erweitert
4. Shorthand Properties
5. Flexbox-Shorthands
6. Custom Properties (Variables)
7. CSS Functions (`calc`, `clamp`, ...)
8. Transition & Animation
9. CSS Frameworks (Tailwind & Co.)
---
# Box-Model in Code
<!-- _class: invert -->
<!-- _backgroundColor: #000 -->
# CSS: Extended
---
# CSS Selectors – Attribut-Selektoren
```css
* { box-sizing: border-box; }
/* presence */
[disabled] { opacity: 0.5; }
.card {
width: 320px; /* inkl. padding + border */
padding: 1.5rem;
border: 2px solid #ccc;
border-radius: 0.75rem;
margin: 1rem auto; /* Außen + horizontal zentriert */
}
/* exact value */
[type="email"] { border-color: blue; }
/* contains word */
[class~="btn"] { cursor: pointer; }
/* starts with */
[href^="https"] { color: green; }
/* ends with */
[src$=".png"] { border: 1px solid #ccc; }
/* contains substring */
[class*="icon"] { padding-left: 20px; }
```
Inspector im DevTools zeigt das Box-Model live an.
---
<!-- _class: lead -->
# Flexbox
## 1D-Layout (Reihe ODER Spalte)
---
# Flexbox — Basics
# CSS Combinators
```css
.container {
display: flex;
gap: 1rem; /* Abstand zwischen Items */
flex-direction: row; /* row | column */
justify-content: space-between; /* Haupt-Achse */
align-items: center; /* Quer-Achse */
flex-wrap: wrap; /* umbruchen erlaubt */
}
```
/* Child (direkt) */
div > p { margin: 0; }
```html
<div class="container">
<div>1</div>
<div>2</div>
<div>3</div>
</div>
/* Descendant (Nachkomme) */
div p { margin: 0; }
/* Next Sibling */
h1 + p { font-size: 1.2em; }
/* Subsequent Sibling */
h1 ~ p { color: #666; }
/* Selector List */
h1, h2, h3 { font-weight: bold; }
```
---
# Flexbox — Achsen
**`flex-direction: row` (default):** Haupt-Achse horizontal.
```
┌─────────────────────────────────────┐
│ ◄── justify-content ──► │
│ ▲ │
│ │ │
│ align-items │
│ │ │
│ ▼ │
└─────────────────────────────────────┘
```
`column`: Achsen drehen sich 90°.
---
# Flexbox — Item-Properties
# Pseudo Classes – Erweitert
```css
.item {
flex: 1; /* nimm gleiche Anteile vom verfügbaren Raum */
flex: 0 0 200px; /* fest 200px, kein wachsen, kein schrumpfen */
flex-grow: 2; /* doppelte Anteile */
order: -1; /* visuell zuerst, im DOM hinten */
align-self: end; /* override align-items für DIESES Item */
}
```
/* Form States */
:valid { border-color: green; }
:invalid { border-color: red; }
:placeholder-shown { color: #999; }
**Shorthand:** `flex: <grow> <shrink> <basis>`.
/* Content */
:before { content: "→ "; }
:after { content: " [Wichtig]"; }
:first-letter { font-size: 2em; }
:first-line { font-weight: bold; }
/* NOT */
:not(.disabled) { pointer-events: auto; }
:not(:last-child) { border-bottom: 1px solid #ccc; }
```
---
# Typische Flex-Patterns
# Shorthand Properties
```css
/* Navigation: Logo links, Items rechts */
.nav { display: flex; justify-content: space-between; }
/* margin: top right bottom left */
margin: 10px 20px 10px 20px;
/* Karte: Bild + Text nebeneinander */
.card { display: flex; gap: 1rem; align-items: center; }
/* centering */
margin: 0 auto;
/* Button-Gruppe: alle gleich groß */
.btn-group { display: flex; gap: 0.5rem; }
.btn-group button { flex: 1; }
/* padding same */
padding: 20px;
/* Footer: gleichmäßig verteilt */
.footer { display: flex; justify-content: space-around; }
/* border: width style color */
border: 1px solid #333;
/* background: color image position/size repeat */
background: #fff url(logo.png) 0 0 no-repeat;
/* font: style variant weight size/line-height family */
font: italic normal bold 16px/1.5 Arial, sans-serif;
```
---
<!-- _class: lead -->
# Grid
## 2D-Layout (Reihe UND Spalte)
---
# Grid — Basics
# Flexbox Shorthands
```css
.container {
display: grid;
grid-template-columns: 1fr 2fr 1fr; /* 3 Spalten, Verhältnis 1:2:1 */
grid-template-rows: auto 1fr auto; /* Header, Body, Footer */
gap: 1rem;
}
/* flex: grow shrink basis */
flex: 1 0 auto;
/* place-items: align-items justify-items */
place-items: center stretch;
/* place-content: align-content justify-content */
place-content: space-between center;
/* gap: row-gap column-gap */
gap: 20px 40px;
```
`fr` = Fraction Unit — verbleibender Raum aufgeteilt.
---
# Grid — Areas (named layout)
```css
.layout {
display: grid;
grid-template-areas:
"header header"
"nav main"
"footer footer";
grid-template-columns: 200px 1fr;
}
.layout header { grid-area: header; }
.layout nav { grid-area: nav; }
.layout main { grid-area: main; }
.layout footer { grid-area: footer; }
```
Lesbarer als Spalten-/Zeilen-Nummern.
---
# Grid — Auto-Layout
```css
/* So viele Spalten wie reinpassen, jede min. 200px */
.gallery {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 1rem;
}
```
Mobile: 1 Spalte. Tablet: 2-3. Desktop: 4-5. **Ohne Media Queries.**
---
# Flexbox vs. Grid
| | Flexbox | Grid |
|--|---------|------|
| Dimension | 1D | 2D |
| Use-Case | Navigation, Karten-Reihe, Button-Gruppe | Seiten-Layout, komplexes Raster |
| Item-Größe | flexibel | meist fest |
| Direction | row/column | rows + columns |
**Beide in einem Layout möglich:** Grid für Seite, Flexbox in Komponenten.
---
<!-- _class: lead -->
# Responsive Design
---
# Mobile-First mit Media Queries
```css
/* Default: Mobile */
.sidebar { display: none; }
.content { padding: 1rem; }
/* Tablet aufwärts */
@media (min-width: 768px) {
.sidebar { display: block; width: 240px; }
.content { padding: 2rem; }
}
/* Desktop */
@media (min-width: 1280px) {
.sidebar { width: 320px; }
}
```
**Mobile-First**: kleinste Größe als Default, dann größer.
---
# Viewport-Meta
```html
<meta name="viewport" content="width=device-width, initial-scale=1">
```
**Pflicht** im `<head>`. Ohne dieses Meta zoomt iPhone & Android alles auf 980 px Breite.
---
# Fluid Sizing — ohne Media Queries
```css
/* Font: skaliert zwischen 14px und 22px */
h1 { font-size: clamp(1.4rem, 2.5vw + 1rem, 2.5rem); }
/* Padding: skaliert mit Viewport */
.card { padding: clamp(1rem, 3vw, 3rem); }
/* Breite: nie mehr als 70 Zeichen für Lesetext */
.prose { max-width: 70ch; margin: auto; }
```
`clamp(min, ideal, max)` ist modernes Allzweck-Werkzeug.
---
<!-- _class: lead -->
# Animationen
---
# Transitions — sanfter Wechsel
```css
button {
background: hotpink;
transition: background 0.2s ease, transform 0.15s;
}
button:hover {
background: deeppink;
transform: translateY(-2px);
}
```
**Was animiert performant:** `transform`, `opacity`. **Was nicht:** `width`, `height`, `top/left`.
---
# Keyframe-Animationen
```css
@keyframes pulse {
0% { transform: scale(1); opacity: 1; }
50% { transform: scale(1.1); opacity: 0.7; }
100% { transform: scale(1); opacity: 1; }
}
.notification {
animation: pulse 1.5s ease infinite;
}
```
`animation: <name> <duration> <timing> <iteration>`.
---
# Reduced Motion — Pflicht
Nicht alle wollen Animationen. (Vestibuläre Probleme, ADHS, Migräne.)
```css
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}
```
**Standard-Bestandteil** jeder Seite — ein User-Setting respektieren.
---
<!-- _class: lead -->
# CSS-Variablen + Modern
---
# Custom Properties (CSS Variables)
# CSS Custom Properties (Variables)
```css
:root {
--primary: hotpink;
--gap: 1rem;
--radius: 0.75rem;
--primary-color: #d63384;
--spacing: 20px;
--radius: 8px;
}
button {
background: var(--primary);
padding: var(--gap);
.button {
background: var(--primary-color);
padding: var(--spacing);
border-radius: var(--radius);
}
/* Dark Mode: nur Variablen umsetzen */
@media (prefers-color-scheme: dark) {
:root { --primary: deeppink; }
}
```
---
@@ -382,72 +226,67 @@ button {
# CSS Functions
```css
.box {
width: calc(100% - 2rem); /* Mathe */
font-size: clamp(1rem, 2vw, 2rem); /* min, ideal, max */
background: linear-gradient(45deg, hotpink, deeppink);
color: oklch(0.7 0.2 30); /* moderner Farbraum */
filter: blur(2px) brightness(1.2); /* Bildeffekte */
/* calc */
width: calc(100% - 40px);
/* min/max/clamp */
width: min(100%, 600px);
font-size: clamp(14px, 2vw, 20px);
/* var with fallback */
color: var(--text-color, #333);
/* rgb/rgba/hsl/hsla */
color: hsl(200, 100%, 50%);
background: rgba(0, 0, 0, 0.5);
```
---
# Transition & Animation
```css
/* transition: property duration timing-function */
transition: all 0.3s ease-in-out;
transition: background 0.2s, transform 0.1s;
/* animation */
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
.fade-in {
animation: fadeIn 0.5s ease-out;
}
```
---
# CSS-Frameworks
# CSS Frameworks
| Framework | Stil |
|-----------|------|
| **Tailwind CSS** | Utility-Klassen direkt im HTML |
| **Bootstrap** | Komponenten-Bibliothek (klassisch) |
| **Pico** | klassen-frei, semantisches HTML reicht |
| **Open Props** | CSS-Variablen-Set |
| **Bootstrap** | Komponenten + Grid, opinionated |
| **Tailwind CSS** | Utility-First, atomar |
| **Bulma** | klassisch, ohne JS |
| **shadcn/ui** | kopierbare Komponenten (Tailwind-basiert) |
| **Flowbite** | Tailwind-Komponentenbib. |
---
# Tailwind CSS – Beispiel
```html
<!-- Tailwind: alle Styles als Klassen -->
<button class="bg-pink-500 hover:bg-pink-600 px-4 py-2 rounded-md">
Klick
<button class="bg-blue-600 hover:bg-blue-700
text-white font-semibold
px-4 py-2 rounded-lg
transition shadow-sm">
Klick mich
</button>
```
---
- Keine eigenen CSS-Klassen mehr
- JIT-Compiler erzeugt nur genutzte Klassen
- Design-System via `tailwind.config.js`
# Tailwind — Argumente dafür/dagegen
**Pro:**
- Schnell, weniger Context-Switch (HTML + CSS in einer Datei)
- Konsistent (Design-System eingebaut)
- Tree-Shaking → kleines Bundle
**Contra:**
- HTML voller Klassen — schwerer zu lesen
- Lernkurve eigene
- Versions-Lock-in mit Setup
**Faustregel:** für neue Projekte ausprobieren, vorhandene Projekte nicht zwanghaft migrieren.
---
<!-- _class: aufgabe -->
# Selbstlernen — Layout-Übung
1. **Flexbox-Spiel:** [flexboxfroggy.com](https://flexboxfroggy.com) — alle 24 Level durch.
2. **Grid-Spiel:** [cssgridgarden.com](https://cssgridgarden.com) — 28 Level durch.
3. **Eigene Karten-Galerie:** `repeat(auto-fit, minmax(...))` Pattern anwenden.
**Bonus:** Dark-Mode mit CSS-Variablen + `prefers-color-scheme`.
---
# Zusammenfassung
**Heute gelernt:**
- Box-Model + `box-sizing: border-box` global
- **Flexbox** für 1D-Layouts (Navigation, Karten-Reihen)
- **Grid** für 2D-Layouts (Seiten-Layout, Galerien)
- Mobile-First Media Queries + `clamp()` für fluid
- Transitions + Keyframes — `prefers-reduced-motion` respektieren
- CSS-Variablen für Theming
- Tailwind & Co. als moderner Framework-Stil
**Nächste Stunde:** Node.js — JavaScript außerhalb des Browsers.