Zum Inhalt
wannacode

Text, Links, Bilder, Tabellen

Kurz gesagt: Der Inhalt einer HTML-Seite besteht aus Überschriften h1–h6, Absätzen, Listen, Links mit href, Bildern mit alt und Datentabellen mit caption, th und scope.

Problem

„Milch“ führt ins Leere

Ein Kunde schreibt, dass auf der Seite des Brots der Link „Milch“ zu „Seite nicht gefunden“ führt. Auf der Startseite funktioniert dasselbe Menü. Die Seite liegt unter https://shop.example/bread/white/dobrudzha.

HTML, CSS, JS
index.html

Klick auf „Milch“. Die Sandbox ist eine einzige Seite und öffnet keine Links, aber die Konsole sagt, was in href steht: milk. Die anderen Links beginnen mit /, dieser nicht. Ohne / geht der Browser nicht zu /milk. Er baut die Adresse aus der Adresse der Seite, auf der du gerade bist, und erhält eine andere.

Die Idee

Vollständige und relative Adressen

Ein Link ist <a> mit dem Attribut href: wohin er führt. Die Adresse in href (eine URL) ist entweder vollständig oder relativ.

Eine vollständige Adresse hat alles: das Schema (https://), den Host (shop.example) und den Pfad (/bread/white/dobrudzha). Der Pfad besteht aus Ordnern, die durch / getrennt sind, und der letzte Teil ist die Seite.

Eine relative Adresse ist unvollständig, und der Browser ergänzt sie aus der Adresse der Seite, auf der der Link steht. Der Anfang entscheidet, wie:

  • milk (davor nichts): ab dem Ordner der Seite.
  • ../milk: einen Ordner nach oben.
  • /milk: ab der Wurzel der Website, egal auf welcher Seite.
  • #price: eine Stelle in derselben Seite, das Element mit id="price".

Darum benutzt das Menü, das auf jeder Seite steht, Adressen ab der Wurzel: /milk führt von überall zum selben Ziel. Eine vollständige Adresse schreibst du nur für eine andere Website.

Sieh es dir an

Sieh zu, wie die Adresse gebaut wird

Fünf Links auf derselben Seite. Schau, welche Teile der Adresse oben der Browser behält und was er hinzufügt.

<!-- die Adresse der Seite: https://shop.example/bread/white/dobrudzha -->
<a href="milk">Milch</a>
<a href="../milk">Milch</a>
<a href="/milk">Milch</a>
<a href="#price">Der Preis</a>
<a href="https://recipes.example/bread">Rezepte</a>
Schritt für Schritt, in Worten
  1. Die Seite liegt unter https://shop.example/bread/white/dobrudzha. Der Browser zerlegt die Adresse in Teile: das Schema, den Host und den Pfad. Der Pfad besteht aus Ordnern, und der letzte Teil ist die Seite selbst.
  2. href="milk" hat nichts davor. Der Browser behält den Ordner der Seite, /bread/white/, und ersetzt nur den letzten Teil. Er erhält /bread/white/milk: eine Seite, die es nicht gibt.
  3. ../ bedeutet einen Ordner nach oben. Aus /bread/white/ geht der Browser hinauf nach /bread/ und hängt milk an. Es ist immer noch nicht /milk.
  4. Ein Schrägstrich davor bedeutet: von der Wurzel der Website. Der Browser behält nur das Schema und den Host. Diese Adresse funktioniert von jeder Seite des Shops aus.
  5. # ist eine Stelle in derselben Seite. Der Browser behält die ganze Adresse und hängt #price an. Die Seite wird nicht neu geladen, sondern zum Element mit id="price" gescrollt.
  6. Eine Adresse mit Schema ist vollständig. Der Browser nimmt nichts von der Seite. So verlinkst du auf eine andere Website.
  7. Der Anfang von href entscheidet: nichts oder ../ zählt ab dem Ordner, / ab der Wurzel, # bleibt in der Seite, https:// ist eine vollständige Adresse.

Der Browser fragt den Server nicht, ob die Adresse existiert. Er baut die Adresse nach den Regeln und geht dorthin. Darum fällt ein Fehler in href nicht im Code auf, sondern erst, wenn jemand auf den Link klickt. Im Browser siehst du die gebaute Adresse, wenn du die Maus über einen Link hältst: unten links im Fenster.

Probier es aus

Repariere die Links

Repariere die Links: „Milch“ und „Warenkorb“ müssen von jeder Seite des Shops aus funktionieren (eine Adresse ab der Wurzel: /milk und /cart). „Zum Preis“ muss zum Absatz mit dem Preis springen. „Rezepte mit diesem Brot“ führt zu einer anderen Website: Lass ihn in einem neuen Tab öffnen, ohne dass diese Website Zugriff auf unsere Seite bekommt.

HTML, CSS, JS

Probier es aus

Ergänze

Der Link soll zum Preis auf derselben Seite springen. Was gehört in href?

<a href="">Zum Preis</a>
…
<p id="price">Preis: 1,80 €</p>

Die Idee

Text: Gliederung, Absätze, Listen

Die Überschriften <h1> … <h6> sind keine sechs Schriftgrößen. Sie sind die Gliederung der Seite, wie das Inhaltsverzeichnis eines Buchs. <h1> ist der Titel der Seite, <h2> sind ihre Abschnitte, <h3> sind Teile eines Abschnitts. Ebenen werden nicht übersprungen: Nach <h2> kommt <h3>, nicht <h5>. Ein Screenreader zeigt diese Gliederung als Liste, und man springt von Abschnitt zu Abschnitt. Die Größe änderst du mit CSS, ohne die Gliederung zu berühren.

Der Rest:

  • <p> ist ein Absatz. <br> ist ein Zeilenumbruch innerhalb eines Absatzes (eine Adresse, ein Gedicht), kein Weg, Listen zu bauen.
  • <ul> ist eine Liste ohne Reihenfolge (Zutaten), <ol> hat eine Reihenfolge (Schritte). Jeder Eintrag ist <li>.
  • <dl> ist eine Liste von Paaren aus „Name und Wert“: <dt> ist der Name (Gewicht), <dd> ist der Wert (650 g).
  • <strong> ist wichtig („Enthält Gluten.“), und <em> ist eine Betonung, die die Bedeutung ändert („in einem Stoffbeutel, nicht in Plastik“). Wenn du nur fett aussehen willst, ohne Bedeutung, ist das CSS.
HTML, CSS, JS
index.html

Probier es aus

Mach eine Gliederung

Ein Kollege hat die Überschriften nach Größe gewählt: Der Name des Brots ist ein <h4> und das Angebot ein <h1>. Mach die Gliederung: Der Produktname ist der Titel der Seite, „Zutaten“ und „So bewahrst du es auf“ sind die Abschnitte. Das Angebot ist keine Überschrift: Mach es zu wichtigem Text in einem Absatz. Die Zutaten sind eine Liste.

HTML, CSS, JS
index.html

Die Idee

Bilder

<img src="img/bread.svg" alt="Ein rundes Weißbrot mit knuspriger Kruste" width="240" height="240">
  • src ist die Adresse des Bilds. Sie wird wie href gebaut.
  • alt ist der Text anstelle des Bilds. Ein Screenreader liest ihn vor, eine Suchmaschine indexiert ihn, und wenn das Bild nicht lädt, zeigt der Browser ihn an seiner Stelle. Schreib, was das Bild zeigt und warum es da ist.
  • Ein Bild, das nur Dekoration ist oder den Text daneben wiederholt, bekommt alt="". Dann überspringt es der Screenreader. Gar kein alt ist ein Fehler: Der Screenreader weiß nicht, dass es Dekoration ist.
  • Ein Bild, das der einzige Inhalt eines Links ist, gibt dem Link seinen Namen. Das alt ist das Ziel des Links: „Der Shop“, nicht „Logo“.
  • width und height sind die Größe in Pixeln. Solange das Bild unterwegs ist, kennt der Browser seine Größe nicht und gibt ihm 0 Pixel Höhe. Wenn es ankommt, springt der Text darunter nach unten. Mit width und height hält der Browser den Platz im Voraus frei, auch wenn CSS es kleiner macht.

Probier es aus

Füge alt und Größen hinzu

Das Logo ist das Einzige im Link zur Startseite: Der Link muss „Der Shop“ heißen. Das Foto des Brots zeigt etwas: Beschreib es in alt. Das Geschenk-Symbol wiederholt den Text daneben. Das Foto ist 240 × 240 Pixel groß: Sag es dem Browser.

HTML, CSS, JS
index.html

Ein Screenreader sagt bei einem Link nur „Link“. In welcher Zeile steckt der Fehler?

Die Idee

Datentabellen

Eine Tabelle ist für Daten in Zeilen und Spalten: Preise, Bestellungen, ein Fahrplan. Ein Screenreader liest sie als Tabelle vor: „Zeile 3, Spalte Preis, 7,90 €“. Darum ist sie nur für Daten da und nicht dafür, eine Seite in Spalten anzuordnen. Das macht CSS.

<table>
<caption>Preise heute</caption>
<thead>
<tr><th scope="col">Produkt</th><th scope="col">Preis</th></tr>
</thead>
<tbody>
<tr><th scope="row">Weißkäse</th><td>7,90 €</td></tr>
</tbody>
</table>
  • <caption> ist der Name der Tabelle. Sie steht in der Tabelle, nicht als Überschrift darüber.
  • <tr> ist eine Zeile. <td> ist eine Datenzelle, und <th> ist eine Kopfzelle.
  • scope="col" sagt, dass die Kopfzelle für die Spalte darunter gilt, und scope="row" für die Zeile rechts davon.
  • <thead> enthält die Kopfzeilen, <tbody> die Daten, <tfoot> die Summe unten.

Probier es aus

Die Preisliste

Die Preisliste besteht aus <td>-Zellen und fettem Text. Mach daraus eine Datentabelle: Der Name „Preise heute“ gehört zur Tabelle, die Kopfzeile steht in <thead>, und die Produkte stehen in <tbody>. Die Spaltenköpfe und die Produktnamen sind Kopfzellen; sag mit scope, wofür jede gilt.

HTML, CSS, JS
index.html
Genauer, für Neugierige

Mehr über Adressen. ./milk ist dasselbe wie milk. ?page=2 behält den Pfad und ändert nur die Abfrage: /bread/white/dobrudzha?page=2. Eine Adresse, die mit // beginnt, behält nur das Schema: //cdn.example/x.js ist https://cdn.example/x.js. ../ über der Wurzel führt nicht höher: ../../../milk ist von unserer Seite aus /milk. In JavaScript ist dieses Bauen new URL('../milk', 'https://shop.example/bread/white/dobrudzha').

target="_blank" und window.opener. Chromium gibt einem neuen Tab von target="_blank" schon window.opener === null, genau wie bei rel="noopener", und rel="opener" bringt die Verbindung zurück. Wir schreiben rel="noopener", damit es auch in Browsern klar ist, die es nicht von selbst tun.

Bilder für verschiedene Bildschirme. srcset gibt mehrere Größen eines Bilds an, und der Browser wählt eine für den Bildschirm. loading="lazy" lädt das Bild, wenn es sich dem Bildschirm nähert. Beides gehört zum CSS-Modul und zur Geschwindigkeit.

Verbundene Zellen. colspan="3" verbindet drei Zellen in einer Zeile, und rowspan="2" zwei Zellen in einer Spalte. Dann ist scope wichtig: Ohne es rät der Browser, für welche Zellen die Kopfzelle gilt.

<b>, <i> und <br>. Es gibt sie, und sie haben eine Bedeutung: <b> ist Text, der hervorsticht, ohne wichtiger zu sein (ein Schlüsselwort), <i> ist eine andere Stimme (ein Fachbegriff, der Titel eines Buchs). Für wichtigen Text gibt es <strong>, für Betonung <em>.

Übung

Bestellung 1042

Baue die Seite der Bestellung 1042 von Grund auf. Ein Menü mit einem Link „Meine Bestellungen“ zu /orders. Eine Überschrift „Bestellung 1042“, darunter „Status: versendet“. Dann eine Tabelle „Die Produkte in der Bestellung“ mit den Spalten Produkt, Menge, Preis, Summe: Dobrudzha-Brot 2 × 1,80 € = 3,60 €, Frischmilch 3% 1 × 2,40 € = 2,40 €, Weißkäse 1 × 7,90 € = 7,90 €. Vor jedem Namen steht ein Bild von 32 × 32 (img/bread.svg, img/milk.svg, img/cheese.svg). Unten steht die Zeile „Gesamt“ mit 13,90 € in der letzten Spalte.

HTML, CSS, JS
index.html

Test

Teste dich

1. Die Seite liegt unter https://shop.example/bread/white/dobrudzha. Wohin führt <a href="../milk">?
2. Der Produktname ist als <h1> zu groß. Was tust du?
3. Neben dem Text „Geschenk bei Bestellungen über 30 €“ steht ein Geschenk-Symbol. Welches alt braucht es?
4. Warum schreibt man width und height an <img>, wenn das Bild auch ohne sie angezeigt wird?
5. Wann ist <table> das richtige Element?

Erstellt von Ivo Gergov im Rahmen der Kampagne von Evo Tech für zugängliche Programmierausbildung ·