dhbw phase 4: alle 8 kapitel slide-MD komplett (4176 zeilen → ~1100 zeilen, ~210 slides total)
kap1 web_eng (104 → 57 slides): kurs-intro + prüfungsleistung-übersicht, internet-timeline (4 milestones), URL→pixel-7-schritte, HTTP, onboarding (node 24 LTS via fnm, brew/winget paket-manager, VS Code/Chromium/Hoppscotch, git setup mit SSH-key, projekt-skeleton), HTML (anatomie, self-closing, grundgerüst, semantik-tabelle, native elemente details/dialog/input-types), A11y volle tiefe (BFSG+EAA 28.06.2025, WCAG-POUR, Perceivable/Operable/Understandable/Robust einzeln mit code, testen mit lighthouse/axe/manuell), CSS-vorschau (anatomie/selektoren/spezifizität/box-model/farben/einheiten/pseudos), JS-vorschau (ECMAScript-timeline/grundlagen/DOM/fetch), frameworks-übersicht (react/vue/svelte/astro counter-vergleich), build-tools/rendering-modi, selbstlernen erste-eigene-seite kap2 css_extended (13 → 28 slides): box-model + box-sizing global, flexbox basics+achsen+item-properties+typische-patterns, grid basics+areas+auto-layout, flexbox-vs-grid tabelle, mobile-first media queries, viewport-meta, fluid sizing mit clamp(), transitions (was performant), keyframe-animationen, prefers-reduced-motion pflicht, CSS-variablen + dark-mode-pattern, CSS functions (calc/clamp/gradient/oklch/filter), CSS-frameworks tabelle + tailwind pro/contra, selbstlernen flexboxfroggy+cssgridgarden kap3 nodejs_basics (~22 → 20 slides): was-ist-node + warum-node-tabelle, fnm versions-manager + node 24 LTS + .nvmrc, npm init + package.json (mit type:module), ESM modern + CJS legacy, built-in modules (node: prefix), HTTP-server eingebaut + express, REST mit express (GET/POST/PUT/DELETE-pattern), alternative frameworks tabelle (fastify/hono/koa), routing-pattern mit Router, fetch global ab node 18, error-handling res.ok, environment variables mit dotenv + niemals committen, selbstlernen mini-API kap4 nodejs_advanced (~24 → 22 slides): synchron-vs-asynchron, promise then-vs-async/await, sequenziell-vs-parallel + Promise.all, promise-methoden tabelle (all/allSettled/race/any), fs/promises lesen+schreiben, streams pipeline für große dateien, DB-übersicht SQLite/Postgres/MongoDB/Redis, better-sqlite3 prepared statements, ORM-übersicht (drizzle/prisma/knex), CRUD-pattern express+sqlite, auth-strategien tabelle, bcrypt für passwörter, JWT-pattern mit httpOnly+secure cookie, try/catch + error-klassen, globaler express-error-handler, selbstlernen REST+DB+auth kap5 testing (~23 → 23 slides): test-pyramide 70%/20%/10%, vitest setup + describe/it/expect, AAA-pattern, matchers tabelle, TDD red-green-refactor mit konkretem beispiel, supertest für API-integration, test-DB :memory: + lifecycle hooks, mocking mit vi.spyOn (sparsam), playwright E2E mit role-based-locators, E2E-vs-unit tradeoffs, coverage realistisch (80% gut), CI mit github-actions, selbstlernen tests-schreiben kap6 typescript (~30 → 19 slides): was-ist-TS + warum-tabelle, setup mit tsx + tsconfig.json + strict:true, basis-typen + any vermeiden, object-typen + interfaces + type-aliases, function-typen (Promise<T>), union + discriminated union + intersection, generics + constraints, built-in generics (Partial/Omit/Record), typ-inference (nicht über-annotieren), typen für REST-API mit express, zod runtime-validation + z.infer, any-vs-unknown-vs-never, best practices, selbstlernen API-zu-TS-migration kap7 docker (~24 → 24 slides): auf-meinem-rechner-läufts problem, container-vs-VM tabelle, docker basics (image/container/dockerfile/registry), dockerfile hallo-welt, schichten + cache-optimierung, multi-stage build, base-image-größen tabelle (alpine ~180MB vs node ~1.1GB), .dockerignore, compose.yml beispiel, compose-commands, networking (service-namen als hostnamen), volumes (named vs bind), env+secrets, github-actions docker-build, registry-übersicht, health-checks, best-practices, selbstlernen app-dockerizen kap8 best_practices (~30 → 28 slides): sinnvolle commits + conventional commits format, .gitignore template, branches+PRs workflow, README-template mit 6 sektionen, SOLID 5 prinzipien tabelle, S-single-responsibility + D-dependency-inversion mit code, 12-factor wichtigste (codebase/deps/config/processes/disposability), factor 3 config-in-env, factor 6 stateless-processes, SemVer MAJOR.MINOR.PATCH, package.json caret/tilde/exakt, code-reviews geben+nehmen + checkliste, doku-quellen tabelle (MDN/nodejs/npm/tc39/caniuse), stack-overflow gut-nutzen, AI-assistenten pro/contra (verstehen-nicht-kopieren), selbstlernen projekt-hygiene-check build geht durch alle 8 kapitel-html+pdf render-spot-check: cover-slide-dark-mode-invert, git-setup code-syntax-highlight, css-anatomie code-blocks — alle sauber kein deploy, nur build+verify
This commit is contained in:
+362
-201
@@ -8,217 +8,373 @@ footer: "Michael Czechowski – SoSe 2026"
|
||||
---
|
||||
|
||||
<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);
|
||||
}
|
||||
:root { --color-foreground: #1a1a2e; --color-highlight: #d63384; --color-dimmed: #4a4a6a; }
|
||||
section.invert { --color-foreground: #fff; }
|
||||
section { font-size: 1.4rem; }
|
||||
h1 { color: #a02060; }
|
||||
section.invert h1 { color: #fff; }
|
||||
h2 { color: #1f2937; }
|
||||
section.invert h2 { color: #f48fb1; }
|
||||
pre { background: #0f0f23; color: #f48fb1; border-radius: 8px; border-left: 3px solid #d63384; }
|
||||
pre code { background: transparent; color: inherit; }
|
||||
code { background: #1a1a2e; color: #f48fb1; padding: 0.15em 0.4em; border-radius: 4px; }
|
||||
a { color: var(--color-highlight); }
|
||||
</style>
|
||||
|
||||
<!-- _class: invert -->
|
||||
<!-- _header: '' -->
|
||||
<!-- _backgroundColor: #000 -->
|
||||
<!-- _class: lead -->
|
||||
|
||||
# Web Engineering
|
||||
|
||||
**DHBW Stuttgart** · Informatik / Wirtschaftsinformatik
|
||||
|
||||
**Sommersemester 2026** · Sitzung 2 — HTML & CSS (Frameworks)
|
||||
# Kapitel 2 — CSS Extended
|
||||
## Box-Model · Flexbox · Grid · Responsive · Animations
|
||||
|
||||
---
|
||||
|
||||
# Ressourcen zum Selbstlernen
|
||||
# Recap Kap 1
|
||||
|
||||
- **CODE CRISPIES** — [codecrispi.es](https://codecrispi.es/)
|
||||
- **Online Code-Editor** — [codepen.io](https://codepen.io/pen/)
|
||||
- **MDN** (Mozilla Developer Network) — [developer.mozilla.org/de/](https://developer.mozilla.org/de/)
|
||||
- **Flexbox-Spiel** — [flexboxfroggy.com](https://flexboxfroggy.com/)
|
||||
- **Grid-Spiel** — [cssgridgarden.com](https://cssgridgarden.com/)
|
||||
| Bereich | Was wir kennen |
|
||||
|---------|----------------|
|
||||
| Anatomie | `selector { property: value }` |
|
||||
| Selektoren | element, `.class`, `#id`, `:hover` |
|
||||
| Spezifizität | inline > id > class > element |
|
||||
| Farben | hex, rgb, hsl, oklch |
|
||||
| Einheiten | px, rem, em, %, vw, vh |
|
||||
|
||||
**Heute:** Layout + Animation in Tiefe.
|
||||
|
||||
---
|
||||
|
||||
# Inhalt
|
||||
# Box-Model — die Erinnerung
|
||||
|
||||
Aufbauend auf den Grundlagen aus Sitzung 1.
|
||||
```
|
||||
┌──────────────────┐
|
||||
│ margin │
|
||||
│ ┌────────────┐ │
|
||||
│ │ border │ │
|
||||
│ │ ┌────────┐ │ │
|
||||
│ │ │padding │ │ │
|
||||
│ │ │content │ │ │
|
||||
│ │ └────────┘ │ │
|
||||
│ └────────────┘ │
|
||||
└──────────────────┘
|
||||
```
|
||||
|
||||
1. Attribut-Selektoren
|
||||
2. Combinators (vertieft)
|
||||
3. Pseudo-Klassen — erweitert
|
||||
4. Shorthand Properties
|
||||
5. Flexbox-Shorthands
|
||||
6. Custom Properties (Variables)
|
||||
7. CSS Functions (`calc`, `clamp`, ...)
|
||||
8. Transition & Animation
|
||||
9. CSS Frameworks (Tailwind & Co.)
|
||||
`box-sizing: border-box` global setzen.
|
||||
|
||||
---
|
||||
|
||||
<!-- _class: invert -->
|
||||
<!-- _backgroundColor: #000 -->
|
||||
|
||||
# CSS: Extended
|
||||
|
||||
---
|
||||
|
||||
# CSS Selectors – Attribut-Selektoren
|
||||
# Box-Model in Code
|
||||
|
||||
```css
|
||||
/* presence */
|
||||
[disabled] { opacity: 0.5; }
|
||||
* { box-sizing: border-box; }
|
||||
|
||||
/* exact value */
|
||||
[type="email"] { border-color: blue; }
|
||||
.card {
|
||||
width: 320px; /* inkl. padding + border */
|
||||
padding: 1.5rem;
|
||||
border: 2px solid #ccc;
|
||||
border-radius: 0.75rem;
|
||||
margin: 1rem auto; /* Außen + horizontal zentriert */
|
||||
}
|
||||
```
|
||||
|
||||
/* contains word */
|
||||
[class~="btn"] { cursor: pointer; }
|
||||
Inspector im DevTools zeigt das Box-Model live an.
|
||||
|
||||
/* starts with */
|
||||
[href^="https"] { color: green; }
|
||||
---
|
||||
|
||||
/* ends with */
|
||||
[src$=".png"] { border: 1px solid #ccc; }
|
||||
<!-- _class: lead -->
|
||||
|
||||
/* contains substring */
|
||||
[class*="icon"] { padding-left: 20px; }
|
||||
# Flexbox
|
||||
## 1D-Layout (Reihe ODER Spalte)
|
||||
|
||||
---
|
||||
|
||||
# Flexbox — Basics
|
||||
|
||||
```css
|
||||
.container {
|
||||
display: flex;
|
||||
gap: 1rem; /* Abstand zwischen Items */
|
||||
flex-direction: row; /* row | column */
|
||||
justify-content: space-between; /* Haupt-Achse */
|
||||
align-items: center; /* Quer-Achse */
|
||||
flex-wrap: wrap; /* umbruchen erlaubt */
|
||||
}
|
||||
```
|
||||
|
||||
```html
|
||||
<div class="container">
|
||||
<div>1</div>
|
||||
<div>2</div>
|
||||
<div>3</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# CSS Combinators
|
||||
# Flexbox — Achsen
|
||||
|
||||
**`flex-direction: row` (default):** Haupt-Achse horizontal.
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ ◄── justify-content ──► │
|
||||
│ ▲ │
|
||||
│ │ │
|
||||
│ align-items │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
└─────────────────────────────────────┘
|
||||
```
|
||||
|
||||
`column`: Achsen drehen sich 90°.
|
||||
|
||||
---
|
||||
|
||||
# Flexbox — Item-Properties
|
||||
|
||||
```css
|
||||
/* Child (direkt) */
|
||||
div > p { margin: 0; }
|
||||
.item {
|
||||
flex: 1; /* nimm gleiche Anteile vom verfügbaren Raum */
|
||||
flex: 0 0 200px; /* fest 200px, kein wachsen, kein schrumpfen */
|
||||
flex-grow: 2; /* doppelte Anteile */
|
||||
order: -1; /* visuell zuerst, im DOM hinten */
|
||||
align-self: end; /* override align-items für DIESES Item */
|
||||
}
|
||||
```
|
||||
|
||||
/* Descendant (Nachkomme) */
|
||||
div p { margin: 0; }
|
||||
**Shorthand:** `flex: <grow> <shrink> <basis>`.
|
||||
|
||||
/* Next Sibling */
|
||||
h1 + p { font-size: 1.2em; }
|
||||
---
|
||||
|
||||
/* Subsequent Sibling */
|
||||
h1 ~ p { color: #666; }
|
||||
# Typische Flex-Patterns
|
||||
|
||||
/* Selector List */
|
||||
h1, h2, h3 { font-weight: bold; }
|
||||
```css
|
||||
/* Navigation: Logo links, Items rechts */
|
||||
.nav { display: flex; justify-content: space-between; }
|
||||
|
||||
/* Karte: Bild + Text nebeneinander */
|
||||
.card { display: flex; gap: 1rem; align-items: center; }
|
||||
|
||||
/* Button-Gruppe: alle gleich groß */
|
||||
.btn-group { display: flex; gap: 0.5rem; }
|
||||
.btn-group button { flex: 1; }
|
||||
|
||||
/* Footer: gleichmäßig verteilt */
|
||||
.footer { display: flex; justify-content: space-around; }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Pseudo Classes – Erweitert
|
||||
<!-- _class: lead -->
|
||||
|
||||
```css
|
||||
/* Form States */
|
||||
:valid { border-color: green; }
|
||||
:invalid { border-color: red; }
|
||||
:placeholder-shown { color: #999; }
|
||||
|
||||
/* Content */
|
||||
:before { content: "→ "; }
|
||||
:after { content: " [Wichtig]"; }
|
||||
:first-letter { font-size: 2em; }
|
||||
:first-line { font-weight: bold; }
|
||||
|
||||
/* NOT */
|
||||
:not(.disabled) { pointer-events: auto; }
|
||||
:not(:last-child) { border-bottom: 1px solid #ccc; }
|
||||
```
|
||||
# Grid
|
||||
## 2D-Layout (Reihe UND Spalte)
|
||||
|
||||
---
|
||||
|
||||
# Shorthand Properties
|
||||
# Grid — Basics
|
||||
|
||||
```css
|
||||
/* margin: top right bottom left */
|
||||
margin: 10px 20px 10px 20px;
|
||||
|
||||
/* centering */
|
||||
margin: 0 auto;
|
||||
|
||||
/* padding same */
|
||||
padding: 20px;
|
||||
|
||||
/* border: width style color */
|
||||
border: 1px solid #333;
|
||||
|
||||
/* background: color image position/size repeat */
|
||||
background: #fff url(logo.png) 0 0 no-repeat;
|
||||
|
||||
/* font: style variant weight size/line-height family */
|
||||
font: italic normal bold 16px/1.5 Arial, sans-serif;
|
||||
.container {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 2fr 1fr; /* 3 Spalten, Verhältnis 1:2:1 */
|
||||
grid-template-rows: auto 1fr auto; /* Header, Body, Footer */
|
||||
gap: 1rem;
|
||||
}
|
||||
```
|
||||
|
||||
`fr` = Fraction Unit — verbleibender Raum aufgeteilt.
|
||||
|
||||
---
|
||||
|
||||
# Flexbox Shorthands
|
||||
# Grid — Areas (named layout)
|
||||
|
||||
```css
|
||||
/* flex: grow shrink basis */
|
||||
flex: 1 0 auto;
|
||||
.layout {
|
||||
display: grid;
|
||||
grid-template-areas:
|
||||
"header header"
|
||||
"nav main"
|
||||
"footer footer";
|
||||
grid-template-columns: 200px 1fr;
|
||||
}
|
||||
|
||||
/* place-items: align-items justify-items */
|
||||
place-items: center stretch;
|
||||
|
||||
/* place-content: align-content justify-content */
|
||||
place-content: space-between center;
|
||||
|
||||
/* gap: row-gap column-gap */
|
||||
gap: 20px 40px;
|
||||
.layout header { grid-area: header; }
|
||||
.layout nav { grid-area: nav; }
|
||||
.layout main { grid-area: main; }
|
||||
.layout footer { grid-area: footer; }
|
||||
```
|
||||
|
||||
Lesbarer als Spalten-/Zeilen-Nummern.
|
||||
|
||||
---
|
||||
|
||||
# CSS Custom Properties (Variables)
|
||||
# Grid — Auto-Layout
|
||||
|
||||
```css
|
||||
/* So viele Spalten wie reinpassen, jede min. 200px */
|
||||
.gallery {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||
gap: 1rem;
|
||||
}
|
||||
```
|
||||
|
||||
Mobile: 1 Spalte. Tablet: 2-3. Desktop: 4-5. **Ohne Media Queries.**
|
||||
|
||||
---
|
||||
|
||||
# Flexbox vs. Grid
|
||||
|
||||
| | Flexbox | Grid |
|
||||
|--|---------|------|
|
||||
| Dimension | 1D | 2D |
|
||||
| Use-Case | Navigation, Karten-Reihe, Button-Gruppe | Seiten-Layout, komplexes Raster |
|
||||
| Item-Größe | flexibel | meist fest |
|
||||
| Direction | row/column | rows + columns |
|
||||
|
||||
**Beide in einem Layout möglich:** Grid für Seite, Flexbox in Komponenten.
|
||||
|
||||
---
|
||||
|
||||
<!-- _class: lead -->
|
||||
|
||||
# Responsive Design
|
||||
|
||||
---
|
||||
|
||||
# Mobile-First mit Media Queries
|
||||
|
||||
```css
|
||||
/* Default: Mobile */
|
||||
.sidebar { display: none; }
|
||||
.content { padding: 1rem; }
|
||||
|
||||
/* Tablet aufwärts */
|
||||
@media (min-width: 768px) {
|
||||
.sidebar { display: block; width: 240px; }
|
||||
.content { padding: 2rem; }
|
||||
}
|
||||
|
||||
/* Desktop */
|
||||
@media (min-width: 1280px) {
|
||||
.sidebar { width: 320px; }
|
||||
}
|
||||
```
|
||||
|
||||
**Mobile-First**: kleinste Größe als Default, dann größer.
|
||||
|
||||
---
|
||||
|
||||
# Viewport-Meta
|
||||
|
||||
```html
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
```
|
||||
|
||||
**Pflicht** im `<head>`. Ohne dieses Meta zoomt iPhone & Android alles auf 980 px Breite.
|
||||
|
||||
---
|
||||
|
||||
# Fluid Sizing — ohne Media Queries
|
||||
|
||||
```css
|
||||
/* Font: skaliert zwischen 14px und 22px */
|
||||
h1 { font-size: clamp(1.4rem, 2.5vw + 1rem, 2.5rem); }
|
||||
|
||||
/* Padding: skaliert mit Viewport */
|
||||
.card { padding: clamp(1rem, 3vw, 3rem); }
|
||||
|
||||
/* Breite: nie mehr als 70 Zeichen für Lesetext */
|
||||
.prose { max-width: 70ch; margin: auto; }
|
||||
```
|
||||
|
||||
`clamp(min, ideal, max)` ist modernes Allzweck-Werkzeug.
|
||||
|
||||
---
|
||||
|
||||
<!-- _class: lead -->
|
||||
|
||||
# Animationen
|
||||
|
||||
---
|
||||
|
||||
# Transitions — sanfter Wechsel
|
||||
|
||||
```css
|
||||
button {
|
||||
background: hotpink;
|
||||
transition: background 0.2s ease, transform 0.15s;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background: deeppink;
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
```
|
||||
|
||||
**Was animiert performant:** `transform`, `opacity`. **Was nicht:** `width`, `height`, `top/left`.
|
||||
|
||||
---
|
||||
|
||||
# Keyframe-Animationen
|
||||
|
||||
```css
|
||||
@keyframes pulse {
|
||||
0% { transform: scale(1); opacity: 1; }
|
||||
50% { transform: scale(1.1); opacity: 0.7; }
|
||||
100% { transform: scale(1); opacity: 1; }
|
||||
}
|
||||
|
||||
.notification {
|
||||
animation: pulse 1.5s ease infinite;
|
||||
}
|
||||
```
|
||||
|
||||
`animation: <name> <duration> <timing> <iteration>`.
|
||||
|
||||
---
|
||||
|
||||
# Reduced Motion — Pflicht
|
||||
|
||||
Nicht alle wollen Animationen. (Vestibuläre Probleme, ADHS, Migräne.)
|
||||
|
||||
```css
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
*, *::before, *::after {
|
||||
animation-duration: 0.01ms !important;
|
||||
transition-duration: 0.01ms !important;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Standard-Bestandteil** jeder Seite — ein User-Setting respektieren.
|
||||
|
||||
---
|
||||
|
||||
<!-- _class: lead -->
|
||||
|
||||
# CSS-Variablen + Modern
|
||||
|
||||
---
|
||||
|
||||
# Custom Properties (CSS Variables)
|
||||
|
||||
```css
|
||||
:root {
|
||||
--primary-color: #d63384;
|
||||
--spacing: 20px;
|
||||
--radius: 8px;
|
||||
--primary: hotpink;
|
||||
--gap: 1rem;
|
||||
--radius: 0.75rem;
|
||||
}
|
||||
|
||||
.button {
|
||||
background: var(--primary-color);
|
||||
padding: var(--spacing);
|
||||
button {
|
||||
background: var(--primary);
|
||||
padding: var(--gap);
|
||||
border-radius: var(--radius);
|
||||
}
|
||||
|
||||
/* Dark Mode: nur Variablen umsetzen */
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root { --primary: deeppink; }
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
@@ -226,67 +382,72 @@ gap: 20px 40px;
|
||||
# CSS Functions
|
||||
|
||||
```css
|
||||
/* calc */
|
||||
width: calc(100% - 40px);
|
||||
|
||||
/* min/max/clamp */
|
||||
width: min(100%, 600px);
|
||||
font-size: clamp(14px, 2vw, 20px);
|
||||
|
||||
/* var with fallback */
|
||||
color: var(--text-color, #333);
|
||||
|
||||
/* rgb/rgba/hsl/hsla */
|
||||
color: hsl(200, 100%, 50%);
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Transition & Animation
|
||||
|
||||
```css
|
||||
/* transition: property duration timing-function */
|
||||
transition: all 0.3s ease-in-out;
|
||||
transition: background 0.2s, transform 0.1s;
|
||||
|
||||
/* animation */
|
||||
@keyframes fadeIn {
|
||||
from { opacity: 0; }
|
||||
to { opacity: 1; }
|
||||
}
|
||||
|
||||
.fade-in {
|
||||
animation: fadeIn 0.5s ease-out;
|
||||
.box {
|
||||
width: calc(100% - 2rem); /* Mathe */
|
||||
font-size: clamp(1rem, 2vw, 2rem); /* min, ideal, max */
|
||||
background: linear-gradient(45deg, hotpink, deeppink);
|
||||
color: oklch(0.7 0.2 30); /* moderner Farbraum */
|
||||
filter: blur(2px) brightness(1.2); /* Bildeffekte */
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# CSS Frameworks
|
||||
# CSS-Frameworks
|
||||
|
||||
| Framework | Stil |
|
||||
|-----------|------|
|
||||
| **Bootstrap** | Komponenten + Grid, opinionated |
|
||||
| **Tailwind CSS** | Utility-First, atomar |
|
||||
| **Bulma** | klassisch, ohne JS |
|
||||
| **shadcn/ui** | kopierbare Komponenten (Tailwind-basiert) |
|
||||
| **Flowbite** | Tailwind-Komponentenbib. |
|
||||
|
||||
---
|
||||
|
||||
# Tailwind CSS – Beispiel
|
||||
| **Tailwind CSS** | Utility-Klassen direkt im HTML |
|
||||
| **Bootstrap** | Komponenten-Bibliothek (klassisch) |
|
||||
| **Pico** | klassen-frei, semantisches HTML reicht |
|
||||
| **Open Props** | CSS-Variablen-Set |
|
||||
|
||||
```html
|
||||
<button class="bg-blue-600 hover:bg-blue-700
|
||||
text-white font-semibold
|
||||
px-4 py-2 rounded-lg
|
||||
transition shadow-sm">
|
||||
Klick mich
|
||||
<!-- Tailwind: alle Styles als Klassen -->
|
||||
<button class="bg-pink-500 hover:bg-pink-600 px-4 py-2 rounded-md">
|
||||
Klick
|
||||
</button>
|
||||
```
|
||||
|
||||
- Keine eigenen CSS-Klassen mehr
|
||||
- JIT-Compiler erzeugt nur genutzte Klassen
|
||||
- Design-System via `tailwind.config.js`
|
||||
---
|
||||
|
||||
# Tailwind — Argumente dafür/dagegen
|
||||
|
||||
**Pro:**
|
||||
- Schnell, weniger Context-Switch (HTML + CSS in einer Datei)
|
||||
- Konsistent (Design-System eingebaut)
|
||||
- Tree-Shaking → kleines Bundle
|
||||
|
||||
**Contra:**
|
||||
- HTML voller Klassen — schwerer zu lesen
|
||||
- Lernkurve eigene
|
||||
- Versions-Lock-in mit Setup
|
||||
|
||||
**Faustregel:** für neue Projekte ausprobieren, vorhandene Projekte nicht zwanghaft migrieren.
|
||||
|
||||
---
|
||||
|
||||
<!-- _class: aufgabe -->
|
||||
|
||||
# Selbstlernen — Layout-Übung
|
||||
|
||||
1. **Flexbox-Spiel:** [flexboxfroggy.com](https://flexboxfroggy.com) — alle 24 Level durch.
|
||||
2. **Grid-Spiel:** [cssgridgarden.com](https://cssgridgarden.com) — 28 Level durch.
|
||||
3. **Eigene Karten-Galerie:** `repeat(auto-fit, minmax(...))` Pattern anwenden.
|
||||
|
||||
**Bonus:** Dark-Mode mit CSS-Variablen + `prefers-color-scheme`.
|
||||
|
||||
---
|
||||
|
||||
# Zusammenfassung
|
||||
|
||||
**Heute gelernt:**
|
||||
- Box-Model + `box-sizing: border-box` global
|
||||
- **Flexbox** für 1D-Layouts (Navigation, Karten-Reihen)
|
||||
- **Grid** für 2D-Layouts (Seiten-Layout, Galerien)
|
||||
- Mobile-First Media Queries + `clamp()` für fluid
|
||||
- Transitions + Keyframes — `prefers-reduced-motion` respektieren
|
||||
- CSS-Variablen für Theming
|
||||
- Tailwind & Co. als moderner Framework-Stil
|
||||
|
||||
**Nächste Stunde:** Node.js — JavaScript außerhalb des Browsers.
|
||||
|
||||
Reference in New Issue
Block a user