HTML/Tutorials/Listen/Fußnoten mit CSS

Aus SELFHTML-Wiki
< HTML‎ | Tutorials‎ | Listen
Wechseln zu: Navigation, Suche

Informationen zu diesem Text

Lesedauer
20min
Schwierigkeitsgrad
einfach
Vorausgesetztes Wissen
Grundkenntnisse in
HTML
CSS

Bei Druckerzeugnissen werden Anmerkungen oft aus dem Fließtext in Fußnoten ausgelagert, um den Text flüssig lesbar zu gestalten. Diese Anmerkungen können Legenden, Quellenangaben oder weiterführende Erklärungen enthalten. Nach Din 5008 wird hinter das zu erklärende Wort eine Anmerkungsziffer gesetzt, die auf eine Erklärung am Seitenende verweist.[1]

Auf Webseiten sind Fußnoten eigentlich nicht nötig, da es einerseits keine feste Paginierung (Seiteneinteilung) gibt, sodass auch längere Texte in ein Dokument zusammengefasst werden können und andererseits ein Hyperlink direkt zu einer Anmerkung oder Quelle verweisen kann. Des Weiteren können Sie mit einem Tooltip eine Kurzinfo zur Verfügung stellen, die aber auf mobilen Geräten nicht dargestellt wird.

Trotzdem kann es eine Webseite aufwerten, wenn Sie Fußnoten setzen, die einen seiteninternen Link von der Textstelle zur Fußnote und wieder zurück bieten.

Fußnoten mit CSS[Bearbeiten]

Ziel unseres Anwendungsbeispiels soll es sein, dass auch Benutzer mit Screenreadern die Zusammenhänge zwischen Link und Fußnote erkennen können. Hugo Giraudel stellte 2015 zugängliche Fußnoten mit CSS vor[2], die Screenreadern durch ARIA-Attribute weitere Informationen über die Linkbeziehungen zu den Fußnoten zu geben. Falls ein Text viele Fußnoten, bzw. aria-Labels enthält, verkehrt sich dies jedoch ins Gegenteil, wenn der Textfluss durch das Vorlesen der zahlreichen aria-Hinweise unterbrochen wird.

Was oft vergessen wird: Es gibt nur sehr wenig völlig Blinde, die auf Screenreader angewiesen sind, jedoch viele eingeschränkt Sehende. Für sie wird z. B. bei Buttons eine Mindestgröße von 44 x 44px empfohlen, damit sie noch gut erkenn- und klickbar sind. Fußnoten unterschreiten diesen Wert bei Weitem.

zugängliches Markup[Bearbeiten]

Dieses Beispiel arbeitet mit document structure roles, die „normalen“ HTML-Elementen eine zusätzliche Semantik geben.[3]

zugängliches Markup - Links im Haupttext
Fußnoten-Stichwort <a href="fn01" role="doc-noteref">[1]</a>

<footer>
  <h2 id="footnote-label">Fußnoten</h2>
  <ol>
    <li id="fn01" role="doc-footnote">Fußnoteninhalt</li>
    ...
  </ol>
</footer>

Links, die auf Fußnoten verweisen, erhalten ein role-Attribut mit dem Wert doc-noteref. So wird klar, dass es keine externen Links sind.

Auch die Fußnote selbst wird so als role="doc-footnote" ausgezeichnet. Daneben enthält die Fußnoten-Referenz im Haupttext ein href-Attribut auf die entsprechende id der Fußnote.

Der Footer, in dem unsere Fußnoten aufgelistet werden, erhält eine id footnote-label.

Backlinks einrichten[Bearbeiten]

Gerade bei längeren Texten (und besonders für Screenreader-Nutzer) ist es oft schwierig von der Fußnote wieder zurück zur passenden Stelle im Hauptteil zu gelangen. Ein „Back-to-Content“-Link macht dieses Beispiel nun wirklich zugänglich.

Backlink, um in den Haupttext zurückzuspringen ansehen …
Fußnoten-Stichwort <a href="fn01" id="fnref01" role="doc-noteref">[1]</a>

<footer>
  <h2 id="footnote-label">Fußnoten</h2>
  <ol>
    <li id="fn01" role="doc-footnote">
      Fußnoteninhalt
      <a role="doc-backlink" href="#fnref01">1.</a>
    </li>
    ...
  </ol>
</footer>

Jeder Verweis auf eine Fußnote erhält nun eine id, die zur Kennzeichnung den String fnref- erhält.

Am Ende jeder Fußnote wird nun ein Link angefügt, der als Linktext das Backlink Unicode Icon (↩) enthält. Um den Link genauer zu beschreiben, erhält er zusätzlich ein role="doc-backlink".

Anmerkungsziffern automatisch erstellen[Bearbeiten]

