Files
uni/slides/dhbw/01_web_eng.md
T
libretech b242c7b4e6 223015c 02 + dhbw 01: klausurfolien markiert, prosa-sätze bei allen tabellen, layout-fixes
223015c/02:
- glossar landkarte: klausur, prosa, reihenfolge (host→client→server→req→res→protokoll), tcp/http als beispiel
- glossar adressen/daten/eigenschaften/protokolle: prosa-sätze
- tcp/ip-modell: nichtssagenden satz ersetzt
- dateneinheiten: merkhilfe durch prosa ersetzt
- osi vs tcp/ip: bg right statt h:440, prosa statt einzeiler
- port: tabelle→liste, prosa statt bullets
- ip vs mac vs port: prosa
- tcp vs udp, http-methoden, status-codes, einheiten: prosa
- selektoren id + farben: klausur markiert
- farben: mdn-link, prosa-satz

dhbw/01:
- farben: prosa-satz synchronisiert
- über-mich: collage-bild hinzugefügt
2026-05-07 15:21:40 +02:00

1445 lines
29 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: 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: #d63384;
border-radius: 8px;
border-left: 3px solid #d63384;
}
pre code {
background: transparent;
color: inherit;
}
code {
background: #1a1a2e;
color: #d63384;
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**
---
<!-- _class: lead -->
# Herzlich Willkommen!
## 1. Sitzung: 08.05.2026
---
# Über mich
![bg right:33% fit](./assets/logos/collage.png)
**Michael Werner Czechowski**
- Systems and Platform Engineer
- Schwerpunkte:
- Web-Technologien, Barriere-Armut, Open Source
- Hintergrund:
- Philosophie (Uni Stuttgart)
- Wirtschaftsinformatik (Leibniz-FH Hannover)
- Honorardozent (DHBW Stuttgart, HdM Stuttgart, Leibniz-FH)
- Kontakt: michael.czechowski@lehre.dhbw-stuttgart.de
---
# Vorlesungsplan
| Sitzung | Datum | Thema |
|---------|-------|-------|
| 1 | 08.05. | Intro, Projektgruppen, Internet 101 |
| 2 | 15.05. | HTML und CSS (Frameworks) |
| 3 | 22.05. | JS (Frameworks) und npm |
| 4 | 29.05. | nodeJS: Scripting, Running and Building |
| 5 | 05.06. | Express API, CRUD und "Middlewares" |
| 6 | 12.06. | **Projektwerkstattbericht** |
| 7 | 19.06. | Testing (unit, integration, end-to-end) |
| 8 | 26.06. | TypeScript |
| 9 | 03.07. | Docker, Proxies and DBs |
| 10 | 10.07. | Wrap-up & Projektsupport |
| 11 | 17.07. | **Präsentation** |
---
# Prüfungsleistung – Übersicht
Eigenes Projekt: **Web-App** ODER **Backend** (API/CLI — Command-Line Interface).
**Grundanforderungen (75 Punkte)**
| Punkte | Bereich |
|--------|---------|
| 20 | Idee, Konzeption, Planung |
| 5 | Plattformunabhängigkeit |
| 25 | Clean Code (KISS, SOLID, DI, Testing, Error Handling) |
| 15 | Präsentation |
| 10 | Dokumentation |
**Zusatzpunkte (max. 10):** TypeScript, Docker, Dev/Prod-Parity, `.env`, npm-Publish, Domain, HTTPS, Responsive Design.
---
# Prüfungsleistung – Idee & Konzeption (20 P.)
- "Powerpoint"-Präsentation + Folien
- Aussagekräftiger Arbeitstitel + Beschreibung
- **Elevator Pitch** (max. 1 Min.)
- Repo-Link (GitHub / GitLab / Codeberg / BitBucket)
- **Logs**: wie hat sich Projekt verändert vs. Ursprungsidee?
- Schematischer Projektaufbau (UML o. Ä.)
---
# Prüfungsleistung – Clean Code (25 P.)
- `README.md` (clone, start, contribute)
- **KISS** – Keep It Simple, Stupid
- **SOLID:**
- **S**ingle Responsibility Principle
- **O**pen/Closed Principle
- **L**iskov Substitution Principle
- **I**nterface Segregation Principle
- **D**ependency Inversion Principle
- **DI** – Dependency Injection
- **Testing-Pyramide** (Unit, Integration, E2E)
- **Exception/Error Handling**
---
# Prüfungsleistung – Abgabe & Termine
- **Code-Upload:** bis 27.07.
- **Präsentation:** 17.07. (Gruppen, ~10 Min.)
Details: https://git.dailysh.it/DHBW/pruefungsleistung
---
# Internet 101 – Zeitleiste
| Jahr | Ereignis |
|------|----------|
| 1966 | ARPANET |
| 1969 | RFCs |
| 1986 | IETF |
| 1992 | Internet Society |
| 1974 | TCP/IP und HTTP(S) |
| 1987 | Domain Names und DNS |
| 1993 | "Erster" Browser: Mosaic |
| 1994 | W3C (HTML, XML, CSS, SVG, WCAG etc.) |
| 1995 | ECMAScript (JS) |
| 2006/08 | V8 JS Runtime Engine |
| Heute | 1,3 Mio. km Unterseekabel |
---
<!-- _header: '' -->
<!-- _footer: '' -->
![bg fit](./assets/demos/browser-server-sequence.png)
---
# HTTP – Hypertext Transfer Protocol
**Request:**
```
GET /products HTTP/1.1
Host: localhost:8080
```
**Response:**
```
HTTP/1.1 200 OK
Content-Type: application/json
[{"id": 1, "name": "Produkt A"}, ...]
```
---
<!-- _class: invert -->
<!-- _header: '' -->
<!-- _backgroundColor: #000 -->
# Onboarding
## Tools, Runtimes, Workflows
---
# Werkzeuge & Betriebssystem
**Erforderliche Werkzeuge:**
- **Terminal** (zsh / bash / fish / pwsh) — Kommandozeile
- **Editor** (siehe folgende Folie)
- **JavaScript-Runtime** (Node.js / Bun / Deno)
- **Browser mit DevTools** (Chromium / Firefox / Safari)
- **Git** — verteiltes Versionskontrollsystem (Stand der Industrie)
**OS-Empfehlung:**
| OS | Status |
|----|--------|
| **macOS** | First-class, viele Tools "just work" |
| **Linux** | First-class, beste Server-Parität |
| **Windows + WSL2** | Empfohlen — Windows-CLI hat Edge Cases |
| **Windows nativ** (PowerShell) | Funktioniert, aber holpriger Pfad |
---
# Node.js installieren – macOS
Empfohlen: **LTS** (aktuell **Node.js 24** — Stand 2026).
Paketmanager: **[Homebrew](https://brew.sh)**
```bash
# Homebrew installieren (falls nicht vorhanden)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# Node.js LTS installieren
brew install node@24
# Version prüfen
node --version
npm --version
```
Alternative: Installer von [nodejs.org](https://nodejs.org)
---
# Node.js installieren – Linux
Empfohlen: **LTS** (aktuell **Node.js 24**).
**Debian / Ubuntu** ([NodeSource](https://github.com/nodesource/distributions)):
```bash
curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -
sudo apt install -y nodejs
```
**Arch / Manjaro:**
```bash
sudo pacman -S nodejs npm
```
**Fedora / RHEL:**
```bash
sudo dnf module install nodejs:24/common
```
→ Distro-Pakete sind oft **veraltet**. Versionsmanager (folgende Folie) bevorzugen.
---
# Node.js installieren – Windows
Empfohlen: **LTS** (aktuell **Node.js 24**).
**Option 1: winget** (empfohlen, Win 10/11):
```powershell
winget install OpenJS.NodeJS.LTS
```
**Option 2: Chocolatey** ([chocolatey.org](https://chocolatey.org)):
```powershell
choco install nodejs-lts
```
**Option 3: Scoop** ([scoop.sh](https://scoop.sh)):
```powershell
scoop install nodejs-lts
```
**Option 4:** Installer von [nodejs.org](https://nodejs.org)
→ **Empfehlung:** WSL2 + Linux-Workflow nutzen.
---
# Direkt-Install: Wenn es eng wird
**Typisches Szenario** in Studium und Beruf — drei parallele Projekte mit unterschiedlichen Anforderungen:
| Projekt | Stack | Node-Version |
|---------|-------|--------------|
| Praktikums-API | Express (Legacy) | 18.x (LTS Hydrogen) |
| Studienarbeit | Next.js 15 | 22.x (LTS Jod) |
| Aktuelles Lab-Projekt | neueste Features | 24.x (Iron, current LTS) |
System-Install kennt nur **eine** Node-Version global.
**Symptome im Alltag:**
- `npm install` bricht mit `engines`-Warning ab
- native Module (z. B. `node-sass`) bauen nicht
- CI-Pipeline ist grün, lokal rot — oder umgekehrt
- erheblicher Zeitverlust beim Debuggen von Versions-Konflikten
→ Lösung: **Versionsmanager** und Node-Version pro Projekt pinnen.
---
# Node-Versionsmanager
Verschiedene Projekte brauchen oft verschiedene Node-Versionen. **Lösung:** Versionsmanager.
| Tool | Sprache | Geschwindigkeit | Plattform |
|------|---------|-----------------|-----------|
| **nvm** | Bash | langsam (Shell-Funktion) | macOS, Linux |
| **fnm** | Rust | sehr schnell | macOS, Linux, Windows |
| **asdf** | Bash | mittel, multi-language | macOS, Linux |
| **volta** | Rust | schnell, pinning per `package.json` | alle |
```bash
# fnm
curl -fsSL https://fnm.vercel.app/install | bash
fnm install --lts # aktuell Node 24
fnm use lts-latest
# .nvmrc / .node-version automatisch
echo "lts/*" > .nvmrc
fnm use # liest .nvmrc
```
---
# Alternative Runtimes
| Runtime | Erschienen | Engine | USP |
|---------|------------|--------|-----|
| **Node.js** | 2009 | V8 (C++) | Standard, größtes Ökosystem |
| **Deno** | 2020 | V8 (Rust) | Sicherheit, TypeScript nativ, Std-Lib |
| **Bun** | 2022 | JavaScriptCore (Zig) | Geschwindigkeit, all-in-one |
```bash
# Deno
curl -fsSL https://deno.land/install.sh | sh
deno run main.ts
# Bun
curl -fsSL https://bun.sh/install | bash
bun install
bun run dev
```
→ Im Kurs primär **Node.js**. Bun und Deno sind ebenfalls zulässig.
---
# Editor
- **VS Code** (empfohlen) — kostenlos, große Plugin-Auswahl
- **JetBrains WebStorm** — sehr mächtig, kostenpflichtig
- kostenlos für Studierende via [JetBrains Education](https://www.jetbrains.com/community/education/#students)
- **Vim / Neovim / Emacs** — für CLI-Profis
- **Zed** — modern, schnell
---
# Browser DevTools
Chromium / Firefox / Safari — `F12` oder `Cmd+Opt+I`
<small>Chromium = Open-Source-Basis von Chrome, Edge, Brave, Opera, Vivaldi etc.</small>
**Wichtigste Panels:**
- **Network** — HTTP-Requests, Responses, Timing
- **Console** — `console.log`, JS-Errors, REPL
- **Elements** — DOM-Inspektor, Live-CSS-Editor
- **Sources** — Debugger, Breakpoints, Source-Maps
- **Performance** — Profiling, Frame-Rate, FPS
- **Application** — LocalStorage, Cookies, Service Workers
---
# HTTP-Clients
- **Bruno** ([usebruno.com](https://usebruno.com)) — open source, git-friendly
- **Hoppscotch** ([hoppscotch.io](https://hoppscotch.io)) — open source, browser-basiert (vormals Postwoman)
- **Insomnia** / **Postman** — etabliert, freemium
- **curl** / **httpie** — CLI (Command-Line Interface, scriptbar)
---
# Git Setup & Workflow
**Einmalige Konfiguration:**
```bash
git config --global user.name "Vorname Nachname"
git config --global user.email "vorname.nachname@example.com"
git config --global init.defaultBranch main
git config --global pull.rebase true
```
**SSH-Key für GitHub/GitLab:**
```bash
ssh-keygen -t ed25519 -C "vorname.nachname@example.com"
cat ~/.ssh/id_ed25519.pub # → in GitHub-Settings einfügen
```
**Tägliche Befehle:**
```bash
git status # was hat sich geändert?
git add <file> # für Commit vormerken
git commit -m "feat: ..." # Conventional Commits
git push # hochladen
git pull --rebase # neueste Änderungen holen
```
---
# Projekt-Skeleton
```bash
mkdir mein-projekt && cd mein-projekt
git init
npm init -y # erzeugt package.json
echo "node_modules" > .gitignore
echo ".env" >> .gitignore
npm install express
```
**`package.json` minimal:**
```json
{
"name": "mein-projekt",
"version": "0.1.0",
"type": "module",
"scripts": {
"start": "node index.js",
"dev": "node --watch index.js"
}
}
```
`.env` für Secrets (nie committen!), `.env.example` mit Dummy-Werten committen.
---
<!-- _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)
Formattierungssprache mit strenger Syntax:
```
<element attribute="value"> ... </element>
```
- Öffnende und schließende Tags müssen identisch sein
- Schließendes Tag hat ein `/` nach der Spitzklammer
---
# 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 -->
# 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** ✓
```html
<link rel="stylesheet" href="style.css">
```
**Option 2: Style-Tag**
```html
<style>p { color: blue; }</style>
```
**Option 3: Inline** ✗
```html
<p style="color: blue;">...</p>
```
→ Standard ist externe Datei. Inline vermeiden (schwer zu warten, keine Wiederverwendung).
---
# CSS-Anatomie
![bg right:35%](./assets/demos/css-anatomie.png)
```css
selector {
property: value;
}
```
**Beispiel:**
```css
h1 {
color: #333333;
font-size: 2rem;
margin-bottom: 1rem;
}
```
Selektor → was wird gestylt
Property → welche Eigenschaft
Value → welcher Wert
---
# 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.
⚠️ 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). Tiefer in `02_css_extended`.
---
# 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 -->
<!-- _header: '' -->
<!-- _backgroundColor: #000 -->
# JavaScript
---
# JavaScript Grundlagen
```javascript
// Variablen
let name = "Welt";
const alter = 25;
// Funktionen
function gruss(name) {
return `Hallo, ${name}!`;
}
// Arrow Functions
const add = (a, b) => a + b;
// Arrays
const arr = [1, 2, 3];
arr.map(x => x * 2); // [2, 4, 6]
```
---
# DOM Manipulation
```javascript
// Element auswählen
const title = document.querySelector('h1');
// Inhalt ändern
title.textContent = 'Neue Überschrift';
// Event Listener
button.addEventListener('click', () => {
alert('Geklickt!');
});
```
---
# Fetch API
```javascript
fetch('/api/products')
.then(res => res.json())
.then(data => {
console.log(data);
})
.catch(err => console.error(err));
```
---
# Async/Await
```javascript
async function loadProducts() {
try {
const res = await fetch('/api/products');
const data = await res.json();
return data;
} catch (err) {
console.error('Fehler:', err);
}
}
```
---
<!-- _header: '' -->
<!-- _footer: '' -->
<!-- _backgroundColor: #050517 -->
![bg fit](./assets/demos/web-engineering-mandala.png)
---
<!-- _backgroundColor: #050517 -->
<!-- _color: #e2e8f0 -->
# Web Engineering Mandala
Interaktive version: [nextlevelshit.github.io/web-engineering-mandala](https://nextlevelshit.github.io/web-engineering-mandala/)
3 Schichten:
- **Core Layer** — JS, HTML, CSS (vanilla)
- **Build Layer** — bundlers, runtimes, template engines, pre/post processors
- **Application Layer** — frontend, backend, frameworks, SSR, CSS-utilities
3 Segmente: HTML (blau) · JavaScript (rot) · CSS (grün) · Mittelpunkt: `package.json`
---
# JavaScript Frameworks – Kategorien
| Kategorie | Beispiele |
|-----------|-----------|
| **CSS Frameworks** | Tailwind, Bootstrap, shadcn/ui |
| **Frontend Frameworks** | React, Vue, Svelte, Astro |
| **Rendering / Meta** | Next.js, Nuxt, Gatsby |
| **Build Tools / Bundler** | Webpack, Vite, Parcel, esbuild |
| **Backend Frameworks** | Express, Fastify, NestJS |
---
# Vanilla JS – Counter
```html
<button id="myButton">Clicked 0 times</button>
<script>
let count = 0;
const btn = document.getElementById('myButton');
btn.addEventListener('click', () => {
count++;
btn.textContent = `Clicked ${count} times`;
});
</script>
```
✓ hohe Kompatibilität, simpel
✗ State-Management, Re-Rendering wird schnell komplex
---
# React – Counter (JSX)
```jsx
import { useState } from "react";
function MyButton() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(count + 1)}>
Clicked {count} times
</button>
);
}
```
- **Component-Based** Architecture
- **Virtual DOM**, JSX, Hooks
- großes Ökosystem (React Router, Redux, …)
---
# Vue 3 – Composition API
```vue
<script setup>
import { ref } from "vue";
const count = ref(0);
</script>
<template>
<button @click="count++">
Clicked {{ count }} times
</button>
</template>
```
- **Reactive Data Binding**
- Single-File Components (`.vue`)
- Vue Router, Pinia (State)
---
# Svelte – Counter
```svelte
<script>
let count = 0;
</script>
<button on:click={() => count += 1}>
Clicked {count} {count === 1 ? 'time' : 'times'}
</button>
```
- **Compiler-Based** – kein Runtime-Framework
- Reactive Assignments (`let`)
- Built-in Animationen
---
# Astro – Content-First
```astro
---
const greeting = "Hallo DHBW";
---
<html>
<body>
<h1>{greeting}</h1>
<MyReactButton client:load />
</body>
</html>
```
- **Islands Architecture** – Komponenten mehrerer Frameworks mischen
- Default: kein JS im Output (nur statisches HTML)
- Hydration on demand (`client:load`, `client:visible`)
---
# Rendering Frameworks
| | Frontend | SSR | SSG | File Routing |
|---|---|---|---|---|
| **Next.js** | React | ✓ | ✓ | `/app/page.js` |
| **Nuxt** | Vue | ✓ | ✓ | `/pages/*.vue` |
| **Gatsby** | React | – | ✓ | GraphQL Data |
---
# Build Tools – Webpack
- Module Bundling (JS, CSS, Images)
- Module Loaders + großes Plugin-Ökosystem
- Code Splitting, HMR
- Konfigurations-lastig (`webpack.config.js`)
→ Standard für viele Legacy-Setups.
---
# Build Tools – Vite
```javascript
// vite.config.js
import { defineConfig } from "vite";
export default defineConfig({
server: {
proxy: {
"/api": {
target: "http://localhost:4567",
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, "")
}
}
}
});
```
- Rollup unter der Haube, **HMR mit ES Modules**
- Tree-Shaking, Code Splitting, React + Vue out-of-the-box
---
# Build Tools – Parcel
```json
{
"name": "my-project",
"source": "src/index.html",
"browserslist": "> 0.5%, last 2 versions, not dead",
"scripts": {
"start": "parcel",
"build": "parcel build"
},
"devDependencies": {
"parcel": "latest"
}
}
```
- **Zero-Config**
- Auto-Resolution, HMR
- TS / CSS-Preprocessors out-of-the-box
---
# Microfrontends
- Mehrere unabhängige Frontend-Apps in einer Page
- Module Federation (Webpack 5)
- **single-spa**: https://single-spa.js.org/
- Anwendungsfall: große Teams, unterschiedliche Tech-Stacks pro Domain
→ Komplexitätskosten: nur bei echtem Skalierungsbedarf.
---
# Demo-Repos
- https://github.com/nextlevelshit/dhbw-client-js (Counter, multi-framework)
- https://github.com/nextlevelshit/node-cache-api (API + Tests)
- https://github.com/nextlevelshit/dhbw-docker (Compose-Stack)