Files
uni/slides/dhbw/01_web_eng.md
T

40 KiB
Raw Blame History

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
<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>

bg cover opacity:0.2

Web Engineering

DHBW Stuttgart · Informatik / Wirtschaftsinformatik

Sommersemester 2026


Ressourcen zum Selbstlernen


Herzlich Willkommen!

1. Sitzung: 08.05.2026


Über mich

bg right:33% fit

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

<style scoped> .lp-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; margin-top: 0.5rem; } .lp-card { border: 1px solid #d63384; border-radius: 8px; padding: 10px 12px; background: #fff; font-size: 0.95em; display: flex; flex-direction: column; gap: 4px; } .lp-card .head { font-weight: bold; color: #a02060; display: flex; justify-content: space-between; align-items: baseline; font-size: 0.85em; } .lp-card .head .num { font-size: 1.1em; } .lp-card .topic { color: #1a1a2e; line-height: 1.25; } .lp-card.milestone { background: #fce4ec; border-color: #a02060; border-width: 2px; } .lp-card.milestone .topic { font-weight: bold; } </style>
108.05.
Intro · Projektgruppen · Internet 101
215.05.
HTML und CSS (Frameworks)
322.05.
JS (Frameworks) und npm
429.05.
nodeJS: Scripting, Running, Building
505.06.
Express API, CRUD, Middlewares
612.06.
Projektwerkstattbericht
719.06.
Testing (Unit · Integration · E2E)
826.06.
TypeScript
903.07.
Docker · Proxies · DBs
1010.07.
Wrap-up & Projektsupport
1117.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:
    • Single Responsibility Principle
    • Open/Closed Principle
    • Liskov Substitution Principle
    • Interface Segregation Principle
    • Dependency 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.librete.ch/DHBW/pruefungsleistung


Internet-Timeline

Jahr Meilenstein
1966 ARPANET-Projekt startet (DARPA)
1969 Erste Verbindung zwischen UCLA und Stanford
1974 TCP/IP-Protokoll entwickelt
1989 Tim Berners-Lee erfindet das WWW (CERN)
1993 Mosaic — erster grafischer Browser
1994 W3C gegründet (HTML, CSS, SVG, WCAG)
1995 ECMAScript / JavaScript wird Standard
2008 V8 JavaScript Engine (Chrome / Node.js)

bg fit


Das WWW (1989)

Tim Berners-Lee am CERN (Genf)

Problem: Wissenschaftler:innen können Forschungsdokumente nicht verlinken — Inkompatible Systeme, kein gemeinsames Format.

Lösung — drei Bausteine:

  • HTML — Auszeichnungssprache für Dokumente
  • HTTP — Protokoll zur Übertragung
  • URL — eindeutige Adressen

1991: erste Webseite geht online · 1993 vom CERN gemeinfrei freigegeben.

→ WWW ≠ Internet. Das WWW ist eine Anwendung auf dem Internet.


bg fit


bg cover


Heute: Physische Infrastruktur

  • 5,5 Milliarden Menschen online
  • > 400 Unterseekabel, ca. 1,3 Mio. km Glasfaser
  • Daten reisen mit Lichtgeschwindigkeit
  • Latenz Frankfurt — New York: ~80 ms

→ Keine "Cloud" ohne Kabel. Das Internet ist physische Infrastruktur — und damit angreifbar.

Geopolitik: Five-Eyes-Allianz (USA, UK, CA, AU, NZ) zapft Unterseekabel ab (Programm "Tempora", aufgedeckt 2013 durch Snowden). DE ist Teil der Fourteen Eyes.


bg fit


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"}, ...]

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

# 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


Node.js installieren – Linux

Empfohlen: LTS (aktuell Node.js 24).

Debian / Ubuntu (NodeSource):

curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -
sudo apt install -y nodejs

Arch / Manjaro:

sudo pacman -S nodejs npm

Fedora / RHEL:

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):

winget install OpenJS.NodeJS.LTS

Option 2: Chocolatey (chocolatey.org):

choco install nodejs-lts

Option 3: Scoop (scoop.sh):

scoop install nodejs-lts

Option 4: Installer von nodejs.org

