Einheit 03 — Flexbox, Grid, Tabellen, Formulare & Projektideen-Pitches
Webentwicklung & Agentic Coding | Sommersemester 2026 | Universität Graz
Willkommen zur dritten Einheit. Heute vertiefen wir HTML und CSS mit Layout-Techniken und bereiten die Projektideen-Pitches vor.
content → padding → border → marginKurzer Rueckblick auf Einheit 02: HTML-Struktur und CSS-Grundlagen.
Flexbox ist ein eindimensionales Layout-System. Es ordnet Elemente entlang einer Hauptachse (main axis) an und erlaubt die Ausrichtung entlang der Querachse (cross axis).
Anwendungsfälle: Navigationsleisten, Button-Gruppen, zentrierte Inhalte, gleichmäßig verteilte Elemente.
Flexbox visualisieren: Ein Flex-Container ist wie eine Zeile, in der Karten nebeneinander liegen. Die Hauptachse bestimmt die Richtung, die Querachse die Ausrichtung senkrecht dazu.
/* Flex-Container aktivieren */
display: flex;
/* Hauptachse: Verteilung */
justify-content: flex-start;
justify-content: center;
justify-content: space-between;
justify-content: space-around;
/* Querachse: Ausrichtung */
align-items: stretch;
align-items: center;
align-items: flex-start;
align-items: flex-end;
/* Umbruch erlauben */
flex-wrap: wrap;
/* Abstand zwischen Items */
gap: 1rem;
/* Wachsen: Platz einnehmen */
flex-grow: 1;
/* Schrumpfen: Platz abgeben */
flex-shrink: 0;
/* Basisgroesse */
flex-basis: 200px;
/* Kurzschreibweise */
flex: 1 0 200px;
/* Einzelnes Item ausrichten */
align-self: center;
/* Reihenfolge aendern */
order: 2;
Die wichtigsten Flexbox-Eigenschaften auf einen Blick. Container-Eigenschaften steuern das Layout aller Kinder, Item-Eigenschaften beeinflussen einzelne Elemente.
<nav class="hauptnav">
<a href="/" class="logo">DH-Archiv</a>
<ul class="nav-links">
<li><a href="/sammlung">Sammlung</a></li>
<li><a href="/briefe">Briefe</a></li>
<li><a href="/suche">Suche</a></li>
<li><a href="/ueber">Über uns</a></li>
</ul>
</nav>
.hauptnav {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem 2rem;
background: #1a5276;
color: white;
}
.nav-links {
display: flex;
gap: 1.5rem;
list-style: none;
}
.nav-links a {
color: white;
text-decoration: none;
}
.nav-links a:hover {
text-decoration: underline;
}
Klassisches Beispiel: Logo links, Links rechts. Mit space-between verteilt Flexbox den Platz automatisch.
CSS Grid ist ein zweidimensionales Layout-System. Es arbeitet mit Zeilen (rows) und Spalten (columns) gleichzeitig.
Grid eignet sich hervorragend für DH-Projekte: Sammlungs-Galerien, Metadaten-Übersichten, Portfolio-Layouts.
Grid vs. Flexbox ist keine Entweder-oder-Entscheidung. In der Praxis kombiniert man beides: Grid fuer das Gesamtlayout, Flexbox fuer Komponenten darin.
/* Grid-Container aktivieren */
display: grid;
/* Spalten definieren: 3 gleich breite Spalten */
grid-template-columns: 1fr 1fr 1fr;
/* Kurzform mit repeat() */
grid-template-columns: repeat(3, 1fr);
/* Responsive: automatisch so viele wie reinpassen */
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
/* Zeilen definieren */
grid-template-rows: auto 1fr auto;
/* Abstand zwischen Zellen */
gap: 1.5rem;
/* Abstand getrennt fuer Zeilen und Spalten */
row-gap: 2rem;
column-gap: 1rem;
/* Items ueber mehrere Spalten/Zeilen */
grid-column: span 2; /* 2 Spalten breit */
grid-row: span 3; /* 3 Zeilen hoch */
Die fr-Einheit (fraction) verteilt den verfuegbaren Platz anteilig. auto-fill und minmax() machen das Grid responsiv ohne Media Queries.
<div class="sammlung-grid">
<article class="objekt-karte">
<h3>Richtbeil (1798)</h3>
<p>Strafvollzug im
18. Jahrhundert</p>
</article>
<article class="objekt-karte">
<h3>Schandmaske (1650)</h3>
<p>Ehrenstrafe fuer
oeffentliche Vergehen</p>
</article>
<article class="objekt-karte">
<h3>Folterzange (1720)</h3>
<p>Instrument der
peinlichen Befragung</p>
</article>
</div>
.sammlung-grid {
display: grid;
grid-template-columns:
repeat(3, 1fr);
gap: 1.5rem;
padding: 1rem;
}
.objekt-karte {
background: #f9f9f4;
border: 1px solid #ddd;
border-radius: 8px;
padding: 1.5rem;
}
.objekt-karte h3 {
font-size: 1.1rem;
margin-bottom: 0.5rem;
color: #1a5276;
}
/* Responsive: ab 768px
nur noch 1 Spalte */
@media (max-width: 768px) {
.sammlung-grid {
grid-template-columns: 1fr;
}
}
3-Spalten-Grid fuer Sammlungsobjekte. Die Karten passen sich responsiv an. Inhalt stammt aus dem Kriminalmuseum.
/* Bereiche benennen */
.page-layout {
display: grid;
grid-template-columns: 250px 1fr;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
min-height: 100vh;
}
/* Elemente den Bereichen zuweisen */
.page-header { grid-area: header; }
.page-sidebar { grid-area: sidebar; }
.page-main { grid-area: main; }
.page-footer { grid-area: footer; }
/* Responsive: Sidebar verschwindet */
@media (max-width: 768px) {
.page-layout {
grid-template-columns: 1fr;
grid-template-areas:
"header"
"main"
"footer";
}
.page-sidebar { display: none; }
}
Grid Areas sind besonders nuetzlich fuer komplexe Seitenlayouts. Die ASCII-artige Syntax macht den Code selbstdokumentierend — man sieht das Layout direkt im CSS.
Navigation, Button-Gruppen, Karteninhalt, Footer-Elemente
Seitenlayouts, Galerien, Dashboards, Formulare
Es ist keine Entweder-oder-Entscheidung. Die beste Praxis ist, beides zu kombinieren. Grid fuer das Makro-Layout, Flexbox fuer Mikro-Komponenten.
<table>
<caption>Korrespondenz-Metadaten</caption>
<thead>
<tr>
<th scope="col">Datum</th>
<th scope="col">Absender</th>
<th scope="col">Empfänger</th>
<th scope="col">Ort</th>
<th scope="col">Thema</th>
</tr>
</thead>
<tbody>
<tr>
<td>12.03.1887</td>
<td>Hugo Schuchardt</td>
<td>Wilhelm Meyer-Lübke</td>
<td>Graz</td>
<td>Romanische Etymologie</td>
</tr>
<!-- weitere Zeilen ... -->
</tbody>
</table>
<thead> und <tbody> für Semantik.
scope="col" verbessert die Barrierefreiheit.
<caption> beschreibt den Tabelleninhalt.
Tabellen nur fuer tabellarische Daten verwenden, nie fuer Layout! Die Beispieldaten stammen aus der Hugo-Schuchardt-Korrespondenz.
/* Grundlayout: Raender zusammenfassen */
table {
width: 100%;
border-collapse: collapse;
font-size: 0.9rem;
}
th, td {
padding: 0.75rem 1rem;
text-align: left;
border-bottom: 1px solid #ddd;
}
/* Tabellenkopf hervorheben */
th {
background: #1a5276;
color: white;
font-weight: 600;
}
/* Gestreifte Zeilen (Zebra-Muster) */
tbody tr:nth-child(even) {
background: #f5f5f0;
}
/* Hover-Effekt fuer bessere Lesbarkeit */
tbody tr:hover {
background: #eaf2f8;
}
/* Beschriftung */
caption {
caption-side: top;
font-weight: bold;
margin-bottom: 0.5rem;
text-align: left;
color: #666;
}
Drei Techniken fuer lesbare Tabellen: border-collapse, Zebra-Streifen, Hover-Effekt.
Tabellen sind auf kleinen Bildschirmen problematisch. Zwei Lösungsansätze:
/* Container mit Scroll */
.table-wrapper {
overflow-x: auto;
}
/* Minimale Spaltenbreite */
.table-wrapper table {
min-width: 600px;
}
Einfach, behält Tabellen-Layout bei.
@media (max-width: 640px) {
table, thead, tbody,
th, td, tr {
display: block;
}
thead { display: none; }
td {
padding-left: 50%;
position: relative;
}
td::before {
content: attr(data-label);
position: absolute;
left: 0.5rem;
font-weight: bold;
}
}
Aufwendiger, aber mobilfreundlich.
Die einfachste Loesung (overflow-x: auto) ist fuer die meisten DH-Projekte ausreichend. Die Karten-Variante erfordert data-label-Attribute im HTML.
Korrespondenz-Daten der Hugo-Schuchardt-Sammlung als gestylte Tabelle:
<table class="metadaten-tabelle">
<caption>Briefe Hugo Schuchardt (Auswahl)</caption>
<thead>
<tr>
<th scope="col">Nr.</th>
<th scope="col">Datum</th>
<th scope="col">Absender</th>
<th scope="col">Empfänger</th>
<th scope="col">Thema</th>
</tr>
</thead>
<tbody>
<tr>
<td>001</td>
<td>15.01.1882</td>
<td>Hugo Schuchardt</td>
<td>Graziadio Ascoli</td>
<td>Kreolische Sprachen</td>
</tr>
<tr>
<td>002</td>
<td>03.05.1885</td>
<td>Gustav Meyer</td>
<td>Hugo Schuchardt</td>
<td>Albanische Grammatik</td>
</tr>
<tr>
<td>003</td>
<td>22.11.1890</td>
<td>Hugo Schuchardt</td>
<td>Jan Baudouin de Courtenay</td>
<td>Sprachkontakt</td>
</tr>
</tbody>
</table>
Reale Daten aus der Schuchardt-Korrespondenz machen die Uebung relevant fuer DH-Studierende.
<form action="/suche" method="GET">
<fieldset>
<legend>Manuskript-Suche</legend>
<label for="titel">Titel:</label>
<input type="text" id="titel" name="titel"
placeholder="z.B. Kreolische Studien">
<label for="autor">Autor:</label>
<input type="text" id="autor" name="autor">
<label for="datum">Datum (von):</label>
<input type="date" id="datum" name="datum">
<label for="sprache">Sprache:</label>
<select id="sprache" name="sprache">
<option value="">-- Bitte wählen --</option>
<option value="de">Deutsch</option>
<option value="fr">Französisch</option>
<option value="la">Latein</option>
</select>
<label for="notizen">Notizen:</label>
<textarea id="notizen" name="notizen" rows="3"></textarea>
<button type="submit">Suchen</button>
</fieldset>
</form>
Alle wichtigen Formularelemente: text, date, select, textarea, button. Labels und fieldset fuer Barrierefreiheit.
HTML5 bietet eingebaute Validierung — ganz ohne JavaScript:
<!-- Pflichtfeld -->
<input type="text" name="titel" required>
<!-- E-Mail-Format wird automatisch geprueft -->
<input type="email" name="email" required>
<!-- Zahlenwert mit Grenzen -->
<input type="number" name="jahr" min="1400" max="2026">
<!-- Muster (RegEx): Signatur-Format -->
<input type="text" name="signatur"
pattern="[A-Z]{2}-[0-9]{4}"
title="Format: XX-0000 (z.B. HS-0312)">
<!-- Textlaenge begrenzen -->
<input type="text" name="schlagwort"
minlength="2" maxlength="50">
HTML-Validierung ist die erste Verteidigungslinie. Serverseitige Validierung ist trotzdem immer noetig, aber fuer unsere statischen Seiten reicht HTML5.
/* Formular mit Grid layouten */
form fieldset {
display: grid;
grid-template-columns: auto 1fr;
gap: 0.75rem 1rem;
align-items: center;
border: 1px solid #ddd;
border-radius: 8px;
padding: 1.5rem;
}
/* Labels rechtsbuendig */
label {
text-align: right;
font-weight: 600;
color: #333;
}
/* Einheitliche Eingabefelder */
input, select, textarea {
padding: 0.5rem 0.75rem;
border: 1px solid #ccc;
border-radius: 4px;
font-size: 1rem;
font-family: inherit;
}
input:focus, select:focus, textarea:focus {
outline: 2px solid #1a5276;
border-color: #1a5276;
}
/* Button ueber volle Breite */
button[type="submit"] {
grid-column: 1 / -1;
padding: 0.75rem;
background: #1a5276;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 1rem;
}
CSS Grid eignet sich hervorragend fuer Formularlayouts: Label links, Input rechts. Focus-Styles verbessern die Barrierefreiheit.
Gute Formulare sind für alle nutzbar — auch mit Screenreader oder Tastatur:
<label for="..."> — Jedes Eingabefeld braucht ein Label.
Das for-Attribut muss zur id des Inputs passen.<fieldset> + <legend> — Gruppiert zusammengehörige
Felder mit einer Überschrift.aria-describedby — Verbindet Hilfetext mit dem Eingabefeld.:focus-Styles sichtbar machen.Barrierefreiheit ist keine optionale Zugabe, sondern eine Grundanforderung. Im DH-Bereich ist das besonders relevant, weil viele Projekte oeffentlich finanziert sind.
Requirement Engineering (RE) bedeutet: Anforderungen so präzise formulieren, dass ein LLM (oder ein Entwicklerteam) genau versteht, was gebaut werden soll.
Je präziser die Beschreibung, desto besser das Ergebnis beim Agentic Coding.
RE ist eine Kernkompetenz fuer Agentic Coding. Studierende lernen, dass gute Ergebnisse von guten Anforderungen abhaengen.
Ein effektiver Workflow für Agentic Coding:
Wichtig: Nicht alles auf einmal prompten, sondern schrittweise aufbauen und jedes Ergebnis im Browser pruefen.
Ein typisches DH-Portfolio besteht aus mehreren Seiten:
Die Portfolio-Struktur wird im Assignment 1 umgesetzt. Studierende sollen bereits jetzt ueberlegen, welche Seiten ihr Portfolio haben soll.
Ihr Pitch sollte folgende Punkte abdecken:
Es geht nicht um Perfektion — es geht darum, eine Idee zu formulieren und Feedback von der Gruppe zu bekommen.
Pitches sind informell. Es geht darum, die Projektidee zu schaerfen, nicht um eine fertige Praesentation.
Dieses Beispiel zeigt die Struktur eines guten Pitches: Klar, konkret, mit DH-Bezug.
<thead>, <tbody>, <th>required, pattern, min/max)Zusammenfassung aller Themen der heutigen Einheit.
Fragen? Schreiben Sie im Forum oder kommen Sie in die Sprechstunde.
Hinweis auf Assignment 1 und die naechste Einheit.