Im obigen Beispiel wurden die einzelnen Fußnoten fest nummeriert - bei einer Änderung im Text müssen unter Umständen alle Nummern händisch geändert werden.

CSS-Counters erlauben das Erstellen und Kontrollieren automatischer Nummerierungen, die sich bei Änderung des Markups dynamisch anpassen. Für jeden Link auf eine Fußnote, der ein role="doc-noteref"-Attribut besitzt, soll nun eine inkrementelle Zahl ermittelt werden, die dann in einem :after-Pseudoelement dargestellt wird.

Das HTML bleibt unverändert, außer, dass bei den Fußnoten-Referenzen der Linktext leer ist.

Anmerkungsziffern mit CSS-Counters erstellen ansehen …
body {
  counter-reset: footnotes;
}

[role="doc-noteref"] {
  counter-increment: footnotes; 
}

[role="doc-noteref"]::after {
  content: '[' counter(footnotes) ']'; 
  vertical-align: super; 
  font-size: 0.75em; 
}

[role="doc-noteref"]:focus::after {
  outline: thin dotted;
  outline-offset: 2px;
}

CSS zählt nun die Fußnoten. Mit counter-reset: footnotes; wird der Zähler auf 0 gesetzt.

[role="doc-noteref"] selektiert nun alle Fußnoten-Referenzen. Bei ihnen wird mit counter-increment die Zählung um 1 erhöht;

[role="doc-noteref"]::after erzeugt nun ein Pseudoelement, das mit content den aktuellen Wert von counter(footnotes) erhält. Es soll hochgestellt dargestellt werden, dies könnte man mit dem sup-Element erreichen, wird hier aber mit vertical-align erreicht.

Komfort-Version mit JavaScript[Bearbeiten]

Das oben gezeigte Beispiel bietet dem Benutzer Komfort und Zugänglichkeit - für den Entwickler ist das händische Generieren von Fußnoten aufwändig und fehleranfällig.

Die folgende Lösung erlaubt es die Fußnoten direkt im Text zu notieren. Ein Script ersetzt den Text durch den Link zur Fußnote, fügt die Fußnote mit dem Textinhalt und einen Backlink ein.

HTML-Markup[Bearbeiten]

Das HTML-Markup wird nun vereinfacht. Der Fußnoteninhalt schließt sich in einem Custom Element dem Fußnotenstichwort an. Es gibt in HTML weder ein passendes Element für die Fußnoten unten als auch für den Link dahin.[4] David MacDonald schlug ein <noteref> und ein <note>-Element vor.[5]

In Mediawiki wird ein <ref>-Element verwendet, dass dann von der Software in eine Fußnote umgewandelt wird.

ursprüngliches HTML-Markup ansehen …
Fußnoten-Stichwort<x-ref>Fussnoteninhalt</x-ref>

Das x-ref-Element ist durch das vorangestellte x als custom element erkennbar, wird aber normal dargestellt und per CSS gestylt. Falls Javascript deaktiviert ist, verbleiben die Notizen im Kontext.

JavaScript[Bearbeiten]

Das im body geladene Script durchsucht das Dokument nach allen Vorkommen von x-ref:

var footnotes = document.querySelectorAll('x-ref');

Die so entstandene Live node list aller Vorkommen wird nun abgearbeitet:


JS-Funktion, die Fußnoten setzt ansehen …
Fußnoten-Stichwort<x-ref>Fussnoteninhalt</x-ref>
  1. mit textContent wird der Fußnoteninhalt ausgelesen und in das
  2. mit createElement erzeugte Fußnoten-Listenelement kopiert
  3. dieses Listenelement erhält nun eine id und den Backlink als weiteres Kindelement
  4. das x-ref Element wird gelöscht und an seine Stelle ein a-Element mit passendem href-Attribut, id und role-Attribut eingehängt

bisher[Bearbeiten]

autoFootNoter.js wird am Ende des HTML-body eingebunden. Sie können die zwei Funktionen aber auch ganz einfach in Ihre Library integrieren.

Beispiel
Die erste Funktion muss am Ende einmal aufgerufen werden.

Sie beginnt mit einem Konfigurationsabschnitt mit hoffentlich selbstsprechenden Variablen.

