Struktur, Links & Bilder
Ohne Links ist euer Hypertext nur Text. Und ohne Bilder lässt es sich schlecht Gestaltung präsentieren.
Wiederholung
Beim letzten Mal haben wir uns angesehen, wie ein typischer Website-Ordner strukturiert ist, wie eine typische HTML-Datei aufgebaut ist und was Favicons eigentlich sind. Außerdem haben wir uns mit den ersten HTML-Elementen wie dem <head> und <body> beschäftigt und uns angesehen, wie diese Elemente aus Tags aufgebaut und mit Attributen versehen werden. Zu guter Letzt haben wir ein paar Worte über semantisches HTML gewechselt und die ersten semantischen Elemente für Absätze, Überschriften, Zitate und Listen angesehen.
Was ist der Wurzel- oder „Root“-Ordner einer Website?
So wird der Ordner bezeichnet, in dem alle Dateien eurer Website abliegen. Die besondere Datei „index.html“ stellt hier die Startseite eurer Website dar. Alle Pfade in eurer Website beziehen sich auf diesen Wurzelordner.
Was ist ein <!DOCTYPE html>?
Dieses verpflichtende Tag am Anfang jedes HTML-Dokuments weist den Browser dazu an, die Website nach dem HTML-Standard darzustellen. Man kann es auch als <!doctype html> in Kleinbuchstaben schreiben. Ohne diesen Hinweis verfallen manche Browser teilweise in einen „Quirksmode“, der die Darstellung der Website beeinträchtigen kann.
Welche beiden Elemente sind innerhalb von <html> zugelassen?
Das <head>- und das <body>-Element, in dieser Reihenfolge. Im <head>-Element befinden sich Metadaten zur Seite, die im Browser selbst nicht sichtbar sind. Sie werden vor allem für die Steuerung von bestimmten Browserfunktionen wie der Skalierung und für Suchmaschinen verwendet. Im <body>-Element hingegen befindet sich der sichtbare Inhalt eurer Website.
Wo stehen Attribute?
Ein Attribut ist ein Merkmal, das einem HTML-Element hinzugefügt werden kann, z.B. um es eindeutig zu identifizieren („id“) oder, um einen Hinweis zur Sprache des Inhalts zu geben („lang“). Attribute befinden sich immer im öffnenden Tag eines HTML-Elements, also z.B. <html lang="en"></html>.
Was ist ein selbstschließendes Tag?
Ein selbstschließendes Tag ist ein HTML-Element, das keinen Inhalt unterstützt und dementsprechend auch kein schließendes Tag hat, z.B. das <meta>-Element oder das <br>-Element für harte Zeilenumbrüche. Selbstschließende Elemente werden auch teilweise „Void-Elements“ genannt und mit einem Slash vor der schließenden spitzen Klammer geschrieben, z.B. <br />.
Wie kann man eine geordnete Liste innerhalb einer ungeordneten Liste verschachteln?
Listen können verschachtelt werden, indem sie innerhalb eines <li>-Elements angelegt werden. Dabei spielt die Art der Liste keine Rolle, ihr könnt also geordnete Listen in ungeordneten Listen und andersherum verschachteln.
<ul>
<li>Ich bin ein ungeordnetes Listenelement</li>
<li>Und hier noch eins!</li>
<li>
Ich habe eine Unterliste
<ul>
<li>Ich bin ein verschachteltes Listenelement</li>
<li>
Ich bin ein verschachteltes Listenelement mit einer geordneten Liste
<ol>
<li>Erster Punkt</li>
<li>
Zweiter Punkt
<ul>
<li>Und wieder ungeordnet!</li>
</ul>
</li>
<li>Dritter Punkt</li>
</ol>
</li>
</ul>
</li>
<li>Und ich bin wieder auf der obersten Ebene!</li>
</ul>
Häufige HTML-Elemente (Teil 2)
Nachdem wir uns letztes Mal vor allem Elemente angesehen haben, um (Text-)Inhalte auf eine Seite zu bringen, sehen wir uns nun eine Klasse von häufigen Elementen an, die bei der Strukturierung von Inhalten helfen. Ich nenne diese Elemente deshalb auch gerne „Struktur-Elemente“. Diese Elemente sind auf der Seite nicht direkt sichtbar, helfen aber dabei, dem Dokument eine semantische Struktur zu geben, und können später bei der Gestaltung mit CSS „ausgewählt“ werden.
Der Block für Alles
Es gibt ein HTML-Element, das ständig eingesetzt wird, aber eigentlich kaum auftauchen sollte, das <div>-Element. Dieses HTML-Element ist eine generische Box. Sie sollte nur dann verwendet werden, wenn kein anderes HTML-Element passt.
Leider machen viele Entwicklerinnen und Entwickler sich das Leben leicht und nehmen für alles eine Div, was es wiederum schwieriger für Menschen mit Behinderungen macht, eine Seite zu konsumieren. Seid bitte nicht so!
Das <div> hat seinen Platz, z.B. als „Gruppierungselement“ für Styling-Zwecke, aber wenn es ein semantisch sinnvolleres Element für das gibt, was ihr erreichen möchtet, nehmt bitte das.
Navigationsbereiche
Fast jede Website hat einen oder mehrere Navigationsbereiche, typischerweise ein Hauptmenü im oberen Bereich der Seite und ein sekundäres Menü für weniger wichtige Seiten im unteren Bereich der Seite. Oft befinden sich diese beiden Menüs respektive in einem <header>- und einem <footer>-Element, aber das ist nicht zwingend notwendig.
Ein Navigationsbereich wird mit einem <nav>-Element erstellt, die einzelnen Links darin befinden sich oft innerhalb einer <ul>.
Wichtig ist auch, dass nicht jeder Link auf eurer Website innerhalb eines <nav>-Elements zu finden sein muss. Nur Gruppen von Navigationslinks sollten so zusammengefasst werden.
<nav>
<ul>
<li><a href="#">Home</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Contact</a></li>
</ul>
</nav>
Kopfzeilen
Einleitende Elemente können in einem <header>-Element gruppiert werden. So hat eine Website zum Beispiel meistens einen Header am Beginn der Seite, in dem sich das Logo und das Hauptmenü befinden. Aber auch ein Artikel oder ein Karten-Element können einen Header besitzen, in dem z.B. Titel und Autor gruppiert werden.
Es gibt keine Beschränkung, wie viele <header>-Elemente auf einer einzelnen Seite auftauchen können, aber es sollten sich niemals zwei gleichzeitig im selben Abschnitt befinden.
<header>
<a href="/">
<!-- Hier wäre wahrscheinlich ein SVG mit eurem Logo statt einem Text -->
<span>Logo</span>
</a>
<nav>
<ul>
<li><a href="#">Home</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Contact</a></li>
</ul>
</nav>
</header>
span {
font-weight: bold;
text-transform: uppercase;
}
Der Hauptteil
In jedem HTML-Element gibt es Elemente, die sich in anderen HTML-Dokumenten wiederholen, z.B. das Hauptmenü, oder der Footer. Das merkt ihr wahrscheinlich auch schon in euren Designs.
Jede Seite hat aber auch einen Teil, der einzigartig für diese Seite ist, z.B. die Details zu einem Projekt. Diesen Teil packt ihr in ein <main>-Element, das genau zu diesem Zweck existiert. Und da dieses Element den Hauptteil darstellt und es nur einen Hauptteil geben kann, kann es auch nur ein <main>-Element pro Seite geben.
Die <h1> des Dokuments könnt ihr euch auch als Überschrift für diesen Hauptteil vorstellen, denn sie stellt die Hauptüberschrift des HTML-Dokuments dar.
<!-- Hier würde euer <header> stehen -->
<main>
<h1>Meine Projekte</h1>
<p>Hier ist eine Liste meiner Projekte:</p>
<ul>
<li>
<a href="#">Projekt 1</a>
</li>
<li>
<a href="#">Projekt 2</a>
</li>
<li>
<a href="#">Projekt 3</a>
</li>
<li>
<a href="#">Projekt 4</a>
</li>
</ul>
</main>
<!-- Hier würde euer <footer> stehen -->
Abschnitte
So wie ihr auch ein langes Textdokument in mehrere Abschnitte einteilen würdet, um es übersichtlicher zu machen, teilt man auch eine lange Website in einzigartige Abschnitte auf. Dafür verwendet man das <section>-Element.
So habt ihr z.B. auf eurer Startseite einen Abschnitt über euch, einen Abschnitt, der eure Projekte teasert, und einen Abschnitt mit Kontaktinformationen. Diese drei Abschnitte hätten dann auch jeweils ihre eigene Überschrift (<h2>) und könnten wiederum eigene Unterabschnitte beinhalten.
<!-- Hier würde euer <header> stehen -->
<main>
<h1>Mein Portfolio</h1>
<p>Willkommen auf meiner Website!</p>
<section>
<h2>Über mich</h2>
<p>Lorem ipsum, dolor sit amet consectetur adipisicing elit. Laudantium ratione aliquam delectus nihil esse repellendus enim voluptates doloribus obcaecati quibusdam. Beatae rerum quos itaque illum consectetur cupiditate autem a ipsam.</p>
</section>
<section>
<h2>Meine Projekte</h2>
<p>Mehr zu meinen Projekten erfahrt ihr auf den jeweiligen Detail-Seiten:</p>
<ul>
<li>
<a href="#">Projekt 1</a>
</li>
<li>
<a href="#">Projekt 2</a>
</li>
<li>
Etc…
</li>
</ul>
</section>
<section>
<h2>Arbeitet mit mir!</h2>
<p>Ihr könnt mich jederzeit unter meinen Kontaktdaten erreichen:</p>
<p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Voluptate voluptates itaque consectetur in ipsa quibusdam quam vero, aut sequi, commodi sint voluptas. Animi iste aperiam suscipit. Illo hic quisquam voluptatem?</p>
</section>
</main>
<!-- Hier würde euer <footer> stehen -->
Falls ihr mal einen Abschnitt habt, der auch für sich selbst auf einer eigenen Seite stehen könnte, könnt ihr dafür statt einer <section> ein <article>-Element verwenden.
Fußzeilen für den Abschluss
Das Gegenstück zum <header>-Element ist das <footer>-Element, das eine Fußzeile darstellt. Auf den meisten Websites befinden sich hier das Copyright, sowie ein oder mehrere Navigationsbereiche für Links zu Seiten wie Impressum, AGB und Datenschutzerklärung und Social-Media-Accounts.
Wie auch schon Header, können Footer aber auch innerhalb des <main>-Elements verwendet werden, z.B. in Zitaten, um die zitierte Person zu benennen, oder innerhalb eines Teasers zu einem eurer Projekte, um zum Beispiel das Erstellungsdatum anzugeben.
<p>Body</p>
<header>
<p>Header</p>
<nav>
<p>Nav</p>
</nav>
</header>
<main>
<p>Main</p>
<section>
<p>Section 1</p>
</section>
<section>
<p>Section 2</p>
</section>
<section>
<p>Section …</p>
</section>
</main>
<footer>
<p>Footer</p>
<nav>
<p>Nav</p>
</nav>
</footer>
body {
text-align: center;
font-family: system-ui, sans-serif;
}
body, header, nav, main, section, footer {
background-color: rgb(0 0 0 / 0.1);
box-shadow: inset 0 0 0 1px #111;
padding: 1rem;
&:not(body) {
margin-top: 1rem;
}
}
p {
margin: 0;
}
Exkurs: Code-Editor Einrichten
Da wir uns im nächsten Abschnitt mit der Erstellung von Links befassen werden und ihr dazu mehr als ein HTML-Dokument benötigt, ist jetzt der Zeitpunkt gekommen, an dem wir zusätzlich zu Quadrants auch einen Code-Editor verwenden werden.
Wie bereits in der ersten Stunde erwähnt, empfehle ich euch hierfür Zed, ihr könnt aber gerne auch einen eigenen Editor wie VS Code verwenden, falls ihr damit bereits Erfahrungen sammeln konntet.
Zed ist sehr schlank. Nach der Installation gibt es nicht viel, das ihr konfigurieren müsstet, um loslegen zu können. Einen Account müsst ihr euch nicht erstellen, und persönlich bin ich ein Fan der „Atom-Keymap“ für Tastenkürzel, aber das ist sehr subjektiv.

