Files
uni/slides/dhbw/02_html_css.md
T

1182 lines
24 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
marp: true
theme: gaia
paginate: true
backgroundColor: #fff
header: "Web Engineering – DHBW Stuttgart"
footer: "Michael Czechowski – SoSe 2026"
title: HTML & CSS
---
<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);
}
</style>
<!-- _class: invert -->
<!-- _header: '' -->
<!-- _backgroundColor: #000 -->
![bg cover opacity:0.2](./assets/background.png)
# Web Engineering
**DHBW Stuttgart** · Informatik / Wirtschaftsinformatik
**Sommersemester 2026** · Sitzung 2 — HTML & CSS
[https://librete.ch/dhbw/](https://librete.ch/dhbw/)
---
<!-- _header: '' -->
<!-- _footer: '' -->
![bg fit](./assets/qr/slides-dhbw.png)
---
# Ressourcen zum Selbstlernen
- **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/)
<!-- _class: invert -->
<!-- _header: '' -->
<!-- _backgroundColor: #000 -->
# HTML – Hypertext Markup Language
---
# Was ist HTML? (1/2)
**H**yper**T**ext **M**arkup **L**anguage
- **Keine** Programmiersprache
- Am ehesten eine Formattierungssprache
- Beschreibt **Struktur und Aufbau** einer Webseite
```html
<p>Das ist ein Absatz.</p>
<input type="date" />
```
Erfunden 1989 von Tim Berners-Lee. Aktuelle Version: HTML5 (seit 2014).
---
# Was ist HTML? (2/2)
- Mit HTML werden **HTML-Dokumente** beschrieben (`index.html`)
- Ein HTML-Dokument beschreibt das **Document Object Model (DOM)**
- Der DOM ist eine **hierarchische Baumstruktur** (Eltern, Kinder, Geschwister)
- *parent* nodes / elements
- *child* nodes / elements
- *sibling* nodes / elements
<small>In HTML sprechen wir von **Elementen**, in JavaScript eher von **Nodes**.</small>
---
# HTML-Anatomie (1/2)
```
Opening tag Closing tag
│ │
▼ ▼
<p> My cat is very grumpy </p>
└────────┬─────────┘
Content
└─────────────────────────────────┘
Element
```
- **Opening tag** + **Content** + **Closing tag** = **Element**
- Öffnende und schließende Tags müssen identisch sein
- Schließendes Tag hat ein `/` nach der Spitzklammer
---
# HTML-Anatomie — Attribute
```
Attribute
┌───────────────┐
<p class="editor-note"> My cat is very grumpy </p>
```
- **Attribute** stehen im opening tag
- Format: `name="wert"` (Anführungszeichen empfohlen)
- Mehrere Attribute durch Leerzeichen getrennt: `<input type="text" name="email" required>`
---
# HTML-Anatomie (2/2)
Wir unterscheiden **umschließende** und **selbst-schließende** Tags.
**Umschließend:**
- `<b> ... </b>` – fett-gedruckter Text (inline)
- `<a> ... </a>` – Hyperlink
- `<body> ... </body>` – sichtbarer Teil eines HTML-Dokuments
- `<details> ... </details>` – Aufklapp-Text / Akkordion
**Selbst-schließend:**
- `<img />` – Bild, Vektorgrafik
- `<input />` – Eingabefeld
- `<meta />` – Metadaten
---
# Darstellungsebene und Metadaten
```html
<html>
<head>
METADATEN
</head>
<body>
DARSTELLUNGSEBENE
</body>
</html>
```
Ein HTML-Dokument besteht aus zwei Teilen:
- `<head> ... </head>` – Metadaten für Browser, Suchmaschinen, Social Sharing
- `<body> ... </body>` – darzustellender Inhalt, Text, Formulare
---
# HTML Metadaten
```html
<html>
<head>
<title>DHBW Stuttgart</title>
<meta name="description" content="Studium mit Praxis" />
<meta property="og:image" content="https://...." />
</head>
...
</html>
```
<small>*Webseiten besuchen nicht nur Menschen, sondern auch Suchmaschinen, Bots, Screen-Reader. Metadaten helfen beim "Verstehen" der Inhalte.*</small>
---
# HTML Metadaten – Vertiefung
| Tag | Funktion |
|-----|----------|
| `<title>` | Browser-Tab, Suchergebnis-Titel |
| `<meta charset>` | Zeichenkodierung (Umlaute!) |
| `<meta viewport>` | Mobile Darstellung |
| `<meta description>` | Suchergebnis-Snippet (max 160 Zeichen) |
**Open Graph** (Social-Media-Vorschau):
```html
<meta property="og:title" content="Artikel-Titel">
<meta property="og:image" content="https://example.com/preview.jpg">
```
→ Wirkt auf Mastodon, LinkedIn, Signal, Slack, MS Teams ...
**SEO:** Google nutzt `<title>` + `<meta description>` für Ranking + Snippet.
---
# HTML-Tags und Attribute
![bg right:35%](./assets/demos/tag-attribut.png)
```html
<body>
<p class="wichtig">Das ist ein wichtiger Absatz.</p>
<p>Das ist ein gewöhnlicher Absatz.</p>
</body>
```
| Teil | Bezeichnung |
|------|-------------|
| `<p>` | Opening Tag |
| `class="wichtig"` | Attribut |
| `Das ist ein wichtiger Absatz.` | Inhalt |
| `</p>` | Closing Tag |
---
# HTML-Tags und Attribute (selbst-schließend)
![bg right:35%](./assets/demos/input-date.png)
```html
Geburtsdatum <input type="date" />
```
| Teil | Bezeichnung |
|------|-------------|
| `<input ...` | Eingabefeld |
| `type="date"` | Attribut *type* mit Wert *date* |
| `... />` | Schließendes `/` im (öffnenden) Tag |
---
# Vollständiges Grundgerüst
![bg right:35%](./assets/demos/grundgeruest.png)
```html
<!DOCTYPE html>
<html lang="de">
<head>
<title>Portfolio von ...</title>
<meta name="description" content="..." />
<meta property="og:image" content="https://...." />
</head>
<body>
<h1>Hallo Welt!</h1>
<p>Das ist mein erster Absatz.</p>
</body>
</html>
```
---
# Die wichtigsten Tags
| Tag | Bedeutung |
|-----|-----------|
| `<h1>` … `<h6>` | Überschriften (h1 = größte) |
| `<p>` | Absatz (Paragraph) |
| `<a href="..."> ... </a>` | Hyperlink |
| `<img src="..." />` | Bild |
| `<ul>`, `<ol>`, `<li>` | Listen |
| `<div>` | Container / Box |
| `<span>` | Inline-Container |
| `<input type="...">` | Eingabefeld |
<small>Semantische Tags (`<header>`, `<main>`, `<article>`, `<footer>`, `<nav>`, `<aside>`) wichtig für Accessibility.</small>
---
# Natives HTML
Was früher mit JavaScript gelöst wurde, kann HTML heute selbst. JS dafür einzusetzen ist heute oft ein **Code Smell**.
| Funktion | HTML-Element |
|----------|--------------|
| Aufklapp-Text | `<details>` + `<summary>` |
| Popup / Modal | `<dialog>` |
| Fortschrittsbalken | `<progress>` |
| Datum-Auswahl | `<input type="date">` |
| Validierung | Attribute: `required`, `min`, `max`, `pattern` |
---
# Beispiel: Details/Summary
<small>*Akkordion · Accordion · Aufklappmenü · Collapsible*</small>
![bg right:35%](./assets/demos/details-closed.png)
```html
<details>
<summary>Klick mich!</summary>
<p>Dieser Text ist versteckt.</p>
</details>
```
<small>Doku: [developer.mozilla.org](https://developer.mozilla.org/de/docs/Web/HTML/Reference/Elements/details)</small>
---
# Beispiel: Details/Summary (geöffnet)
![bg right:35%](./assets/demos/details-open.png)
```html
<details open>
<summary>Klick mich!</summary>
<p>Dieser Text war versteckt.</p>
</details>
```
---
# Beispiel: Button
![bg right:35%](./assets/demos/button.png)
```html
<button>Add to favorites</button>
```
<small>Doku: [developer.mozilla.org](https://developer.mozilla.org/de/docs/Web/HTML/Reference/Elements/button)</small>
---
# Beispiel: Input/Eingabefeld
![bg right:35%](./assets/demos/input.png)
```html
<input
type="text"
maxlength="8"
size="10" />
```
<small>Doku: [developer.mozilla.org](https://developer.mozilla.org/de/docs/Web/HTML/Reference/Elements/input)</small>
---
# Beispiel: Dialog
<small>*Modal · Modales Fenster · Popup · Overlay · Dialogfenster*</small>
![bg right:35%](./assets/demos/dialog.png)
```html
<dialog open>
<p>Greetings, one and all!</p>
<form method="dialog">
<button>OK</button>
</form>
</dialog>
```
<small>Doku: [developer.mozilla.org](https://developer.mozilla.org/de/docs/Web/HTML/Reference/Elements/dialog)</small>
---
<!-- _class: invert -->
<!-- _header: '' -->
<!-- _backgroundColor: #000 -->
# Barrierefreiheit
## Accessibility (a11y)
---
# Wie nutzen Menschen das Web?
| Eingabe | Nutzungsweise |
|---------|---------------|
| **Maus** | Klicken, Scrollen |
| **Tastatur** | Tab-Navigation, Enter, Pfeiltasten |
| **Screenreader** | NVDA, VoiceOver, TalkBack, Orca |
| **Sprachsteuerung** | "Klicke auf Anmelden" |
| **Augensteuerung** | Eye-Tracking |
| **Switch-Geräte** | Ein-/Aus-Schalter (motorische Einschränkungen) |
→ Nicht alle Menschen nutzen Maus oder Touchscreens gleichermaßen.
---
# Web-Zugänglichkeit — Statistik
WHO: ca. **15 % der Weltbevölkerung** mit Behinderung — über **1 Milliarde** potenzielle Nutzer:innen.
| Typ | Permanent | Temporär | Situativ |
|-----|-----------|----------|----------|
| Visuell | Blindheit | Augen-OP | Grelle Sonne |
| Motorisch | Amputation | Gebrochener Arm | Kind auf dem Arm |
| Auditiv | Taubheit | Ohrenentzündung | Laute Umgebung |
| Kognitiv | Legasthenie | Müdigkeit | Ablenkung |
**Curb-Cut-Effekt:** Bordsteinabsenkung für Rollstühle hilft auch Kinderwagen, Rollkoffern, Fahrrädern.
---
# Warum Barrierefreiheit?
**Rechtlich (DE / EU):**
- **EAA** — European Accessibility Act, in Kraft seit 28.06.2025
- **BFSG** — DE-Umsetzung des EAA, betrifft auch Privatwirtschaft
- **BITV 2.0** — Barrierefreie Informationstechnik-Verordnung (öff. Stellen)
- Bußgelder bis **100.000 €**
**Ethisch:** Teilhabe und digitale Inklusion.
**Praktisch:**
- Bessere UX für **alle** (mobile, ältere Menschen, situative Einschränkungen)
- SEO-Bonus durch semantisches HTML, Alt-Texte
- Größerer Markt — ca. 15 % der Bevölkerung
---
# WCAG: Der Standard
**W**eb **C**ontent **A**ccessibility **G**uidelines · Herausgeber: W3C / WAI
**Aktuell:** WCAG 2.2 (verbindlich seit Okt. 2023). WCAG 3 in Working-Draft.
**4 Prinzipien (POUR):**
| Prinzip | Bedeutung |
|---------|-----------|
| **P**erceivable | Wahrnehmbar — Inhalte müssen erkennbar sein |
| **O**perable | Bedienbar — Funktionen müssen nutzbar sein |
| **U**nderstandable | Verständlich — Inhalte müssen klar sein |
| **R**obust | Robust — funktioniert mit verschiedenen Technologien |
**Konformitätslevel:** A · **AA** (gesetzlicher Standard) · AAA
→ [w3.org/WAI/WCAG22/quickref](https://www.w3.org/WAI/WCAG22/quickref/)
---
# Perceivable: Wahrnehmbar
![bg right:35% fit](./assets/demos/contrast-levels.png)
**Texte:**
- **Kontrast:** mindestens 4,5:1 für normalen Text
- **Untertitel** für Videos
- Inhalte bei **200 % Zoom** noch nutzbar
**Textalternativen für Nicht-Text:**
```html
<img src="tankman.jpg"
alt="Ein Mann mit Einkaufstüten steht
allein vor einer Reihe Panzer —
Tiananmen, Peking, 5. Juni 1989">
```
→ Leeres `alt=""` für rein dekorative Bilder.
---
# Operable: Bedienbar
![bg right:35%](./assets/demos/a11y-focus.png)
**Tastaturzugänglich:**
```css
/* Fokus-Ring nur bei Tastatur-Navigation */
button:focus-visible {
outline: 3px solid #d63384;
outline-offset: 3px;
border-radius: 4px;
}
/* Anti-Pattern */
button:focus { outline: none; }
```
**Genügend Zeit:** Session-Timeouts ankündigen, Verlängerung ermöglichen.
**Kein Flackern:** maximal 3×/Sekunde (epileptische Anfälle vermeiden).
---
# Understandable: Verständlich
![bg right:35%](./assets/demos/a11y-error.png)
**Sprache angeben:**
```html
<html lang="de">
```
**Konsistente Navigation** — gleiche Elemente an gleicher Stelle.
**Fehler erklären:**
```html
<input type="email" aria-describedby="email-error">
<p id="email-error" role="alert">
Bitte eine gültige E-Mail-Adresse eingeben.
</p>
```
---
# Robust: Technisch solide
![bg right:35%](./assets/demos/a11y-semantic.png)
**Semantisches HTML:**
```html
<!-- Schlecht -->
<div class="button" onclick="...">Klick mich</div>
<!-- Gut -->
<button type="button">Klick mich</button>
```
**ARIA — nur wenn nötig:**
```html
<div role="tablist" aria-label="Produktkategorien">
<button role="tab" aria-selected="true">Schuhe</button>
<button role="tab" aria-selected="false">Jacken</button>
</div>
```
→ Erste ARIA-Regel: **wenn möglich, natives HTML nutzen**.
---
# Barrierefreiheit testen — Werkzeuge
**Automatisierte Tools** (finden ca. 30 % der Verstöße):
| Tool | Typ | Findet |
|------|-----|--------|
| [WAVE](https://wave.webaim.org/) | Browser-Extension | Kontrast, Struktur, Tab-Reihenfolge |
| [Lighthouse](https://developer.chrome.com/docs/lighthouse/overview) | Chrome DevTools | Performance + A11y-Audit |
| [axe DevTools](https://www.deque.com/axe/devtools/) | Browser-Extension | Detailanalyse, Regel-Engine |
| [Pa11y](https://pa11y.org/) | CLI | CI/CD-Integration |
**Screenreader (OS-nativ oder Open Source):**
| OS | Screenreader |
|----|--------------|
| macOS / iOS | VoiceOver (`Cmd + F5`) — builtin |
| Windows | [NVDA](https://www.nvaccess.org/) (OSS) · Narrator (builtin) |
| Linux | [Orca](https://orca.gnome.org/) — GNOME builtin |
| Android | TalkBack — builtin |
---
# Barrierefreiheit testen
Automatisierte Tools finden nur etwa **30 %** der Probleme. Manuelles Testen unverzichtbar — Gold-Standard: echte Nutzer:innen mit Assistiven Technologien.
**Tastatur-Test** — Maus weglegen, nur Tab / Shift+Tab / Enter / Pfeiltasten:
![w:900 center](./assets/demos/keyboard-a11y.png)
---
<!-- _class: invert -->
<!-- _header: '' -->
<!-- _backgroundColor: #000 -->
# CSS – Cascading Style Sheets
---
# Was ist CSS?
**C**ascading **S**tyle **S**heets
```css
p {
color: blue;
font-size: 16px;
}
```
- Trennt **Inhalt** (HTML) von **Darstellung** (CSS)
- "Cascading" = Regeln können überschrieben werden
- Eine CSS-Datei kann viele HTML-Seiten stylen
---
# CSS einbinden
**Option 1: Externe Datei** (empfohlen)
```html
<link rel="stylesheet" href="style.css">
```
**Option 2: Style-Tag**
```html
<style>p { color: blue; }</style>
```
**Option 3: Inline** (vermeiden)
```html
<p style="color: blue;">...</p>
```
→ Standard ist externe Datei. Inline vermeiden (schwer zu warten, keine Wiederverwendung).
---
# CSS-Anatomie
```css
/* ID selector */
#description {
color: orangered;
/* │ └──── Indicates the value of the expression
│
└──── Indicates the property of the expression */
}
```
- **Selector** — was wird gestylt (`#description` = Element mit `id="description"`)
- **Property** — welche Eigenschaft (`color`)
- **Value** — welcher Wert (`orangered`)
- **Declaration** — `property: value;` (Semikolon trennt Deklarationen)
- **Declaration block** — alles zwischen `{` und `}`
---
# Selektoren: Element
![bg right:35%](./assets/demos/css-selector-element.png)
```css
/* Alle <p>-Elemente */
p {
color: gray;
}
/* Mehrere Elemente gleichzeitig */
h1, h2, h3 {
font-family: sans-serif;
}
```
Element-Selektoren sind die einfachsten. Komma = "oder".
---
# Selektoren: Klasse
![bg right:35%](./assets/demos/css-selector-class.png)
```html
<p class="wichtig">Dieser Text ist wichtig.</p>
<p>Dieser nicht.</p>
```
```css
.wichtig {
color: red;
font-weight: bold;
}
```
**Punkt** vor dem Namen = Klasse. Beliebig oft anwendbar; ein Element kann mehrere Klassen haben.
---
# Selektoren: ID
![bg right:35%](./assets/demos/css-selector-id.png)
```html
<nav id="hauptnavigation">...</nav>
```
```css
#hauptnavigation {
background: #333;
padding: 1rem;
}
```
**Raute** vor dem Namen = ID.
**Hinweis:** IDs sollten **einmalig** pro Seite sein. In der Praxis: Klassen meist besser.
---
# Selektoren: Kombinationen
![bg right:35%](./assets/demos/css-combinators.png)
```css
/* Nachfahre (beliebig tief verschachtelt) */
article p { line-height: 1.6; }
/* Direktes Kind (eine Ebene) */
nav > a { text-decoration: none; }
/* Nächstes Geschwister */
h2 + p { font-size: 1.2rem; }
/* Element mit Klasse */
p.wichtig { color: red; }
```
---
# Spezifität: Welche Regel gewinnt?
![bg right:35%](./assets/demos/css-specificity.png)
| Selektor | Spezifität |
|----------|------------|
| Element (`p`) | 0,0,0,1 |
| Klasse (`.wichtig`) | 0,0,1,0 |
| ID (`#header`) | 0,1,0,0 |
| Inline (`style="..."`) | 1,0,0,0 |
```css
p { color: blue; } /* 0,0,0,1 */
.text { color: green; } /* 0,0,1,0 → gewinnt */
#intro { color: red; } /* 0,1,0,0 → gewinnt über beide */
```
---
# CSS Spezifität – Vertiefung
| Selektor | Inline | IDs | Klassen | Elemente | Gesamt |
|----------|--------|-----|---------|----------|--------|
| `p` | 0 | 0 | 0 | 1 | 0,0,0,1 |
| `.info` | 0 | 0 | 1 | 0 | 0,0,1,0 |
| `p.info` | 0 | 0 | 1 | 1 | 0,0,1,1 |
| `#header` | 0 | 1 | 0 | 0 | 0,1,0,0 |
| `#header .nav a` | 0 | 1 | 1 | 1 | 0,1,1,1 |
**Regeln:**
- Eine Klasse (0,0,1,0) schlägt **jede Anzahl** Elemente (0,0,0,99)
- Eine ID schlägt jede Anzahl Klassen
- `!important` bricht alles → vermeiden
**Best Practice:** Flache Spezifität. BEM-Methodik (`.block__element--modifier`) hält sie niedrig.
---
# Box-Modell
![bg right:42% fit](./assets/demos/box-model-diagram.png)
Jedes HTML-Element ist eine rechteckige **Box**.
**Schichten innen → außen:**
- **content** – Inhalt (Text, Bild)
- **padding** – Innenabstand
- **border** – Rahmen
- **margin** – Außenabstand
<small>Gesamt-Breite = `width + padding + border + margin`. Tipp: `box-sizing: border-box` rechnet padding + border mit ein.</small>
---
# Box-Modell: CSS
![bg right:35%](./assets/demos/css-box-model.png)
```css
.box {
width: 200px;
height: 100px;
padding: 20px;
border: 2px solid black;
margin: 10px;
}
```
**Wichtig:**
```css
* {
box-sizing: border-box;
}
```
→ width/height inkludiert padding + border.
---
# Farben
![bg right:35%](./assets/demos/css-colors.png)
CSS kennt fünf Notationen für Farben: **Keyword**, **Hex**, **RGB**, **RGBA** (mit Transparenz) und **HSL**.
```css
/* Keyword */
color: red;
color: rebeccapurple;
/* Hex */
color: #FF0000;
color: #F00;
/* RGB / RGBA */
color: rgb(255, 0, 0);
color: rgba(255, 0, 0, 0.5);
/* HSL */
color: hsl(0, 100%, 50%);
```
---
# Einheiten
| Einheit | Bedeutung |
|---------|-----------|
| `px` | Pixel (absolut) |
| `%` | Prozent vom Elternelement |
| `em` | Relativ zur Schriftgröße des Elements |
| `rem` | Relativ zur Schriftgröße des Root-Elements |
| `vw` / `vh` | Prozent der Viewport-Breite/-Höhe |
**Empfehlung:**
`rem` für Schrift, `%` oder `vw/vh` für Layout.
---
# Pseudo-Klassen
![bg right:35%](./assets/demos/css-pseudo-classes.png)
```css
/* Hover */
a:hover { color: red; }
/* Besuchter Link */
a:visited { color: purple; }
/* Fokussiertes Element */
input:focus { border-color: blue; }
/* Erstes/n-tes Kind */
li:first-child { font-weight: bold; }
li:nth-child(odd) { background: #eee; }
```
`:` vor dem Namen = Pseudo-Klasse.
---
# Pseudo-Elemente
![bg right:35%](./assets/demos/css-pseudo-elements.png)
```css
/* Vor dem Inhalt einfügen */
.required::before {
content: "* ";
color: red;
}
/* Erster Buchstabe */
p::first-letter {
font-size: 2em;
}
```
`::` = Pseudo-Element (erzeugt "virtuelles" Element)
`:` = Pseudo-Klasse (wählt existierendes Element im Zustand)
---
# Layout: Flexbox
```css
.container {
display: flex;
justify-content: space-between;
align-items: center;
gap: 1rem;
}
```
→ Eindimensionales Layout (Zeile *oder* Spalte). Siehe nachfolgende Folien.
---
# Layout: Grid
```css
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
}
```
→ Zweidimensionales Layout (Zeilen *und* Spalten gleichzeitig).
---
# Responsive Design
![bg right:35%](./assets/demos/css-responsive.png)
```css
/* Mobile First: Basis-Styles */
.container {
padding: 1rem;
}
/* Ab 768px (Tablet) */
@media (min-width: 768px) {
.container { padding: 2rem; }
}
/* Ab 1024px (Desktop) */
@media (min-width: 1024px) {
.container { padding: 3rem; }
}
```
---
# Responsive Design – Vertiefung
**Mobile First** ist Standard: Basis-CSS für kleine Screens, dann Erweiterungen.
| Breakpoint | Gerät | Media Query |
|------------|-------|-------------|
| < 576px | Smartphone (Portrait) | Basis |
| ≥ 576px | Smartphone (Landscape) | `@media (min-width: 576px)` |
| ≥ 768px | Tablet | `@media (min-width: 768px)` |
| ≥ 992px | Desktop | `@media (min-width: 992px)` |
| ≥ 1200px | Large Desktop | `@media (min-width: 1200px)` |
**Viewport-Meta-Tag (kritisch!):**
```html
<meta name="viewport" content="width=device-width, initial-scale=1">
```
**Moderne Alternativen:** `clamp()`, Container Queries, CSS Grid `auto-fit`/`auto-fill`.
---
---
<!-- _class: invert -->
<!-- _backgroundColor: #000 -->
# CSS: Extended
---
# CSS Selectors – Attribut-Selektoren
```css
/* presence */
[disabled] { opacity: 0.5; }
/* 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; }
```
---
# CSS Combinators
```css
/* Child (direkt) */
div > p { margin: 0; }
/* 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; }
```
---
# Pseudo Classes – Erweitert
```css
/* Form States */
:valid { border-color: green; }
:invalid { border-color: red; }
:placeholder-shown { color: #999; }
/* 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; }
```
---
# Shorthand Properties
```css
/* margin: top right bottom left */
margin: 10px 20px 10px 20px;
/* centering */
margin: 0 auto;
/* padding same */
padding: 20px;
/* 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;
```
---
# Flexbox Shorthands
```css
/* 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;
```
---
# CSS Custom Properties (Variables)
```css
:root {
--primary-color: #d63384;
--spacing: 20px;
--radius: 8px;
}
.button {
background: var(--primary-color);
padding: var(--spacing);
border-radius: var(--radius);
}
```
---
# CSS Functions
```css
/* 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
| Framework | Stil |
|-----------|------|
| **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
<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`