→ Empfehlung: WSL2 + Linux-Workflow nutzen.


Direkt-Install: Wenn es eng wird

Typisches Szenario — 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 → Konflikt.


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
# 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
# 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
  • Vim / Neovim / Emacs — für CLI-Profis
  • Zed — modern, schnell

Browser DevTools

Chromium / Firefox / Safari — F12 oder Cmd+Opt+I

Chromium = Open-Source-Basis von Chrome, Edge, Brave, Opera, Vivaldi etc.

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) — open source, git-friendly
  • Hoppscotch (hoppscotch.io) — open source, browser-basiert (vormals Postwoman)
  • Insomnia / Postman — etabliert, freemium
  • curl / httpie — CLI (Command-Line Interface, scriptbar)

Git Setup & Workflow

Einmalige Konfiguration:

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:

ssh-keygen -t ed25519 -C "vorname.nachname@example.com"
cat ~/.ssh/id_ed25519.pub   # → in GitHub-Settings einfügen

Tägliche Befehle:

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

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:

{
  "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.


HTML – Hypertext Markup Language


Was ist HTML? (1/2)

HyperText Markup Language

  • Keine Programmiersprache
  • Am ehesten eine Formattierungssprache
  • Beschreibt Struktur und Aufbau einer Webseite
<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

In HTML sprechen wir von Elementen, in JavaScript eher von Nodes.


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>
  <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>
  <head>
    <title>DHBW Stuttgart</title>
    <meta name="description" content="Studium mit Praxis" />
    <meta property="og:image" content="https://...." />
  </head>
  ...
</html>

Webseiten besuchen nicht nur Menschen, sondern auch Suchmaschinen, Bots, Screen-Reader. Metadaten helfen beim "Verstehen" der Inhalte.


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):

<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%

<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%

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%

<!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

Semantische Tags (<header>, <main>, <article>, <footer>, <nav>, <aside>) wichtig für Accessibility.


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

Akkordion · Accordion · Aufklappmenü · Collapsible

bg right:35%

<details>
  <summary>Klick mich!</summary>
  <p>Dieser Text ist versteckt.</p>
</details>

Doku: developer.mozilla.org


Beispiel: Details/Summary (geöffnet)

bg right:35%

<details open>
  <summary>Klick mich!</summary>
  <p>Dieser Text war versteckt.</p>
</details>

Beispiel: Button

bg right:35%

<button>Add to favorites</button>

Doku: developer.mozilla.org


Beispiel: Input/Eingabefeld

bg right:35%

<input
  type="text"
  maxlength="8"
  size="10" />

Doku: developer.mozilla.org


Beispiel: Dialog

Modal · Modales Fenster · Popup · Overlay · Dialogfenster

bg right:35%

<dialog open>
  <p>Greetings, one and all!</p>
  <form method="dialog">
    <button>OK</button>
  </form>
</dialog>

Doku: developer.mozilla.org


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

Web Content Accessibility Guidelines · Herausgeber: W3C / WAI

Aktuell: WCAG 2.2 (verbindlich seit Okt. 2023). WCAG 3 in Working-Draft.

4 Prinzipien (POUR):

Prinzip Bedeutung
Perceivable Wahrnehmbar — Inhalte müssen erkennbar sein
Operable Bedienbar — Funktionen müssen nutzbar sein
Understandable Verständlich — Inhalte müssen klar sein
Robust Robust — funktioniert mit verschiedenen Technologien

Konformitätslevel: A · AA (gesetzlicher Standard) · AAA

→ w3.org/WAI/WCAG22/quickref


Perceivable: Wahrnehmbar

bg right:35% fit

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:

<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%

Tastaturzugänglich:

/* 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%

Sprache angeben:

<html lang="de">

Konsistente Navigation — gleiche Elemente an gleicher Stelle.

Fehler erklären:

<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%

Semantisches HTML:

<!-- Schlecht -->
<div class="button" onclick="...">Klick mich</div>

<!-- Gut -->
<button type="button">Klick mich</button>

ARIA — nur wenn nötig:

<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 Browser-Extension Kontrast, Struktur, Tab-Reihenfolge
Lighthouse Chrome DevTools Performance + A11y-Audit
axe DevTools Browser-Extension Detailanalyse, Regel-Engine
Pa11y CLI CI/CD-Integration

Screenreader (OS-nativ oder Open Source):

OS Screenreader
macOS / iOS VoiceOver (Cmd + F5) — builtin
Windows NVDA (OSS) · Narrator (builtin)
Linux Orca — 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


CSS – Cascading Style Sheets


Was ist CSS?

Cascading Style Sheets

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)

<link rel="stylesheet" href="style.css">

Option 2: Style-Tag

<style>p { color: blue; }</style>

Option 3: Inline (vermeiden)

<p style="color: blue;">...</p>

→ Standard ist externe Datei. Inline vermeiden (schwer zu warten, keine Wiederverwendung).


CSS-Anatomie

/* 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%

/* 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%

<p class="wichtig">Dieser Text ist wichtig.</p>
<p>Dieser nicht.</p>
.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%

<nav id="hauptnavigation">...</nav>
#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%

/* 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%

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
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

Jedes HTML-Element ist eine rechteckige Box.

Schichten innen → außen:

  • content – Inhalt (Text, Bild)
  • padding – Innenabstand
  • border – Rahmen
  • margin – Außenabstand

Gesamt-Breite = width + padding + border + margin. Tipp: box-sizing: border-box rechnet padding + border mit ein.


Box-Modell: CSS

bg right:35%

.box {
  width: 200px;
  height: 100px;
  padding: 20px;
  border: 2px solid black;
  margin: 10px;
}

Wichtig:

* {
  box-sizing: border-box;
}

→ width/height inkludiert padding + border.


Farben

bg right:35%

CSS kennt fünf Notationen für Farben: Keyword, Hex, RGB, RGBA (mit Transparenz) und HSL.

/* 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%

/* 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%

/* 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

.container {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
}

→ Eindimensionales Layout (Zeile oder Spalte). Tiefer in 02_css_extended.


Layout: Grid

.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
}

→ Zweidimensionales Layout (Zeilen und Spalten gleichzeitig).


Responsive Design

bg right:35%

/* 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!):

<meta name="viewport" content="width=device-width, initial-scale=1">

Moderne Alternativen: clamp(), Container Queries, CSS Grid auto-fit/auto-fill.


JavaScript


ECMAScript

  • Ecma International — European Computer Manufacturers Association
  • Seit 1997 standardisiert als ECMA-262
  • Implementierungen: JavaScript (Netscape, später Mozilla), JScript (Microsoft), ActionScript (Adobe Flash) etc.
  • Aktuelle Version: ECMAScript 2024 (ES15), jährliche Releases

Browser-Kompatibilität:

  • Faustregel: ES2017+ läuft in allen modernen Browsern
  • Ältere Targets via Transpiler (Babel, esbuild, swc, tsc)
  • Kompatibilitätstabelle: kangax.github.io/compat-table

JavaScript Grundlagen

// 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

// Element auswählen
const title = document.querySelector('h1');

// Inhalt ändern
title.textContent = 'Neue Überschrift';

// Event Listener
button.addEventListener('click', () => {
  alert('Geklickt!');
});

Fetch API

fetch('/api/products')
  .then(res => res.json())
  .then(data => {
    console.log(data);
  })
  .catch(err => console.error(err));

Async/Await

async function loadProducts() {
  try {
    const res = await fetch('/api/products');
    const data = await res.json();
    return data;
  } catch (err) {
    console.error('Fehler:', err);
  }
}

bg fit


Web Engineering Mandala

Interaktive version: 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

<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>

Pro: hohe Kompatibilität, simpel Contra: State-Management und Re-Rendering werden schnell komplex


React – Counter (JSX)

bg right:25% fit

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

bg right:25% fit

<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

bg right:25% fit

<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

bg right:25% fit

---
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 ja ja /app/page.js
Nuxt Vue ja ja /pages/*.vue
Gatsby React nein ja GraphQL Data

Build Tools – Webpack

bg right:25% fit

  • 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

bg right:25% fit

// 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

bg right:25% fit

{
  "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