223015b: - add WTF hex code explanation slide (89=137 decimal, PNG signature) - add ASCII lead slide with historical context - remove Hilbert-Studie reference from title 223015c termin 2: - add OSI layer 5 (session) and layer 6 (presentation) slides - add URL/domain anatomy slide - mark HTTP/S section as klausur - improve status codes formatting with client/server examples - add CRUD column to HTTP methods table infrastructure: - add dev-server.sh for multi-course development - update generate-index.sh with course-specific colors - add QR codes for slide URLs
35 KiB
marp, theme, paginate, backgroundColor, header, footer, title
| marp | theme | paginate | backgroundColor | header | footer | title |
|---|---|---|---|---|---|---|
| true | gaia | true | Grundlagen IT- und Internettechnik | Michael Czechowski – HdM Stuttgart – WS 2025/26 | Termin 2: Netzwerke, Protokolle & CSS |
Grundlagen IT- und Internettechnik
223015c · Modul "Technik 1" · 1. Semester Digital- und Medienwirtschaft Hochschule der Medien Stuttgart
Wintersemester 2025/26
https://librete.ch/hdm/223015c/
Termin 2 – 10.01.2026
Netzwerke, Protokolle & CSS
Rückblick Termin 1
Was wir gelernt haben:
- Geschichte: Lovelace -> Hollerith → IBM -> Turing → Von Neumann → ARPANET -> Kalifornische ForscherInnen
- Von-Neumann-Architektur (5 Komponenten)
- Bits, Bytes, Hexadezimal (8Bits = 2 * 4Bits = 16 * 16 Hexadezimalzahlen)
Fragen? Unklarheiten?
Heute
Vormittag:
- Netzwerke (OSI, TCP/IP)
- DNS: Wie funktionieren Domain-Namen?
- HTTP(S) im Detail
Nachmittag:
- CSS-Grundlagen
- "Barrierefreiheit" (a11y, WCAG)
- Selektoren & Spezifität
- Hands-On: Styling
Ressourcen zum Selbstlernen
- Online Code-Editor: https://codepen.io/pen/
- MDN (Mozilla Developer Network): https://developer.mozilla.org/de/
- HTML-Referenz: https://nextlevelshit.github.io/html-over-js/
- CSS lernen: https://codescripsi.es/
- Flexbox-Spiel: https://flexboxfroggy.com/
- Grid-Spiel: https://cssgridgarden.com/
Teil 1: Rechner verbinden
Netzwerk-Grundlagen
Warum Rechner verbinden?
- Daten und Informationen teilen
- Zusammenarbeiten & Kollaboration
- Kommunizieren
- Ressourcen teilen (Drucker, Speicher, andere Geräte)
Kommunikationsarten
| Kategorie | Beispiel |
|---|---|
| Synchron | Telefonat, Video-Call |
| Asynchron | E-Mail, Brief, SMS |
| Verbindungsorientiert | Telefon (Leitung aufbauen) |
| Verbindungslos | Brief, Postkarte |
Das OSI-Modell
7 Schichten der Netzwerkkommunikation:
| Schicht | Name | Beispiel |
|---|---|---|
| 7 | Anwendung | HTTP, FTP, SMTP |
| 6 | Darstellung | Verschlüsselung, Kompression |
| 5 | Sitzung | Sessions |
| 4 | Transport | TCP, UDP |
| 3 | Vermittlung | IP, Routing |
| 2 | Sicherung | Ethernet, MAC |
| 1 | Bitübertragung | Kabel, WLAN |
TCP/IP: Die Praxis
Das Internet nutzt TCP/IP (4 Schichten):
| TCP/IP | Entspricht OSI | Protokolle |
|---|---|---|
| Anwendung | 5-7 | HTTP, DNS, SMTP |
| Transport | 4 | TCP, UDP |
| Internet | 3 | IP |
| Netzzugang | 1-2 | Ethernet, WLAN |
TCP/IP = Transmission Control Protocol / Internet Protocol
IP-Adressen
Jeder Rechner im Netzwerk braucht eine Adresse
IPv4: 4 Zahlen (0-255), Punkt-getrennt
192.168.1.1
Problem: 2⁸·2⁸·2⁸·2⁸ = 2³² = nur 4,3 Milliarden Adressen → Reicht nicht für alle Geräte!
IPv6: 128 Bit = 3,4 × 10³⁸ Adressen
2001:0db8:85a3:0000:0000:8a2e:0370:7334
Spezielle IP-Adressen
| Adresse | Bedeutung |
|---|---|
127.0.0.1 |
Localhost – Ihr eigener Rechner |
192.168.x.x |
Private Adressen (Heimnetz) |
10.x.x.x |
Private Adressen (Firmen) |
Localhost = "Ich selbst" → Perfekt für Web-Entwicklung!
Ports: Die Türnummern
IP-Adresse = Hausnummer Port = Wohnungstür
| Port | Dienst |
|---|---|
| 80 | HTTP (Web) |
| 443 | HTTPS (Web, verschlüsselt) |
| 22 | SSH (Terminal) |
| 25 | SMTP (E-Mail senden) |
Beispiel: 192.168.1.1:8080
(IP-Adresse : Port)
Routing: Der Weg durchs Netz
Router = Postamt
- Entscheidet, wohin Pakete gehen
- Findet besten Weg
- Pakete können verschiedene Wege nehmen!
Traceroute: Zeigt den Weg
traceroute google.de # Mac/Linux
tracert google.de # Windows
Teil 1: Netzwerke
Wie Daten reisen
Wiederholung: OSI-Modell
Merksatz: "Alle deutschen Studierenden trinken verschiedene Sorten Bier/Brause"
| Schicht | Name | Merksatz |
|---|---|---|
| 7 | Anwendung | Alle |
| 6 | Darstellung | deutschen |
| 5 | Sitzung | Studierenden |
| 4 | Transport | trinken |
| 3 | Vermittlung | verschiedene |
| 2 | Sicherung | Sorten |
| 1 | Bitübertragung | Bier/Brause |
OSI vs. TCP/IP
OSI-Modell TCP/IP-Modell
┌─────────────────┐ ┌─────────────────┐
│ 7. Anwendung │ │ │
├─────────────────┤ │ Anwendung │
│ 6. Darstellung │ │ (HTTP, DNS, │
├─────────────────┤ │ SMTP, FTP) │
│ 5. Sitzung │ │ │
├─────────────────┤ ├─────────────────┤
│ 4. Transport │ │ Transport │
│ │ │ (TCP, UDP) │
├─────────────────┤ ├─────────────────┤
│ 3. Vermittlung │ │ Internet │
│ │ │ (IP) │
├─────────────────┤ ├─────────────────┤
│ 2. Sicherung │ │ │
├─────────────────┤ │ Netzzugang │
│ 1. Bitübertrag │ │ │
└─────────────────┘ └─────────────────┘
Schicht 1: Bitübertragung
Physikalische Übertragung von Bits
| Medium | Beschreibung |
|---|---|
| Kupferkabel | Elektrische Signale (Ethernet) |
| Glasfaser | Lichtimpulse (schnell, weit) |
| Funk | Elektromagnetische Wellen (WLAN, 5G) |
Einheiten:
- Bit/s, kbit/s, Mbit/s, Gbit/s
- Achtung: 100 Mbit/s ≠ 100 MB/s!
Schicht 2: Sicherung
MAC-Adressen: Hardware-Identifikation
00:1A:2B:3C:4D:5E
- 48 Bit = 6 Bytes
- Weltweit eindeutig (in Theorie)
- In Netzwerkkarte "eingebrannt"
Ethernet-Frame:
┌────────┬────────┬────────┬────────┬─────┐
│Präambel│Ziel-MAC│Src-MAC │ Daten │ FCS │
└────────┴────────┴────────┴────────┴─────┘
Schicht 3: Vermittlung (IP)
IP-Adressen: Logische Adressierung
IPv4: 192.168.1.100 (32 Bit)
IPv6: 2001:db8::1 (128 Bit)
Subnetzmaske: Trennt Netzwerk von Host
IP: 192.168. 1.100
Maske: 255.255.255. 0
└─Netzwerk─┘└Host┘
Router arbeiten auf Layer 3 (IP-Routing)
Schicht 4: Transport
TCP vs. UDP
| Eigenschaft | TCP | UDP |
|---|---|---|
| Verbindung | Ja (3-Way-Handshake) | Nein |
| Zuverlässig | Ja (Bestätigung) | Nein |
| Reihenfolge | Garantiert | Nicht garantiert |
| Geschwindigkeit | Langsamer | Schneller |
| Anwendung | Web, E-Mail | Streaming, Gaming |
TCP: 3-Way-Handshake
Client Server
│ │
│──── SYN (Seq=100) ──────────>│
│ │
│<─── SYN-ACK (Seq=300, Ack=101)│
│ │
│──── ACK (Seq=101, Ack=301) ──>│
│ │
│ Verbindung hergestellt │
SYN = Synchronize ACK = Acknowledge
Schicht 5: Sitzung (Session)
Verwaltet Verbindungen zwischen Anwendungen:
- Sessions → Login-Sitzungen, "eingeloggt bleiben"
- Dialogsteuerung → Wer darf wann senden?
- Synchronisation → Wiederaufnahme nach Abbruch
Beispiele:
- Web-Sessions (Cookies, Tokens)
- RPC (Remote Procedure Call)
- NetBIOS
Schicht 6: Darstellung (Presentation)
Übersetzt Datenformate:
| Funktion | Beispiel |
|---|---|
| Encoding | UTF-8, ASCII, Unicode |
| Verschlüsselung | TLS/SSL (HTTPS) |
| Kompression | gzip, deflate |
| Serialisierung | JSON, XML, Protobuf |
TLS/SSL: Transport Layer Security → Verschlüsselt HTTP zu HTTPS
Schicht 7: Anwendung
Protokolle, die wir täglich nutzen:
| Protokoll | Port | Funktion |
|---|---|---|
| HTTP | 80 | Webseiten (unverschlüsselt) |
| HTTPS | 443 | Webseiten (TLS-verschlüsselt) |
| DNS | 53 | Namensauflösung |
| SMTP | 25/587 | E-Mail senden |
| IMAP | 993 | E-Mail abrufen |
| SSH | 22 | Sichere Fernsteuerung |
DNS: Das Telefonbuch des Internets
Das Problem
Menschen: www.hdm-stuttgart.de
Computer: 212.132.79.37
DNS = Domain Name System → Übersetzt Namen in IP-Adressen
DNS-Hierarchie
(Root)
.
/ | \
/ | \
.de .org .com
/ \
hdm-stuttgart google
| |
www mail
FQDN: www.hdm-stuttgart.de. (mit Punkt am Ende!)
DNS-Auflösung
1. Browser fragt lokalen DNS-Resolver
2. Resolver fragt Root-Server → ".de ist bei..."
3. Resolver fragt .de-Server → "hdm-stuttgart bei..."
4. Resolver fragt hdm-Server → "www = 212.132.79.37"
5. Resolver cached Antwort
6. Browser verbindet zu 212.132.79.37
Caching: Antworten werden gespeichert → Schneller bei wiederholten Anfragen
DNS-Records
| Typ | Bedeutung | Beispiel |
|---|---|---|
| A | IPv4-Adresse | www → 212.132.79.37 |
| AAAA | IPv6-Adresse | www → 2001:db8::1 |
| CNAME | Alias | blog → www.example.com |
| MX | Mail-Server | @ → mail.example.com |
| TXT | Text (Verifikation) | "v=spf1..." |
URLs & Domains
URL = Uniform Resource Locator
https://www.example.com:443/pfad/seite.html?suche=test#kapitel2
└─┬──┘ └──────┬──────┘└┬┘ └──────┬──────┘ └───┬────┘ └──┬───┘
Protokoll Hostname Port Pfad Query Fragment
| Begriff | Erklärung |
|---|---|
| Domain | example.com (registrierter Name) |
| Subdomain | www, mail, api (Prefix) |
| Hostname | www.example.com (vollständig) |
| Port | Standard: 80 (HTTP), 443 (HTTPS) |
HTTP/S im Detail
HTTP-Request
GET /index.html HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Accept: text/html,application/xhtml+xml
Accept-Language: de-DE,de;q=0.9,en;q=0.8
Connection: keep-alive
| Teil | Bedeutung |
|---|---|
GET |
Methode (was will ich?) |
/index.html |
Pfad (welche Ressource?) |
HTTP/1.1 |
Protokoll-Version |
Host: |
Ziel-Server |
HTTP-Response
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Content-Length: 1234
<!DOCTYPE html>
<html>...</html>
Status-Codes:
- 2xx Erfolg
- 3xx Umleitung
- 4xx Client-Fehler (Browser, App, WhatsApp)
- 5xx Server-Fehler (Instagram, Google, HdM)
HTTP-Methoden
| Methode | CRUD | Zweck | Beispiel |
|---|---|---|---|
| GET | Read | Daten abrufen | Seite laden |
| POST | Create | Daten senden | Formular absenden |
| PUT | Update | Daten ersetzen | Profil aktualisieren |
| PATCH | Update | Daten teilweise ändern | Einzelnes Feld |
| DELETE | Delete | Daten löschen | Account löschen |
Teil 2: CSS
Webseiten gestalten
Was ist CSS?
Cascading Style Sheets
- Trennt Inhalt (HTML) von Darstellung (CSS)
- "Cascading" = Regeln können überschrieben werden
- Eine CSS-Datei für viele HTML-Seiten
p {
color: blue;
font-size: 16px;
}
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 als HTML-Attribute (vermeiden!)
<p style="color: blue;">...</p>
CSS-Anatomie
selector {
property: value;
property: value;
}
Beispiel:
h1 {
color: #333333;
font-size: 2rem;
margin-bottom: 1rem;
}
Selektoren: Element
/* Alle <p>-Elemente */
p {
color: gray;
}
/* Alle <h1>-Elemente */
h1 {
font-size: 2rem;
}
/* Mehrere Elemente */
h1, h2, h3 {
font-family: sans-serif;
}
Selektoren: Klasse
<p class="wichtig">Dieser Text ist wichtig.</p>
<p>Dieser nicht.</p>
/* Alle Elemente mit class="wichtig" */
.wichtig {
color: red;
font-weight: bold;
}
Punkt vor dem Namen = Klasse
Selektoren: ID
<nav id="hauptnavigation">...</nav>
/* Element mit id="hauptnavigation" */
#hauptnavigation {
background: #333;
padding: 1rem;
}
Raute vor dem Namen = ID
⚠️ IDs sollten einmalig pro Seite sein!
Selektoren: Kombinationen
/* Nachfahre (egal wie tief verschachtelt) */
article p {
line-height: 1.6;
}
/* Direktes Kind */
nav > a {
text-decoration: none;
}
/* Nächstes Geschwister */
h2 + p {
font-size: 1.2rem;
}
/* Element mit Klasse */
p.wichtig {
color: red;
}
Spezifität: Wer gewinnt?
Wenn mehrere Regeln auf ein Element zutreffen:
| 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 |
Höhere Spezifität gewinnt!
p { color: blue; } /* 0,0,0,1 */
.text { color: green; } /* 0,0,1,0 → gewinnt! */
Box-Modell
┌─────────────────────────────────────┐
│ margin │
│ ┌─────────────────────────────┐ │
│ │ border │ │
│ │ ┌─────────────────────┐ │ │
│ │ │ padding │ │ │
│ │ │ ┌─────────────┐ │ │ │
│ │ │ │ content │ │ │ │
│ │ │ └─────────────┘ │ │ │
│ │ └─────────────────────┘ │ │
│ └─────────────────────────────┘ │
└─────────────────────────────────────┘
Box-Modell: CSS
.box {
/* Inhalt */
width: 200px;
height: 100px;
/* Innenabstand */
padding: 20px;
/* Rahmen */
border: 2px solid black;
/* Außenabstand */
margin: 10px;
/* Berechnung vereinfachen */
box-sizing: border-box;
}
Farben in CSS
/* Keyword */
color: red;
color: rebeccapurple;
/* Hex (RGB) */
color: #FF0000;
color: #F00; /* Kurzform */
/* RGB/RGBA */
color: rgb(255, 0, 0);
color: rgba(255, 0, 0, 0.5); /* 50% transparent */
/* HSL */
color: hsl(0, 100%, 50%); /* Hue, Saturation, Lightness */
Einheiten
| Einheit | Bedeutung | Beispiel |
|---|---|---|
px |
Pixel (absolut) | font-size: 16px |
% |
Prozent vom Parent | width: 50% |
em |
Relativ zur Schriftgröße | padding: 1em |
rem |
Relativ zur Root-Schriftgröße | font-size: 1.5rem |
vw/vh |
Viewport-Breite/-Höhe | height: 100vh |
Empfehlung: rem für Schrift, % oder vw/vh für Layout
"Barrierefreiheit"
a11y – Accessibility
Wie nutzen Menschen das Web?
| Eingabe | Nutzungsweise |
|---|---|
| Maus | Klicken, Scrollen |
| Tastatur | Tab-Navigation, Enter, Pfeiltasten |
| Screenreader | Vorlesen von Inhalten (NVDA, VoiceOver, JAWS) |
| Sprachsteuerung | "Klicke auf Anmelden" |
| Augensteuerung | Eye-Tracking |
| Switch-Geräte | Ein-/Aus-Schalter |
→ Nicht alle nutzen Maus + Bildschirm!
Warum "Barrierefreiheit"?
Rechtlich:
- EU: European Accessibility Act (seit Juni 2025 in Kraft!)
- DE: BITV 2.0 (Behörden), Privatwirtschaft betroffen
Ethisch:
- Teilhabe für alle Menschen
- Digitale Inklusion
Praktisch:
- Bessere UX für alle (SEO, Mobile, ältere Menschen)
- Größerer Markt (~15% der Bevölkerung)
WCAG: Der Standard
Web Content Accessibility Guidelines
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 |
Perceivable: Wahrnehmbar
Textalternativen für Nicht-Text:
<img src="team.jpg" alt="Unser Team bei der Weihnachtsfeier 2024">
Kontrast: Mindestens 4.5:1 für Text
Untertitel: Videos brauchen Captions
Responsive: Inhalte bei 200% Zoom nutzbar
Operable: Bedienbar
Tastaturzugänglich:
/* Fokus-Indikator NIE entfernen! */
:focus {
outline: 2px solid blue;
outline-offset: 2px;
}
/* Wenn custom styling: */
button:focus-visible {
box-shadow: 0 0 0 3px rgba(0, 100, 255, 0.5);
}
Genug Zeit: Keine automatischen Timeouts ohne Warnung
Keine Blitze: Nichts blinkt mehr als 3x pro Sekunde
Understandable: Verständlich
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 geben Sie eine gültige E-Mail-Adresse ein.
</p>
Robust: Technisch solide
Semantisches HTML:
<!-- Schlecht -->
<div class="button" onclick="...">Klick mich</div>
<!-- Gut -->
<button type="button">Klick mich</button>
ARIA nur wenn nötig:
<!-- Nötig: Custom-Komponente -->
<div role="tablist" aria-label="Produktkategorien">
<button role="tab" aria-selected="true">Schuhe</button>
<button role="tab" aria-selected="false">Jacken</button>
</div>
Barrieren im Netz vermeiden (a11y)
Tastatur-Test:
- Alle Funktionen nur mit Tab + Enter nutzbar?
- Fokus immer sichtbar?
- Logische Tab-Reihenfolge?
Screenreader-Test:
- VoiceOver (Mac):
Cmd + F5 - NVDA (Windows): Gratis-Download
Tools:
- axe DevTools, WAVE (Browser-Extensions)
- Lighthouse (in Chrome DevTools)
Teil 3: Layouts (optional)
Flexbox & mehr
Das Layout-Problem
Früher:
float: left(Hack!)- Tabellen für Layout (Horror!)
- Absolute Positionierung
Heute:
- Flexbox – Eindimensional (Zeile ODER Spalte)
- Grid – Zweidimensional (Zeilen UND Spalten)
Flexbox: Grundlagen
.container {
display: flex;
}
<div class="container">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
</div>
Ergebnis: Items nebeneinander (Zeile)
Flexbox: Richtung
.container {
display: flex;
flex-direction: row; /* Standard: Zeile */
flex-direction: column; /* Spalte */
flex-direction: row-reverse;
flex-direction: column-reverse;
}
Flexbox: Ausrichtung
.container {
display: flex;
/* Hauptachse (horizontal bei row) */
justify-content: flex-start; /* Links */
justify-content: center; /* Mitte */
justify-content: flex-end; /* Rechts */
justify-content: space-between; /* Verteilt */
justify-content: space-around;
/* Querachse (vertikal bei row) */
align-items: flex-start; /* Oben */
align-items: center; /* Mitte */
align-items: flex-end; /* Unten */
align-items: stretch; /* Strecken */
}
Flexbox: Zentrieren
Das berühmte "Vertikal zentrieren":
.container {
display: flex;
justify-content: center; /* Horizontal */
align-items: center; /* Vertikal */
height: 100vh; /* Volle Höhe */
}
Früher: Dutzende Hacks nötig Heute: 3 Zeilen CSS
Flexbox: Items
.item {
/* Wachsen */
flex-grow: 1; /* Nimmt verfügbaren Platz */
/* Schrumpfen */
flex-shrink: 1; /* Schrumpft bei Platzmangel */
/* Basisgröße */
flex-basis: 200px;
/* Kurzform */
flex: 1; /* grow: 1, shrink: 1, basis: 0 */
flex: 0 0 200px; /* grow: 0, shrink: 0, basis: 200px */
}
Flexbox: Beispiel Navigation
nav {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem 2rem;
background: #333;
}
nav a {
color: white;
text-decoration: none;
padding: 0.5rem 1rem;
}
nav a:hover {
background: #555;
}
Pseudo-Klassen
/* Zustände */
a:hover { color: red; }
a:visited { color: purple; }
input:focus { border-color: blue; }
/* Struktur */
li:first-child { font-weight: bold; }
li:nth-child(odd) { background: #eee; }
Pseudo-Elemente
.required::before {
content: "* ";
color: red;
}
p::first-letter { font-size: 2em; }
p::first-line { font-weight: bold; }
Unterschied: : = Pseudo-Klasse · :: = Pseudo-Element
Responsive Design
Media Queries: CSS je nach Bildschirmgröße
/* Mobile First: Standard */
.container { padding: 1rem; }
/* Ab 768px (Tablet) */
@media (min-width: 768px) {
.container { padding: 2rem; max-width: 720px; }
}
Breakpoints: 768px (Tablet) · 1024px (Desktop) · 1280px (Large)
Teil 4: CSS vertiefen
Transitions & moderne Features
Transitions: Sanfte Übergänge
.button {
background: #3498db;
color: white;
padding: 1rem 2rem;
border: none;
cursor: pointer;
/* Transition */
transition: background 0.3s ease;
}
.button:hover {
background: #2980b9;
}
Kein JavaScript nötig!
Transitions: Mehrere Properties
.card {
background: white;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
transform: translateY(0);
transition:
box-shadow 0.3s ease,
transform 0.3s ease;
}
.card:hover {
box-shadow: 0 8px 16px rgba(0,0,0,0.2);
transform: translateY(-4px);
}
CSS Custom Properties (Variablen)
:root {
--primary-color: #3498db;
--secondary-color: #2ecc71;
--text-color: #333;
--spacing: 1rem;
}
.button {
background: var(--primary-color);
padding: var(--spacing);
color: white;
}
.button.secondary {
background: var(--secondary-color);
}
Dark Mode
:root {
--bg-color: white;
--text-color: #333;
}
@media (prefers-color-scheme: dark) {
:root {
--bg-color: #1a1a1a;
--text-color: #eee;
}
}
body {
background: var(--bg-color);
color: var(--text-color);
}
Fragen & Diskussion
Nächster Termin: 24.01.2026 – JavaScript
Kontakt: mail@librete.ch
Lizenz
Diese Präsentation ist lizenziert unter Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)
Basiert auf Material von:
- Markus Thamm / Wolfgang Gruel (HdM Stuttgart)
- Michael Czechowski
Vollständige Lizenz: https://creativecommons.org/licenses/by-sa/4.0/

