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:
1 parent
6209f9f3a0
commit
351e3dfc23
467 files changed
+32391
-4701
No files matched your search
@@ -0,0 +1,837 @@
|
||||
---
|
||||
marp: true
|
||||
theme: gaia
|
||||
paginate: true
|
||||
backgroundColor: #fff
|
||||
header: "Web Engineering – DHBW Stuttgart"
|
||||
footer: "Michael Czechowski – SoSe 2026"
|
||||
title: Web Engineering
|
||||
---
|
||||
|
||||
<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 -->
|
||||
|
||||

|
||||
|
||||
# Web Engineering
|
||||
|
||||
**DHBW Stuttgart** · Informatik / Wirtschaftsinformatik
|
||||
**Sommersemester 2026**
|
||||
|
||||
---
|
||||
|
||||
# Ressourcen zum Selbstlernen
|
||||
|
||||
- **CODE CRISPIES** — [codecrispi.es](https://codecrispi.es/)
|
||||
- **Online Code-Editor** — [codepen.io](https://codepen.io/pen/)
|
||||
- **MDN** — [developer.mozilla.org](https://developer.mozilla.org/de/)
|
||||
- **Flexbox-Spiel** — [flexboxfroggy.com](https://flexboxfroggy.com/)
|
||||
- **Grid-Spiel** — [cssgridgarden.com](https://cssgridgarden.com/)
|
||||
|
||||
---
|
||||
|
||||
<!-- _class: lead -->
|
||||
|
||||
# Herzlich Willkommen!
|
||||
|
||||
## 1. Sitzung: 08.05.2026
|
||||
|
||||
---
|
||||
|
||||
# Über mich
|
||||
|
||||

|
||||
|
||||
Michael Czechowski
|
||||
|
||||
- Software Engineer, ehemals freischaffend
|
||||
- Lektor an HdM Stuttgart + DHBW
|
||||
- librete.ch
|
||||
|
||||
---
|
||||
|
||||
# Vorlesungsplan (Auszug)
|
||||
|
||||
| Termin | Thema |
|
||||
|--------|-------|
|
||||
| 1 | Web Engineering (heute) |
|
||||
| 2 | CSS Extended |
|
||||
| 3 | Node.js Basics |
|
||||
| 4 | Node.js Advanced |
|
||||
| 5 | Testing |
|
||||
| 6 | TypeScript |
|
||||
| 7 | Docker |
|
||||
| 8 | Best Practices |
|
||||
|
||||
---
|
||||
|
||||
# Prüfungsleistung — 75 P + 10 Bonus
|
||||
|
||||
**Projekt-Abgabe** statt Klausur.
|
||||
|
||||
| Bereich | Punkte |
|
||||
|---------|-------:|
|
||||
| Projekt-Struktur + README | 10 |
|
||||
| Code-Qualität | 15 |
|
||||
| Git-Hygiene | 10 |
|
||||
| Tests | 10 |
|
||||
| Docker | 10 |
|
||||
| HTTP / API | 10 |
|
||||
| Frontend + A11y | 10 |
|
||||
| Präsentation + Bonus | 5 + 10 |
|
||||
|
||||
---
|
||||
|
||||
<!-- _class: lead -->
|
||||
|
||||
# Kontext: was ist „das Web"?
|
||||
|
||||
---
|
||||
|
||||
# Internet-Timeline
|
||||
|
||||
| Jahr | Was |
|
||||
|------|-----|
|
||||
| 1969 | ARPANET — 4 Knoten |
|
||||
| 1971 | Email (Ray Tomlinson, `@`) |
|
||||
| 1983 | TCP/IP-Standard |
|
||||
| **1989** | **WWW** (Berners-Lee, CERN) |
|
||||
| 1993 | Mosaic-Browser → Web wird populär |
|
||||
|
||||
---
|
||||
|
||||
# Das WWW (1989)
|
||||
|
||||
**Tim Berners-Lee am CERN.** Drei Standards:
|
||||
|
||||
- **HTTP** — Protokoll
|
||||
- **HTML** — Format
|
||||
- **URL** — Adresse
|
||||
|
||||
Patentfrei → Web konnte explodieren.
|
||||
|
||||
---
|
||||
|
||||
# Heute: physische Infrastruktur
|
||||
|
||||
- ~400 Unterseekabel
|
||||
- 1,3 Mio km Glasfaser weltweit
|
||||
- DE-CIX Frankfurt: größter Internet-Knoten (~12 Tbit/s)
|
||||
|
||||
Das Web ist **physisch.**
|
||||
|
||||
---
|
||||
|
||||
# URL → Pixel in 7 Schritten
|
||||
|
||||
1. **URL parsen** — Schema, Host, Port, Path
|
||||
2. **DNS-Lookup** — Host-Name → IP
|
||||
3. **TCP-Handshake** mit Server
|
||||
4. **TLS-Handshake** (https)
|
||||
5. **HTTP-Request** senden
|
||||
6. Server antwortet mit **HTML + CSS + JS**
|
||||
7. Browser **parsed + rendert** → Pixel
|
||||
|
||||
---
|
||||
|
||||
# HTTP — Anatomie
|
||||
|
||||
```http
|
||||
GET /index.html HTTP/1.1
|
||||
Host: librete.ch
|
||||
User-Agent: Mozilla/5.0 ...
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: text/html
|
||||
Content-Length: 1234
|
||||
|
||||
<!DOCTYPE html>...
|
||||
```
|
||||
|
||||
**Statuscodes:** 200 OK · 301 Moved · 404 Not Found · 500 Server Error
|
||||
|
||||
---
|
||||
|
||||
<!-- _class: lead -->
|
||||
|
||||
# Onboarding
|
||||
## Tools, Runtimes, Workflows
|
||||
|
||||
---
|
||||
|
||||
# Werkzeuge & Betriebssystem
|
||||
|
||||
| Bereich | Empfehlung |
|
||||
|---------|------------|
|
||||
| Editor | **VS Code** · JetBrains (edu lizenz frei) |
|
||||
| Browser | **Chromium / Firefox** |
|
||||
| Terminal | macOS Terminal · Linux Terminal · Windows Terminal |
|
||||
| Paket-Manager | macOS: brew · Linux: apt/dnf · Windows: winget/scoop/choco |
|
||||
| Versions-Control | Git + GitHub/Gitea |
|
||||
|
||||
---
|
||||
|
||||
# Node.js installieren
|
||||
|
||||
**Best Practice:** Versions-Manager statt Direkt-Install.
|
||||
|
||||
| OS | Empfehlung |
|
||||
|----|------------|
|
||||
| macOS | `brew install fnm` → `fnm install --lts` |
|
||||
| Linux | `curl -fsSL https://fnm.vercel.app/install \| bash` |
|
||||
| Windows | `winget install Schniz.fnm` |
|
||||
|
||||
**Aktuelle LTS:** Node 24.
|
||||
|
||||
---
|
||||
|
||||
# Warum Versions-Manager?
|
||||
|
||||
**Direkt-Install** (z.B. `brew install node`) bringt Probleme:
|
||||
- Projekt-A braucht Node 18, Projekt-B braucht Node 22 → Konflikt
|
||||
- Update bricht alte Projekte
|
||||
- Kein automatisches Switching pro Projekt
|
||||
|
||||
**fnm / nvm / volta:** pro Projekt Node-Version, automatisch via `.nvmrc`.
|
||||
|
||||
---
|
||||
|
||||
# Alternative Runtimes
|
||||
|
||||
| Runtime | Stärke |
|
||||
|---------|--------|
|
||||
| **Node** | Standard, größtes Ökosystem |
|
||||
| **Deno** | Sicher by default, TypeScript nativ |
|
||||
| **Bun** | Schnell, all-in-one (runtime + bundler + tester) |
|
||||
|
||||
Für DHBW-Kurs: **Node 24 LTS.**
|
||||
|
||||
---
|
||||
|
||||
# Browser DevTools
|
||||
|
||||
**F12** öffnet das Power-Tool jeder Webentwicklung.
|
||||
|
||||
| Tab | Wofür |
|
||||
|-----|-------|
|
||||
| Elements | DOM-Baum inspizieren + live editieren |
|
||||
| Console | JS ausführen, Errors lesen |
|
||||
| Network | HTTP-Requests sehen, Latenz |
|
||||
| Performance | Render + Memory profilen |
|
||||
| Lighthouse | A11y · SEO · Perf-Audit |
|
||||
|
||||
---
|
||||
|
||||
# HTTP-Clients
|
||||
|
||||
Tools zum Testen von APIs:
|
||||
|
||||
- **curl** — CLI, überall
|
||||
- **Hoppscotch** — Browser, Open Source
|
||||
- **Postman** — GUI, kommerziell
|
||||
- **VS Code REST Client** — Plugin
|
||||
|
||||
---
|
||||
|
||||
# Git Setup
|
||||
|
||||
```sh
|
||||
git config --global user.name "Dein Name"
|
||||
git config --global user.email "du@dhbw.de"
|
||||
git config --global init.defaultBranch main
|
||||
git config --global core.autocrlf input # Windows: true
|
||||
```
|
||||
|
||||
**SSH-Key** für GitHub/Gitea ohne Passwort-Prompt:
|
||||
```sh
|
||||
ssh-keygen -t ed25519 -C "du@dhbw.de"
|
||||
cat ~/.ssh/id_ed25519.pub # zu GitHub kopieren
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Projekt-Skeleton
|
||||
|
||||
```
|
||||
mein-projekt/
|
||||
├── .git/
|
||||
├── .gitignore # node_modules/, .env, build/
|
||||
├── README.md # was, wie, warum
|
||||
├── package.json # npm metadata + scripts
|
||||
├── src/ # eigener Code
|
||||
├── public/ # statische Assets (für Web)
|
||||
├── tests/ # Unit + Integration
|
||||
└── Dockerfile # für Container-Deploy
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
<!-- _class: lead -->
|
||||
|
||||
# HTML
|
||||
## Hypertext Markup Language
|
||||
|
||||
---
|
||||
|
||||
# Was ist HTML?
|
||||
|
||||
**Tim Berners-Lee, 1989.** Struktur-Format des Webs.
|
||||
|
||||
**Syntax:** Tags mit Attributen umfassen Inhalt.
|
||||
**Browser parst HTML** → DOM (Document Object Model) → rendert.
|
||||
|
||||
Plain-Text mit Tags. Lesbar mit jedem Editor.
|
||||
|
||||
---
|
||||
|
||||
# HTML-Anatomie
|
||||
|
||||
```html
|
||||
<a href="https://librete.ch" target="_blank">Mein Link</a>
|
||||
```
|
||||
|
||||
- `<a` — Opening-Tag mit Tag-Namen
|
||||
- `href="..."` — Attribut (Name + Wert)
|
||||
- `Mein Link` — Inhalt
|
||||
- `</a>` — Closing-Tag
|
||||
- Alles zusammen = **Element**
|
||||
|
||||
---
|
||||
|
||||
# Self-closing Tags
|
||||
|
||||
```html
|
||||
<img src="foto.jpg" alt="Sonnenuntergang">
|
||||
<br>
|
||||
<input type="text" name="username">
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="style.css">
|
||||
```
|
||||
|
||||
Kein Closing-Tag. Inhalt aus Attributen + (für `<input>`) User-Eingabe.
|
||||
|
||||
---
|
||||
|
||||
# Document-Grundgerüst
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Meine Seite</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hallo Welt</h1>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Semantische HTML-Tags
|
||||
|
||||
| Tag | Bedeutung |
|
||||
|-----|-----------|
|
||||
| `<header>` | Kopfbereich (Logo, Nav) |
|
||||
| `<nav>` | Navigation |
|
||||
| `<main>` | Hauptinhalt |
|
||||
| `<section>` | Thematischer Abschnitt |
|
||||
| `<article>` | eigenständiger Inhalt |
|
||||
| `<aside>` | Seiten-Inhalt |
|
||||
| `<footer>` | Fußbereich |
|
||||
|
||||
**Pflicht** für SEO + A11y + Wartbarkeit.
|
||||
|
||||
---
|
||||
|
||||
# Native HTML-Elemente — nicht vergessen!
|
||||
|
||||
Bevor du eine Custom-Component baust: **gibt's das schon nativ?**
|
||||
|
||||
| Element | Was |
|
||||
|---------|-----|
|
||||
| `<details>` / `<summary>` | Accordion ohne JS |
|
||||
| `<dialog>` | Modal mit Native Backdrop |
|
||||
| `<input type="date">` | Date-Picker, native, A11y |
|
||||
| `<input type="color">` | Color-Picker |
|
||||
| `<input type="range">` | Slider |
|
||||
| `<datalist>` | Autocomplete-Vorschläge |
|
||||
| `<progress>` | Lade-Balken |
|
||||
|
||||
**Faustregel:** Native zuerst, Custom nur wenn nötig.
|
||||
|
||||
---
|
||||
|
||||
<!-- _class: lead -->
|
||||
|
||||
# Barrierefreiheit
|
||||
## A11y — Accessibility
|
||||
|
||||
---
|
||||
|
||||
# BFSG + EAA — Pflicht ab 28.06.2025
|
||||
|
||||
**Barrierefreiheitsstärkungsgesetz** (DE) setzt **European Accessibility Act** (EU) um.
|
||||
|
||||
**Pflicht:**
|
||||
- Online-Shops, Banken, Versicherungen
|
||||
- E-Books, Buchungssysteme
|
||||
- Smartphone-Apps mit kommerziellem Bezug
|
||||
|
||||
**Ausnahme:** < 10 Mitarbeiter + < 2 Mio € Umsatz.
|
||||
|
||||
**Strafe:** bis 100.000 € Bußgeld + Klage durch Behindertenverbände.
|
||||
|
||||
---
|
||||
|
||||
# Wie nutzen Menschen das Web?
|
||||
|
||||
- **Sehen:** Screen-Reader (NVDA, JAWS, VoiceOver)
|
||||
- **Hören:** Untertitel + Transkripte
|
||||
- **Motorik:** Tastatur statt Maus, Switch-Control
|
||||
- **Kognitiv:** klare Sprache, viel Whitespace
|
||||
- **Vorübergehend:** Sonne im Bildschirm, gebrochener Arm, ÖPNV-Lärm
|
||||
|
||||
~10 % der Bevölkerung haben relevante Beeinträchtigungen. *Du auch — irgendwann.*
|
||||
|
||||
---
|
||||
|
||||
# WCAG · 4 Prinzipien (POUR)
|
||||
|
||||
| Prinzip | Was |
|
||||
|---------|-----|
|
||||
| **P**erceivable | Alt-Text · Untertitel · Kontrast |
|
||||
| **O**perable | Keyboard · Skip-Links |
|
||||
| **U**nderstandable | klare Sprache · Fehler-Hilfe |
|
||||
| **R**obust | semantisches HTML · Standards-konform |
|
||||
|
||||
**WCAG 2.1 Level AA** = Mindest-Standard für BFSG.
|
||||
|
||||
---
|
||||
|
||||
# Perceivable — wahrnehmbar
|
||||
|
||||
- **Alt-Text** für jedes Bild (`<img alt="...">`)
|
||||
- **Untertitel** für jedes Video
|
||||
- **Kontrast 4.5:1** für Text (Level AA)
|
||||
- **Skalierbar** bis 200 %
|
||||
|
||||
```html
|
||||
<img src="foto.jpg" alt="Sonnenuntergang am Bodensee">
|
||||
<!-- LEER alt="" für rein dekorative Bilder -->
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Operable — bedienbar
|
||||
|
||||
- Alle interaktiven Elemente **mit Tastatur erreichbar**
|
||||
- **Fokus sichtbar** (`:focus-visible` mit Outline)
|
||||
- **Skip-Links** für Screen-Reader (Hauptnav überspringen)
|
||||
- **Genug Zeit** für Aufgaben (Auto-Logout pausierbar)
|
||||
|
||||
```css
|
||||
button:focus-visible {
|
||||
outline: 3px solid hotpink;
|
||||
outline-offset: 2px;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Understandable — verständlich
|
||||
|
||||
- **Lese-Niveau** angemessen (Level AA: 9. Klasse)
|
||||
- **Klare Fehlermeldungen** (was war falsch, wie korrigieren)
|
||||
- **Konsistente Navigation** (Header bleibt gleich)
|
||||
- **`lang`-Attribut** im html-Element
|
||||
|
||||
```html
|
||||
<html lang="de">
|
||||
<p lang="en">This sentence is in English.</p>
|
||||
</html>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Robust — Tech-stabil
|
||||
|
||||
- **Semantisches HTML** statt div-Suppe
|
||||
- **ARIA** *nur als Ergänzung*, nicht als Ersatz
|
||||
- **Standards-konform** (Validator: validator.w3.org)
|
||||
|
||||
```html
|
||||
<!-- ❌ semantisch falsch -->
|
||||
<div onclick="...">Klick</div>
|
||||
|
||||
<!-- ✓ semantisch korrekt -->
|
||||
<button onclick="...">Klick</button>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# A11y-Testen — Werkzeuge
|
||||
|
||||
| Tool | Was |
|
||||
|------|-----|
|
||||
| **Lighthouse** (Chrome DevTools) | automatischer Audit |
|
||||
| **axe DevTools** | Plugin, präziser |
|
||||
| **WAVE** | Browser-Plugin, visuell |
|
||||
| **Manuell** | Maus weglegen, nur Tab |
|
||||
| **Screen-Reader** | macOS: VoiceOver (Cmd+F5) · Win: NVDA |
|
||||
|
||||
**Automatisierte Tools** finden ~30 %. Rest = manuell.
|
||||
|
||||
---
|
||||
|
||||
<!-- _class: lead -->
|
||||
|
||||
# CSS
|
||||
## Cascading Style Sheets
|
||||
|
||||
*(Vertiefung in Kap 2 — CSS Extended)*
|
||||
|
||||
---
|
||||
|
||||
# CSS einbinden
|
||||
|
||||
```html
|
||||
<!-- External (best practice) -->
|
||||
<link rel="stylesheet" href="./style.css">
|
||||
|
||||
<!-- Internal -->
|
||||
<style>
|
||||
body { background: #fafafa; }
|
||||
</style>
|
||||
|
||||
<!-- Inline (vermeiden) -->
|
||||
<button style="background: hotpink">Klick</button>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# CSS-Anatomie
|
||||
|
||||
```css
|
||||
button {
|
||||
background-color: hotpink;
|
||||
padding: 10px 20px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
```
|
||||
|
||||
- `button` = **Selektor** (welche Elemente)
|
||||
- `background-color` = **Property**
|
||||
- `hotpink` = **Value**
|
||||
- alles in `{ }` = **Declaration Block**
|
||||
|
||||
---
|
||||
|
||||
# Selektoren
|
||||
|
||||
| Selektor | Was |
|
||||
|----------|-----|
|
||||
| `p` | alle `<p>` |
|
||||
| `.btn` | alle mit `class="btn"` |
|
||||
| `#header` | das Element mit `id="header"` |
|
||||
| `button:hover` | Button beim Hover |
|
||||
| `nav > a` | direkte `<a>` unter `<nav>` |
|
||||
| `*` | alles |
|
||||
|
||||
---
|
||||
|
||||
# Spezifizität — wer gewinnt?
|
||||
|
||||
```css
|
||||
p { color: blue; } /* 1 */
|
||||
.notice { color: red; } /* 10 */
|
||||
#warn { color: green; } /* 100 */
|
||||
[style] /* inline */ /* 1000 */
|
||||
```
|
||||
|
||||
**Inline > ID > Klasse > Element.** Bei Gleichstand: **letzte Regel.**
|
||||
|
||||
`!important` umgeht alles — *vermeiden.*
|
||||
|
||||
---
|
||||
|
||||
# Box-Model
|
||||
|
||||
```
|
||||
┌──────────────────────┐
|
||||
│ margin │
|
||||
│ ┌────────────────┐ │
|
||||
│ │ border │ │
|
||||
│ │ ┌──────────┐ │ │
|
||||
│ │ │ padding │ │ │
|
||||
│ │ │ content │ │ │
|
||||
│ │ └──────────┘ │ │
|
||||
│ └────────────────┘ │
|
||||
└──────────────────────┘
|
||||
```
|
||||
|
||||
**Best Practice:** `* { box-sizing: border-box; }` global.
|
||||
|
||||
---
|
||||
|
||||
# Farben
|
||||
|
||||
| Notation | Beispiel |
|
||||
|----------|----------|
|
||||
| Hex | `#FF5733` |
|
||||
| RGB | `rgb(255, 87, 51)` |
|
||||
| RGBA | `rgb(255, 87, 51, 0.5)` |
|
||||
| HSL | `hsl(11, 100%, 60%)` |
|
||||
| OKLCH (modern) | `oklch(0.7 0.2 30)` |
|
||||
| Schlüsselwort | `hotpink`, `tomato` |
|
||||
|
||||
---
|
||||
|
||||
# Einheiten
|
||||
|
||||
| Einheit | Was |
|
||||
|---------|-----|
|
||||
| `px` | Pixel, fix |
|
||||
| `rem` | relativ zu Wurzel-Font (16 px default) |
|
||||
| `em` | relativ zu Eltern-Font |
|
||||
| `%` | relativ zur Eltern-Größe |
|
||||
| `vw` / `vh` | Viewport-Breite/-Höhe |
|
||||
| `ch` | Breite eines Zeichens |
|
||||
|
||||
**Faustregel:** Font + Spacing in `rem`. Layout in `%` oder `fr`.
|
||||
|
||||
---
|
||||
|
||||
# Pseudo-Klassen & -Elemente
|
||||
|
||||
```css
|
||||
/* Pseudo-Klassen (Zustand) */
|
||||
a:hover { color: hotpink; }
|
||||
input:focus { outline: 2px solid; }
|
||||
button:disabled { opacity: 0.5; }
|
||||
li:nth-child(2n) { background: #eee; }
|
||||
|
||||
/* Pseudo-Elemente (Virtuelles) */
|
||||
p::first-letter { font-size: 2em; }
|
||||
.tooltip::after { content: " 💡"; }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
<!-- _class: lead -->
|
||||
|
||||
# JavaScript
|
||||
## Die Sprache des Webs
|
||||
|
||||
*(Vertiefung in Kap 3+4 — Node.js)*
|
||||
|
||||
---
|
||||
|
||||
# ECMAScript
|
||||
|
||||
**ECMA International** (Schweiz) standardisiert die Sprache.
|
||||
|
||||
| Version | Jahr | Highlight |
|
||||
|---------|------|-----------|
|
||||
| ES5 | 2009 | strict mode, JSON |
|
||||
| ES6 / 2015 | 2015 | `let` `const`, arrow, classes, modules |
|
||||
| ES2017 | 2017 | async/await |
|
||||
| ES2020 | 2020 | optional chaining `?.` |
|
||||
| ES15 | 2024 | aktuell |
|
||||
|
||||
---
|
||||
|
||||
# JavaScript-Grundlagen
|
||||
|
||||
```javascript
|
||||
// Variablen
|
||||
const name = "Ada";
|
||||
let alter = 56;
|
||||
|
||||
// Funktionen
|
||||
const begrüßen = (name) => `Hallo ${name}`;
|
||||
|
||||
// Arrays + Objects
|
||||
const fruits = ["A", "B"];
|
||||
const user = { name: "Ada", admin: true };
|
||||
|
||||
// Schleifen
|
||||
fruits.map(f => f.toUpperCase());
|
||||
|
||||
// async
|
||||
async function laden() {
|
||||
const res = await fetch('/api');
|
||||
return res.json();
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# DOM Manipulation
|
||||
|
||||
```javascript
|
||||
// Element finden
|
||||
const btn = document.querySelector('#myBtn');
|
||||
|
||||
// Inhalt ändern
|
||||
btn.textContent = 'Neu';
|
||||
btn.classList.add('active');
|
||||
|
||||
// Event-Handler
|
||||
btn.addEventListener('click', () => {
|
||||
console.log('Klick!');
|
||||
});
|
||||
|
||||
// Element erzeugen
|
||||
const li = document.createElement('li');
|
||||
li.textContent = 'Item';
|
||||
document.querySelector('ul').appendChild(li);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Fetch + JSON
|
||||
|
||||
```javascript
|
||||
// GET
|
||||
const res = await fetch('https://api.github.com/users/torvalds');
|
||||
const data = await res.json();
|
||||
console.log(data.public_repos);
|
||||
|
||||
// POST
|
||||
await fetch('/api/posts', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ title: 'Hallo', body: '...' })
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
<!-- _class: lead -->
|
||||
|
||||
# Frameworks-Vorschau
|
||||
|
||||
---
|
||||
|
||||
# Framework-Landschaft
|
||||
|
||||
| Framework | Typ | Use-Case |
|
||||
|-----------|-----|----------|
|
||||
| **React** | Library | dominant, große Community |
|
||||
| **Vue 3** | Framework | sanfter Einstieg |
|
||||
| **Svelte** | Compiler | kein Virtual DOM, kleines Bundle |
|
||||
| **Astro** | Hybrid | Content-First, Multi-Framework |
|
||||
| **Angular** | Framework | Enterprise, Google |
|
||||
|
||||
Alle: **Komponenten + reaktive State + Re-Render.**
|
||||
|
||||
---
|
||||
|
||||
# Counter — Vanilla + React
|
||||
|
||||
**Vanilla JS:**
|
||||
```javascript
|
||||
let count = 0;
|
||||
btn.onclick = () => { count++; display.textContent = count; };
|
||||
```
|
||||
|
||||
**React (JSX):**
|
||||
```jsx
|
||||
function Counter() {
|
||||
const [count, setCount] = useState(0);
|
||||
return <button onClick={() => setCount(count + 1)}>{count}</button>;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Counter — Vue + Svelte
|
||||
|
||||
**Vue 3 (Composition):**
|
||||
```vue
|
||||
<script setup>const count = ref(0)</script>
|
||||
<template><button @click="count++">{{ count }}</button></template>
|
||||
```
|
||||
|
||||
**Svelte:**
|
||||
```svelte
|
||||
<script>let count = 0</script>
|
||||
<button on:click={() => count++}>{count}</button>
|
||||
```
|
||||
|
||||
Vier Frameworks, **dasselbe Pattern:** State → UI re-rendert.
|
||||
|
||||
---
|
||||
|
||||
# Build-Tools
|
||||
|
||||
| Tool | Stärke |
|
||||
|------|--------|
|
||||
| **Vite** | schnell, modern, Default für React/Vue/Svelte |
|
||||
| **Webpack** | etabliert, mächtig, verbreitet |
|
||||
| **Parcel** | zero-config |
|
||||
| **Bun** | all-in-one, sehr schnell |
|
||||
|
||||
**Heute:** Vite ist der Default für neue Projekte.
|
||||
|
||||
---
|
||||
|
||||
# Rendering-Modi
|
||||
|
||||
| Modus | Wann |
|
||||
|-------|------|
|
||||
| **CSR** (Client-Side) | Single-Page-Apps (Dashboard, Editor) |
|
||||
| **SSR** (Server-Side) | SEO + erste Latenz wichtig (News, Shop) |
|
||||
| **SSG** (Static Site Gen) | reine Content-Sites (Blog, Doku) |
|
||||
| **ISR** (Incremental SSG) | Hybrid: Content selten ändert |
|
||||
|
||||
Astro / Next.js / Nuxt unterstützen alle.
|
||||
|
||||
---
|
||||
|
||||
<!-- _class: aufgabe -->
|
||||
|
||||
# Selbstlernen — Erste eigene Seite
|
||||
|
||||
1. **Mappe anlegen** `meine-seite/`
|
||||
2. `index.html` mit dem **Grundgerüst** (DOCTYPE, head, body, h1, p)
|
||||
3. `style.css` daneben — mit Hotpink-Background
|
||||
4. **VS Code Live Server** starten → im Browser öffnen
|
||||
5. **DevTools** auf, F12, Tab Elements → DOM-Baum anschauen
|
||||
|
||||
**Bonus:** Lighthouse Audit laufen lassen. Welchen Score erreicht ihr?
|
||||
|
||||
---
|
||||
|
||||
# Zusammenfassung
|
||||
|
||||
**Heute gelernt:**
|
||||
- Internet-Geschichte → WWW → URL→Pixel-7-Schritte
|
||||
- Onboarding-Stack: Node (fnm), VS Code, Git, DevTools
|
||||
- HTML: Anatomie, semantisch, A11y-Foundation
|
||||
- A11y: BFSG/EAA-Pflicht, WCAG POUR
|
||||
- CSS-Basics (Vertiefung in Kap 2)
|
||||
- JS-Basics (Vertiefung in Kap 3+4)
|
||||
- Framework-Landschaft (Vorschau)
|
||||
|
||||
**Nächste Stunde:** CSS deeper — Flexbox, Grid, Responsive, Animations.
|
||||
|
||||
Reference in new issue
Block a user