Lediglich zwei Erweiterungen würde ich euch ans Herz legen: Emmet und Live Server. Diese könnt ihr euch im „Extensions“-Bereich (erreichbar via ⌘ + Shift + X / Strg + Shift + X) installieren.
Emmet erlaubt es euch, wie in Quadrants einfach direkt die Namen der Tags schreiben zu können, ohne die spitzen Klammern verwenden zu müssen. Der Live-Server erlaubt es euch hingegen, einen lokalen Server auf eurem Rechner zu starten und eure Website so direkt zu öffnen und während der Entwicklung anzusehen. Habt ihr die Erweiterung installiert, könnt ihr mit ⌘ + . / Strg + . die Code-Aktionen öffnen und „Open in Browser“ auswählen, um das HTML-Dokument zu öffnen.
Achtung: Da sich das Live-Server-Plugin noch in der Entwicklung befindet, kann es vorkommen, dass ihr in eurem HTML Zeichen findet, die ihr gar nicht geschrieben habt, z.B. ein Ausrufezeichen. Lasst euch davon nicht verrückt machen, das wird nicht sichtbar sein, wenn ihr eure Website veröffentlicht.
Falls ihr VS Code / Codium verwendet, ist Emmet für euch bereits aktiviert und ihr könnt die „Live Preview{ "de": "Wird in einem neuen Tab geöffnet", "en": "Opens in a new tab" }“- oder „Five Server{ "de": "Wird in einem neuen Tab geöffnet", "en": "Opens in a new tab" }“-Erweiterung installieren, um ebenfalls einen lokalen Server starten zu können.
Alternative zu den Live-Server-Plugins
Ich persönlich bin kein Fan von diesen Live-Server Erweiterungen, da sie oft intransparent sind und viel zu viele Features für das mitbringen, was ihr am Anfang macht. Ihr auch innerhalb von Zed ein Terminal öffnen (View > Terminal Panel) und python3 -m http.server eingeben, um einen lokalen Server zu starten.
Achtung: Wenn ihr den Befehl das erste Mal ausführt, und Python (eine andere Programmiersprache) noch nicht auf eurem Computer installiert habt, wird sich ein Fenster öffnen, über das ihr die Installation starten könnt. Auf macOS wird hierbei mehr Festplattenspeicher benötigt, da noch weitere Entwicklungstools installiert werden. Falls ihr also nicht so viel Speicher habt, verwendet besser eine der Live Server Erweiterungen in Zed oder VS Code.
Durch den Befehl wird eure Website unter https://localhost:8000{ "de": "Wird in einem neuen Tab geöffnet", "en": "Opens in a new tab" } erreichbar. Localhost ist euer eigener Computer, 8000 der Port, auf dem der lokale Server läuft. Um den Server wieder zu beenden, klickt in das Terminal und drückt Control + C auf macOS / Strg + C auf Windows.
Warum überhaupt einen lokalen Server?
Man kann HTML-Dateien auch im Finder / Dateimanager auswählen und im Browser öffnen. Allerdings wird die Datei dann über das „file“ Protokoll statt dem „http“ Protokoll geladen. Dabei kann es dazu kommen, dass z.B. korrekt eingefügte Bilder oder Links nicht funktionieren und zukünftig auch CSS und JavaScript Dateien nicht richtig geladen werden können.
Ein lokaler Server simuliert eine veröffentlichte Website, ist also so nah wie möglich an dem finalen Ergebnis dran. Wenn die Website im lokalen Server funktioniert, funktioniert sie meistens auch, wenn sie auf einem richtigen Server ausgeliefert wird.

