per user-feedback nach QA-render-check aller 493 folien (overflow-detector via PIL bottom-band-darkness): 223015b/01-daten-grundlagen s.036 nyquist: H1 'Nyquist-Theorem — warum 2× reicht' → 'Nyquist — warum 2× reicht' body text gekürzt, drei fälle als * statt - (marp fragmented list) 223015b/03-inhalte-bild-audio-video s.009 RGB→Y'CbCr: H1 verkürzt, bg right 50% → 45% contain, list-marker * (Y/Cb/Cr reveal) text 'unabhängig komprimiert werden' eingedampft 223015b/03-inhalte-bild-audio-video s.031 inter-frame: H1 'Inter-Frame-Kompression — die zentrale Idee' → 'Inter-Frame — die zentrale Idee' bg right 42% → 40% contain bullets I/P/B mit * (fragmented reveal) 223015b/05-distribution-metadaten s.012 EXIF-tabelle: 8 zeilen → 5 zeilen (kamera+linse zusammengelegt, belichtung kompakt, software+bearbeitung zusammengelegt) 223015b/05-distribution-metadaten s.014 EXIF-stripping: 7 plattform-zeilen → 5 (facebook+iMessage und E-mail+slack+discord zusammen) faustregel als italic-zeile statt bold-block 223015c/01-geschichte-grundlagen-html s.006 alan turing: bg right 35% (default fill) → 33% contain (verhindert dass composite-bild bis footer reicht) 3 jahres-zeilen als * bullets (fragmented reveal) dhbw/01_web_eng s.054 counter: in 2 folien gesplittet: 'Counter — Vanilla + React' und 'Counter — Vue + Svelte' pointe 'vier frameworks, dasselbe pattern: state → UI re-rendert' am ende der 2. folie dhbw/08_best_practices s.005 .gitignore: code-block gekürzt: 6 sektionen → 5, mehrere lines pro logical group zusammengezogen (pem+key zusammen, vscode+idea zusammen) github.com/github/gitignore als markdown-link bonus: wo pädagogisch sinnvoll - durch * ersetzt (marp progressive-reveal in presenter-modus). nicht überall — nur wo bullets sequenziell aufgedeckt werden sollten. klausurfolien regeneriert (223015b 27, 223015c 19)
17 KiB
marp, theme, paginate, backgroundColor, header, footer, title
| marp | theme | paginate | backgroundColor | header | footer | title |
|---|---|---|---|---|---|---|
| true | gaia | true | Web Engineering – DHBW Stuttgart | Michael Czechowski – SoSe 2026 | Web Engineering |
Web Engineering
DHBW Stuttgart · Informatik / Wirtschaftsinformatik Sommersemester 2026
Ressourcen zum Selbstlernen
- CODE CRISPIES — codecrispi.es
- Online Code-Editor — codepen.io
- MDN — developer.mozilla.org
- Flexbox-Spiel — flexboxfroggy.com
- Grid-Spiel — cssgridgarden.com
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 |
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
- URL parsen — Schema, Host, Port, Path
- DNS-Lookup — Host-Name → IP
- TCP-Handshake mit Server
- TLS-Handshake (https)
- HTTP-Request senden
- Server antwortet mit HTML + CSS + JS
- Browser parsed + rendert → Pixel
HTTP — Anatomie
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
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
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:
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
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
<a href="https://librete.ch" target="_blank">Mein Link</a>
<a— Opening-Tag mit Tag-Namenhref="..."— Attribut (Name + Wert)Mein Link— Inhalt</a>— Closing-Tag- Alles zusammen = Element
Self-closing Tags
<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
<!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.
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 |
|---|---|
| Perceivable | Alt-Text · Untertitel · Kontrast |
| Operable | Keyboard · Skip-Links |
| Understandable | klare Sprache · Fehler-Hilfe |
| Robust | 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 %
<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-visiblemit Outline) - Skip-Links für Screen-Reader (Hauptnav überspringen)
- Genug Zeit für Aufgaben (Auto-Logout pausierbar)
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 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)
<!-- ❌ 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.
CSS
Cascading Style Sheets
(Vertiefung in Kap 2 — CSS Extended)
CSS einbinden
<!-- 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
button {
background-color: hotpink;
padding: 10px 20px;
border-radius: 8px;
}
button= Selektor (welche Elemente)background-color= Propertyhotpink= 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?
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
/* 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: " 💡"; }
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
// 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
// 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
// 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: '...' })
});
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:
let count = 0;
btn.onclick = () => { count++; display.textContent = count; };
React (JSX):
function Counter() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(count + 1)}>{count}</button>;
}
Counter — Vue + Svelte
Vue 3 (Composition):
<script setup>const count = ref(0)</script>
<template><button @click="count++">{{ count }}</button></template>
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.
Selbstlernen — Erste eigene Seite
- Mappe anlegen
meine-seite/ index.htmlmit dem Grundgerüst (DOCTYPE, head, body, h1, p)style.cssdaneben — mit Hotpink-Background- VS Code Live Server starten → im Browser öffnen
- 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.