Die Variable footnotifyElementsByCssSelector enthält einen CSS-Selector, wie Sie Ihn auch in einem CSS-File notieren würden. Er wird der Methode querySelectorAll() übergeben.
function autoFootNoter(){
   /* START KONFIGURTATION */
   var footnotifyElementsByCssSelector = "body .fn",
      appendFootnoteCollectionToElementById = "examplecontent",
      footnoteCollectionId = "footnotes",
      footnoteCollectionHeadingAsHTML = "<h3>Fussnoten</h3>",
      footnoteAnchorIdPrefix = "fna",
      footnoteIdPrefix = "fn",
      showHovernotes = true;
   /* END KONFIGURTATION */
Der folgende Scriptabschnitt sammelt alle Elemente der definierten Klasse. Zum Einsatz kommt die neue DOM-Methode querySelectorAll(), welche eine statische Node-Liste zurückgibt.
   if(!document.querySelector){ return; }
   var f = document.querySelectorAll(footnotifyElementsByCssSelector);
Es wird ein Element für die Fußnoten-Sammlung kreiert. An dieses wird auch die Fußnoten-Überschrift angehängt.

Zusätzlich wird ein Element erzeugt, das später als Hovernote dienen soll. Es wird dem body-Element angehängt.

Es ist wichtig, dass wir hier ein Element via DOM-Methoden erzeugen und anhängen, und nicht etwa via innerHTML. Letzteres war für den Entwickler Anlass aufwändiger Fehlersuche.
   if(f){
      var col = document.createElement("div");
         col.id = footnoteCollectionId;
         col.innerHTML = footnoteCollectionHeadingAsHTML;
      var hnote = document.createElement("div");
         hnote.id="hovernote";
         document.getElementsByTagName("body")[0].appendChild(hnote);
Es wird nun jedes Element der statischen Node-Liste behandelt.

Bei einer statischen Nodeliste iterieren wir im Falle der Entfernung von Nodes anders, als wir das bei live-Nodelisten tun.

Der Fußnoten-Sammlung wird der Inhalt mit einem Backlink angehängt. Dabei wird das ursprüngliche Element in der Original-Fußnote zugunsten eines neutralen div-Elements getilgt.

Anschließend wird der Anker-Link mit id generiert. Er soll anschließend die originale Fußnote der Collection ersetzen.
      for(var i=0, j=1; i< f.length; i++, j++ ){
         col.innerHTML += '<div><a href="#' + footnoteAnchorIdPrefix + j
            + '" id="' + footnoteIdPrefix + j + '">' + j + '</a> <div>'
            + f[i].innerHTML+'</div></div>';
         var a = document.createElement("a");
            a.id = footnoteAnchorIdPrefix+j;
            a.href = '#'+footnoteIdPrefix+j;
            a.innerHTML=j;
Falls Hovernoten erwünscht sind, werden dem erzeugten Anker drei Eventhandler angehängt. Zwei Handler sind nur für das Verbergen zuständig. Der onclick-Handler ist wegen einem Bug in Opera notwendig.
         if(showHovernotes){
            a.title = ""; // Opera title stört bei Hovernotes
            a.onmouseover = function(event){ hoverNote(this,event);};
            a.onclick = function(){ hoverNote(); };
            a.onmouseout = function(){ hoverNote(); };
         }
Zuletzt wird die originale Fußnote durch den erzeugten Link ersetzt. Anders als bei einer Live-Nodeliste wird bei einer statischen Nodeliste durch replaceChild nicht der Knoten aus der Liste gelöscht, sondern es wird nur das DOM verändert. Die gesamte Fußnotensammlung wird nun an das definierte Element angehängt.
         f[0].parentNode.replaceChild(a, f[0]);
      }
      document.getElementById(appendFootnoteCollectionToElementById).appendChild(col);
   }
}
Die zweite Funktion wird durch die den Fußnotenankern angehängten Handler aufgerufen.

Wie immer muss das event-Objekt browserübergreifend abgefragt werden.

Die Position des Hovernote-Elements nahe dem Eventereignis im Fußnoten-Ankerlink bedingt, dass die Hovernote via CSS fixiert positioniert ist.
function hoverNote( el, evt ){
   var h = document.getElementById('hovernote');
   if(!evt) evt = window.event;
   if(el){
      var i = el.hash.substr(1,el.hash.length);
      h.innerHTML = document.getElementById(i).parentNode.innerHTML;
      h.style.display="block";
      h.style.left=(evt.clientX*0.7-10)+'px';
      h.style.top=(evt.clientY+15)+'px';
   }
   else{
      h.style.display="none";
      h.innerHTML ="";
   }
}
Zuletzt rufen wir die Funktion einmal auf.
autoFootNoter();

Live-Beispiel[Bearbeiten]

Beispiel ansehen …
...(Link oben rechts)...


Quellen[Bearbeiten]

  1. Wikipedia: DIN 5008
  2. sitepoint.com: Accessible Footnotes with CSS von Hugo Giraudel
  3. W3C: Digital Publishing WAI-ARIA Module 1.0 W3C Recommendation 14 December 2017
  4. WHATWG: Footnotes
  5. CanAdapt: Footnotes and endnotes in HTML.next von David MacDonald

Weblinks[Bearbeiten]