Hyper-Links
Ohne Links ist eine HTML-Datei nur eine einfache Textdatei, erst mit Links wird sie zu einem Hypertext-Dokument. Höchste Zeit also, dass ihr erfahrt, wie ihr mehrere verschiedene HTML-Dokumente miteinander verlinken könnt.
Das HTML-Element, das ihr dafür verwendet, ist das <a>-Element ( „a“ für „anchor“). Damit könnt ihr Links auf andere HTML-Dokumente und Dateien im WWW setzen, oder eben auch die verschiedenen Seiten auf eurer eigenen Website miteinander verbinden.
Um das Ziel des Links festzulegen, verwendet ihr das href-Attribut. Wenn ihr außerdem das optionale target-Attribut mit dem besonderen Wert _blank verseht, öffnet sich der Link in einem neuen Tab oder Fenster – davon wird aber abgeraten, da Besucherinnen und Besucher eurer Seiten selbst entscheiden können sollten, ob sie einen Link in einem neuen Fenster öffnen möchten oder nicht.
Der Wert des href-Attributs ist eine URL, also ein Pfad zu einem anderen Dokument oder einer Datei, wie z.B. einem PDF. Außerdem könnt ihr zusätzlich noch einen „Sprungpunkt“, einen sogenannten Anker, angeben. Technisch nennt man diesen Anker den „Hash“ der URL, da sich dieser aus dem Hash-Symbol (#) und einer gültigen Element-ID zusammensetzt, z.B. #ueber-mich.
Befindet sich ein Element mit dieser ID (in diesem Beispiel ueber-mich) im Dokument, scrollt der Browser automatisch an diese Position. Somit lassen sich Sprungpunkte auch auf derselben Seite definieren, wie zum Beispiel hier im Inhaltsverzeichnis.
<a href="/">Lokaler Link</a>
<a href="https://webdesign.amxmln.com" target="_blank">Externer Link (öffnet in neuem Tab / Fenster)</a>
<a href="#weit-unten">Ankerlink auf dieser Seite</a>
UR-was? (URL / URI)
Jede Ressource im Internet hat eine einzigartige „Adresse“, um abgerufen werden zu können. Diese Adresse wird als „Uniform Resource Identifier“, kurz „URI“, bezeichnet. Die sogenannten „URLs“ (kurz für „Uniform Resource Locator“) sind hierbei die häufigste Form von URI, weshalb die beiden Begriffe häufig synonym verwendet werden. Umgangssprachlich spricht man auch oft von „Internet-“ oder „Webadresse“.
URIs gibt es in zwei verschiedenen Formen: als absolute und als relative URIs.
Absolute URIs
Absolute URIs bestehen aus einer Zusammensetzung aus Schema / Protokoll, Host und Pfad und zeigen die vollständige Adresse einer Resource im Internet an, z.B. „https://example.com/about/index.html“
Schema / Protokoll ist im Web (fast) immer http oder https
Host ist die Adresse des Servers, oft auch „Domain“ genannt
Pfad ist der Rest der URI, traditionell wortwörtlich der Pfad der Datei auf dem Server
Relative URIs
Relative URIs hingegen werden immer in einem eingeschränkten Kontext verwendet. Sie sind wie Telefonnummern ohne Vorwahl – sie ergeben nur Sinn, wenn man weiß, auf welchen Ort sie sich beziehen. Ein Beispiel für eine relative URI wäre „./about/index.html“.
Technisch sind URIs noch etwas komplexer als hier beschrieben und können noch weitere Teile beinhalten, für diesen Kurs werden wir aber nur diese vereinfachte Definition verwenden. Beachtet bitte aber, dass URIs nur folgende Zeichen beinhalten dürfen:
Buchstaben A – Z und a – z
Ziffern 0 – 9
Sonderzeichen - . _ ~
Daher auch die Einschränkungen in euren Dateinamen. Alle anderen Symbole müssen codiert werden, z.B. werden Leerzeichen als %20 dargestellt.
Jeder Dateipfad auf eurem Computer ist ebenfalls eine URI. Deshalb könnt ihr beim Verlinken eurer eigenen HTML-Dokumente auch relative Pfade verwenden.
./ bedeutet hierbei „vom aktuellen Ordner aus“
../ bedeutet „einen Ordner zurück“
/ bedeutet „vom Root aus“

Ob ihr eure Pfade vom Wurzel-Ordner aus setzt oder von der aktuellen Datei ausgehend, bleibt euch überlassen. Ich würde euch empfehlen, die kürzesten Pfade zu bevorzugen.
Richtlinien für Bilder im Web
Eine Website ohne Bilder ist fast so langweilig wie eine Website ohne Links – und Links und Bilder sind sich gar nicht so unähnlich! Wie ihr schon auf vielen verschiedenen Websites gesehen haben werdet, kommen Bilder in allen möglichen Farben und Formen – so lange diese Formen Rechtecke sind.
Bilder im Web sind einfach nur Dateien, die in einem Ordner auf einem Server liegen. Habt ihr schon einmal ein Bild rechtsgeklickt und „in einem neuen Tab“ geöffnet? Schaut dort mal auf die URL, ihr werdet sehen, dass sie in den meisten Fällen wie ein Link zu einem HTML-Dokument einfach ein direkter Pfad zu dem Bild ist.
Wenn ihr Bilder für das Web vorbereitet, solltet ihr ein paar wichtige Dinge beachten:
Bilder sollten immer möglichst klein sein (< 500 KB), reduziert also Dimensionen und Qualität beim Export und verwendet Werkzeuge wie Squoosh, um die Dateigröße weiter zu reduzieren
Bilder sollten immer nur so breit sein, wie sie maximal dargestellt werden. Wenn ihr wisst, dass ein Bild auf eurer Website in einem Rechteck mit maximal 600px dargestellt wird, braucht ihr es auch nicht breiter als 600px exportieren!
Für Fortgeschrittene: Ihr könnt Bilder auch responsiv machen, indem ihr
srcsetoder<picture>-Elemente verwendet, aber für den Anfang müssen sie das nicht seinVerwendet moderne Formate wie WebP, oder PNG, JPG und SVG
WebP wird gut unterstützt und hat sehr kleine Dateigrößen bei hoher Qualität
JPG ist der Standard für alles, was nicht transparent ist
PNG ist der Standard für alles, was Transparenzen enthält
SVG ist perfekt für abstrakte Formen, Icons und Logos, sowie animierte Grafiken und Zeichnungen
Finger weg von GIFs!
GIF ist ein veraltetes Format für animierte Bilder. Es hat sehr große Schwächen wie eine große Dateigröße, schlechte Qualität, Unterstützung für nur 255 Farben und negative Auswirkungen auf die Barrierefreiheit, da sie nicht pausierbar sind.
Falls ihr Animationen auf eurer Website zeigen möchtet, baut sie entweder mit SVG, HTML und CSS, oder verwendet kleine Videos im MP4-Format. Ein gut vorbereitetes Video hat oft eine höhere Qualität als ein GIF und trotzdem eine kleinere Dateigröße.
Bilder in HTML
Um ein Bild auf eurer Website anzuzeigen, verwendet ihr das <img>-Element. Da es keinen Inhalt unterstützt (denn es wird ja ein Bild angezeigt), ist es ein Void-Element und hat somit kein schließendes Tag.
Welches Bild angezeigt wird, wird durch das src-Attribut festgelegt. Hier könnt ihr entweder einen absoluten Pfad, wie z.B. die URL zu einem Bild auf einer anderen Website, oder einen relativen Pfad verwenden, um ein lokales Bild zu laden.
Außerdem solltet ihr auch immer eine width und eine height angeben. Durch sie weiß der Browser, welches Seitenverhältnis das Bild hat, bevor es lädt, und kann so vermeiden, dass eure Seite „springt“, während die Bilder laden.
Keine Sorge: Die genaue Größe des Bildes könnt ihr später mit CSS genau angeben. Gebt für width und height also einfach die Maße ein, die eure Bilddatei hat. Beide Attribute bestehen nur aus der Zahl, ohne Einheit, also z.B. <img width="300" height="200"> für eine Bilddatei mit 300x200px.
Ihr könnt den Browser auch anweisen, das Bild nicht sofort, sondern erst dann zu laden, wenn es sichtbar wird, z.B. wenn es sich weiter unten auf eurer Seite befindet. Dazu könnt ihr die Attribute loading="lazy" und decoding="async" verwenden.
Das „alt“-Attribut
Das wichtigste Attribut neben src ist aber unweigerlich das alt-Attribut. Darin müsst ihr eine Beschreibung des Bildes hinterlegen, die angezeigt wird, wenn das Bild aus irgendeinem Grund nicht lädt, oder jemand sich eure Website vorlesen lässt.
Versucht bei diesen Beschreibungen so spezifisch wie nötig, aber auch so kurz wie möglich zu bleiben. Konzentriert euch auf die wichtigsten Merkmale des Bildes und versucht, Redundanzen wie „Foto eines …“ zu vermeiden. Stellt euch vor, ihr müsstet das Bild in einem Telefonat beschreiben – das ist der Text, der in das alt-Attribut gehört.
<img
src="https://picsum.photos/seed/webdesign/300/200"
alt="Ein schneebedeckter Berggipfel im Nebel mit einem prominenten Felsen im Vordergrund und einem Schwarm Vögel in der linken Bildhälfte"
width="300"
height="200"
>
<img
src="/img.png"
alt="Dieser Text wird angezeigt, weil das zweite Bild nicht geladen werden kann!"
width="500"
height="200"
>
Bildunterschriften
Wenn ihr Bilder mit einer Bildunterschrift (Caption) darstellen möchtet, gibt es dafür ebenfalls ein eigenes HTML-Element: das <figure>-Element. Innerhalb dieses Elements verwendet ihr weiterhin <img> für das Bild, aber könnt mit <figcaption> auch eine Bildunterschrift damit assoziieren. Das ist besonders nützlich, falls ihr z.B. innerhalb einer eurer Arbeiten etwas mehr Kontext zu einem Bild geben möchtet.
<figure>
<img
src="https://picsum.photos/seed/webdesign/300/200"
alt="Ein schneebedeckter Berggipfel im Nebel mit einem prominenten Felsen im Vordergrund und einem Schwarm Vögel in der linken Bildhälfte"
width="300"
height="200"
>
<figcaption>Ich bin eine tolle Bildunterschrift!</figcaption>
</figure>
Wichtig: Der Text im alt-Attribut ist nicht der Text, den ihr in die <figcaption> schreiben solltet!
Sonderfall: SVG
Scalable Vector Graphics (SVG) sind ein besonderes Bildformat, das statt mit Pixeln mit mathematischen Funktionen arbeitet, um eine Grafik darzustellen. Dadurch sind diese Bilder unendlich skalierbar, ohne an Qualität zu verlieren. Außerdem sind SVGs gerade für einfache Grafiken wie Icons oder Logos um ein Vielfaches kleiner als herkömmliche Rastergrafiken wie JPG- und PNG-Bilder.
Durch diese Eigenheit eignen sich SVGs vor allem für einfache Grafiken, technische Zeichnungen oder abstrakte Illustrationen mit wenig Textur. Auch UI-Designs können, sofern sie keine eigenen Bilder enthalten, sehr gut als SVG funktionieren. Sobald eine Illustration aber viele kleine Teile oder Effekte wie Weichzeichnungen beinhaltet, könnte es sein, dass es sinnvoller ist, sie als Rastergrafik abzulegen – vergleicht hierzu am besten einfach die Größe des exportierten SVG mit der Dateigröße der exportierten Rastergrafik.
Ein SVG könnt ihr in Figma, Penpot, Illustrator oder Inkscape, sowie in vielen anderen Grafikprogrammen erstellen und wie jedes andere Bild auch als src-Attribut in einem <img>-Element verwenden. Mit einem Werkzeug wie SVGOMG{
"de": "Wird in einem neuen Tab geöffnet",
"en": "Opens in a new tab"
} könnt ihr SVGs zusätzlich auch noch optimieren.
Ihre wahre Stärke entfalten SVGs aber vor allem dann, wenn ihr sie direkt in euren HTML-Code einbettet!
Eingebettete SVGs
SVGs sind nämlich auch nur Textdateien und vom Format sehr nah an HTML (sowohl SVG als auch HTML sind Varianten von XML). Ihr könnt SVGs sogar von Hand schreiben, um die volle Kontrolle zu bewahren, was sehr nützlich sein kann, wenn man bestimmte Effekte erzielen möchte.
Da HTML und SVG miteinander kompatibel sind, könnt ihr ein SVG einfach in eurem Code-Editor öffnen und den Code direkt in euer HTML-Dokument einfügen. Dadurch bettet ihr das SVG direkt ein und könnt es dynamisch mit CSS und JavaScript manipulieren und animieren. Dadurch können eure Illustrationen interaktiv werden, die Farbe ändern und sogar auf den Light- oder Darkmode eures Websitebesuchers reagieren.
Der einzige Nachteil ist, dass eingebettete SVGs euren Code sehr schnell sehr unübersichtlich werden lassen können. Lasst euch aber davon nicht abhalten, es auszuprobieren!
<svg
viewBox="0 0 598 613"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M194.966 107.372C187.632 100.636 182.162 91.9479 181.618 81.5272C180.052 51.5024 222.295 52.963 232.2 66.9978C242.106 81.0326 245.827 119.261 235.739 123.226C231.716 124.807 222.544 123.27 212.869 118.947L223.435 158.252L190.05 162.351L194.966 107.372Z" fill="#915B3C"/>
<path d="M211.049 52.0179C206.561 51.8366 194.652 52.7951 192.468 53.0637C191.072 53.2351 189.598 53.7399 188.613 52.5594C187.807 51.5928 187.837 49.7868 187.486 48.5933C187.077 47.2069 186.572 45.8509 186.064 44.4988C184.618 40.6515 182.704 37.0572 180.239 33.7647C175.614 27.5876 169.395 23.0679 161.979 20.9042C153.789 18.5152 144.892 18.8303 136.607 20.536C127.742 22.3612 119.999 26.3125 111.886 30.1323C104.155 33.7724 95.8447 35.8519 87.2594 35.592C78.6094 35.3304 71.6294 31.5165 63.9321 28.0284C56.0522 24.4573 47.3152 22.5617 38.7313 24.2981C30.7185 25.9191 23.6725 30.1749 17.5309 35.4585C11.7847 40.4019 7.23714 46.0589 5.18951 53.4864C2.98665 61.4761 4.01444 69.823 9.99757 75.9103C18.6699 84.7341 32.8586 85.5491 44.3748 83.8808C51.0361 82.9163 57.4459 80.8917 63.4794 77.8996C71.5256 73.9091 78.1772 68.0035 85.5451 62.9699C89.0028 60.6078 92.6267 58.5715 96.4883 56.9511C100.235 55.3782 103.997 54.406 107.8 56.3194C111.822 58.3436 115.453 60.3714 119.897 61.4021C124.16 62.3909 128.585 62.6936 132.928 62.1262C141.378 61.0223 149.393 57.3631 157.391 54.5891C163.913 52.3273 170.905 50.0128 177.905 50.5577C180.825 50.7853 185.134 51.4661 186.527 54.3015C169.589 59.5685 165.415 81.8294 172.23 96.958C175.909 105.124 192.972 113.102 198.585 107.882C202.141 104.576 199.316 101.155 197.481 98.8929C193.968 94.561 192.224 88.6568 197.257 84.7226C201.598 81.3294 207.348 87.4154 207.44 87.3966C208.716 87.1369 219.075 79.4745 225.617 69.3459C233.238 68.8654 233.773 63.7356 231.466 59.8774C229.158 56.0192 217.251 52.269 211.049 52.0179Z" fill="#191847"/>
<path d="M201.484 276.935L252.821 453.837L276.967 586.658H301.203L277.011 276.935H201.484Z" fill="#784931"/>
<path d="M178.414 276.935C181.996 368.835 180.584 418.959 179.782 427.309C178.98 435.658 174.429 491.578 143.414 589.461H168.621C209.695 495.559 224.034 439.639 228.745 427.309C233.455 414.978 247.369 364.854 267.681 276.935H178.414Z" fill="#915B3C"/>
<path d="M200.387 276.935C213.74 337.807 236.836 434.976 269.674 568.439H305.122C307.74 431.452 296.602 341.291 277.314 276.935H200.387Z" fill="#69A1AC"/>
<path d="M178.239 276.935C181.747 368.835 172.655 459.374 144.492 569.87H182.312C223.462 477.369 252.955 387.277 273.112 276.935H178.239Z" fill="#C5CFD6"/>
<path d="M139.824 607.68L141.215 585.257C149.358 587.639 159.558 586.704 171.814 582.454C184.992 591.789 201.581 598.163 221.582 601.576C223.108 601.836 224.134 603.284 223.873 604.81C223.856 604.909 223.834 605.007 223.807 605.103L221.884 611.885H171.814H142.606L139.824 607.68Z" fill="#191847"/>
<path d="M271.559 607.68L272.949 585.257C281.093 587.639 291.292 586.704 303.548 582.454C316.726 591.789 333.315 598.163 353.316 601.576C354.842 601.836 355.868 603.284 355.608 604.81C355.591 604.909 355.569 605.007 355.541 605.103L353.618 611.885H303.548H274.34L271.559 607.68Z" fill="#191847"/>
<path d="M317.219 245.12L366.945 269.685C379.453 270.802 390.136 273.052 398.993 276.434C401.189 277.825 404.092 280.914 396.138 281.694C388.183 282.475 379.851 283.653 379.24 286.521C378.629 289.389 383.943 291.753 382.391 295.751C381.356 298.416 373.397 293.594 358.513 281.285L311.729 270.893L317.219 245.12ZM148.382 276.041L177.244 271.069C169.572 331.698 165.336 363.897 164.537 367.664C162.739 376.142 171.623 387.004 175.655 392.973C166.985 398.844 165.237 383.069 154.337 390.687C144.388 397.64 137.755 408.23 123.871 402.712C122.164 402.033 119.846 398.754 123.429 395.24C132.356 386.487 144.842 371.72 146.112 367.36C147.843 361.414 148.6 330.974 148.382 276.041Z" fill="#915B3C"/>
<path d="M209.007 140.564L220.58 136.412C271.606 166.857 302.751 237.136 363.892 266.495L353.684 284.992C257.467 289.936 218.323 204.415 209.007 140.564Z" fill="#1F28CF"/>
<path d="M183.423 299.718C231.276 291.28 266.476 285.073 289.022 281.098C293.847 280.247 291.709 273.44 290.392 270.047C275.187 230.889 236.048 192.689 225.864 134.928L194.562 135.522C176.512 180.484 176.596 231.909 183.423 299.718Z" fill="#DDE3E9"/>
<path d="M163.556 182.058C158.908 181.566 154.882 179.218 151.478 175.013C136.802 156.888 138.873 145.118 150.13 139.385C161.386 133.651 173.317 139.269 192.273 135.927C193.304 135.745 194.26 135.643 195.141 135.621L204.772 134.484C248.479 222.38 266.933 282.912 260.131 316.078L177.017 330.733C174.117 343.084 171.108 353.576 167.991 362.21L145.343 366.203C131.06 297.663 137.131 236.281 163.556 182.058Z" fill="#2B44FF"/>
<path d="M186.712 279.923C193.182 301.332 200.23 316.456 207.854 325.294L177.01 330.733C180.392 316.326 183.626 299.389 186.712 279.923L186.712 279.923Z" fill="black" fill-opacity="0.1"/>
<g>
<g>
<path d="M537.526 460.362H491.836C490.352 460.362 489.148 461.565 489.148 463.049V469.769C489.148 471.253 490.352 472.456 491.836 472.456H537.526C539.01 472.456 540.214 471.253 540.214 469.769V463.049C540.214 461.565 539.01 460.362 537.526 460.362Z" fill="#AFB9C5"/>
<path d="M502.588 421.391C508.357 402.692 511.589 382.983 512.286 362.263H516.026H518.422C519.118 382.983 522.351 402.692 528.12 421.391H536.855C548.359 421.391 557.684 430.717 557.684 442.22C557.684 453.724 548.359 463.049 536.855 463.049H492.509C481.005 463.049 471.68 453.724 471.68 442.22C471.68 430.717 481.005 421.391 492.509 421.391H502.588Z" fill="#DDE3E9"/>
<path class="shade" d="M467.141 269.107C482.54 267.604 497.939 266.852 513.339 266.852C528.738 266.852 544.137 267.604 559.536 269.107L565.748 375.88C548.278 377.552 530.808 378.389 513.339 378.389C495.869 378.389 478.399 377.552 460.93 375.88L467.141 269.107Z" fill="#C5CFD6"/>
</g>
<path d="M458.244 472.456H569.781H598.001V612.214H569.781V502.02H458.244V612.214H430.023V472.456H458.244Z" fill="#F2F2F2"/>
</g>
</svg>
@keyframes bounce {
from {
translate: 0 -2rem;
}
}
body {
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
min-height: 100vh;
}
svg {
display: block;
max-height: 100vh;
max-width: calc(100% - 2rem);
margin-top: auto;
margin-inline: auto;
}
g > g {
cursor: pointer;
transition: translate 200ms ease;
&:active {
translate: 0 -2rem;
.shade {
fill: gold;
}
}
&:not(:active) {
animation: bounce 750ms linear(0, 0.223 11.7%, 0.392 18.4%, 0.619 24.8%, 0.999 33.3%, 0.748 40%, 0.691 42.7%, 0.672 45.3%, 0.69 47.8%, 0.743 50.4%, 0.999 57.7%, 0.883 61.8%, 0.856 63.6%, 0.848 65.3%, 0.855 67%, 0.879 68.8%, 0.999 74.5%, 0.953 77.5%, 0.94 80.2%, 0.95 82.7%, 1 88.2%, 0.987 91.9%, 1);
}
}
Versucht mal, im Beispiel oben die Lampe anzuklicken. 😉
Audio & Video
Wenn ihr mit animierten SVGs nicht glücklich werdet, oder gerne auch Ton bei euren Bewegtbildern dabei hättet, könnt ihr euch die <audio>- und <video>-Elemente näher ansehen. In ihnen könnt ihr Videos und Audiodateien mithilfe von <source>-Elementen einbetten und über verschiedene Attribute Autoplay, Steuerelemente und viel mehr kontrollieren. Sie sind etwas komplizierter, deshalb behandle ich sie in diesem Einführungskurs nicht weiter.
Bitte beachtet aber, dass gerade Videos sehr groß werden können und ihr gerade bei kostenlosen Hostinganbietern oft ein Limit an Bandbreite habt, die ihr monatlich verwenden dürft, bevor ihr zur Kasse gebeten werdet. Wenn ihr also beispielsweise ein Video mit 50 MB auf eurer Website habt und 50 Menschen eure Website besuchen, verbraucht das 2,5 GB eurer Bandbreite. Wäre das Video 1 GB groß, würden diese 50 Menschen in kürzester Zeit eure halbe Bandbreite verbrauchen!
Deshalb ist es gerade am Anfang besser, die Videos bei einem externen Anbieter wie YouTube oder Vimeo zu hosten und sie dann auf eurer Website einzubetten. Diese Plattformen sind darauf spezialisiert, eure Videos in verschiedenen Formaten und Größen anzulegen und an die Besucher und Besucherinnen eurer Website auszuliefern.
Leider sind viele dieser Anbieter entweder sehr teuer, oder aus dem Ausland, was wiederum bedeutet, dass ihr sehr vorsichtig bei der Einbettung sein müsst und zum Beispiel für Vimeo und YouTube zuerst das Einverständnis eurer Besucherinnen und Besucher einholen müsst.
Praxis
Falls ihr es noch nicht getan habt, installiert euch bitte einen Code-Editor und richtet diesen ein. Ihr werdet ihn für die heutigen Praxisaufgaben brauchen.
In der letzten Praxisaufgabe habt ihr ein erstes HTML-Dokument erstellt und dort einen kleinen „Über mich“-Bereich eingefügt. Versucht nun bitte, dort ein Bild einzusetzen, das ihr vorher zugeschnitten und mit Squoosh optimiert habt.
Falls ihr die Aufgabe in Quadrants gemacht habt, solltet ihr euren Code als HTML-Dokument exportieren und ihn lokal in eurem Code-Editor öffnen. Nur so könnt ihr das Bild lokal verlinken.
Der zweite Teil der heutigen Praxis ist ein kleines „Link-Spiel“, mit dem ihr das Setzen von Links üben und ein tieferes Verständnis für Dateipfade entwickeln könnt. Ladet euch dafür bitte das Starterpaket herunter und entpackt es auf eurem Computer.
Öffnet den Ordner dann in eurem Code-Editor. Das Beispiel ist ein einfacher Blog, auf dessen Startseite sich alle Posts absteigend sortiert nach Veröffentlichungsdatum befinden. Jeder Post selbst verlinkt auf den nächsten und den vorherigen Post in der Veröffentlichungsreihenfolge.
Wird im neusten Post „Ethical Considerations in AI-Driven Design“ auf „Next Post“ geklickt, soll der älteste Post „Designing for Accessibility: Inclusive User Experiences“ erscheinen. Klickt man in diesem Post auf „Previous Post“, soll man wieder beim neusten Post landen.
Im Beispielordner unter „Posts“ sind alle Posts nach Jahr und Erscheinungsmonat gruppiert, der neuste Post befindet sich also z.B. im Ordner /posts/2023/10, da er im Oktober 2023 erschienen ist.
Leider sind im Quellcode alle Links zu Posts durch ein „#“ ersetzt worden. Eure Aufgabe ist es nun, sie wiederherzustellen. Fangt am besten auf der Startseite an und arbeitet euch dann durch die einzelnen Posts.
Tipp: Verwendet die „Suchen“-Funktion eures Code-Editors, um nach „href="#"“ zu suchen. So findet ihr schnell die Stellen, an denen ihr die Links eintragen müsst.
Viel Spaß!