JavaScript/Tutorials/zugängliche Dropdown-Navigation
atina
- browser
Hallo,
am Ende des Beispielcodes stand folgender Hinweis, mit dem ich aber nicht viel anfangen kann:
"In den Beispielcode wurde noch ein Polyfill für Browser eingebaut, die details/summary nicht unterstützen (z.Zt. IE und Edge). Dieser Polyfill ist an die Bedürfnisse der Navigation angepasst.
Im realen Einsatz sollte der Polyfill in eine eigene Datei ausgelagert und nur bei Bedarf geladen werden. "
Was genau muss ich jetzt noch anstellen, damit die Untermenüs der Navigation auch im IE nicht von Anfang an aufgeklappt sind?
Hallo,
ich vermute, du meinst dieses Tutorial:
https://wiki.selfhtml.org/wiki/JavaScript/Tutorials/zugängliche_Dropdown-Navigation
Das Beispiel https://wiki.selfhtml.org/extensions/Selfhtml/example.php/Beispiel:Menue_mit_details.html sollte auch im IE funktionieren. Tut es das bei dir?
Im Quelltext dieser Datei findest du folgendes:
// Polyfill für IE und Edge
var native_details = ('open' in document.createElement("details"));
if (!native_details) {
/* var script = document.createElement('script');
script.src = "details-polyfill.js";
document.getElementsByTagName('head')[0].appendChild(script);
*/
// details-polyfill.js
...
// Ende details-polyfill.js
}
Alles zwischen // details-polyfill.js und // Ende details-polyfill.js muss in eine Datei mit Namen details-polyfill.js verschoben werden, und der Teil
/* var script = document.createElement('script');
script.src = "details-polyfill.js";
document.getElementsByTagName('head')[0].appendChild(script);
*/
muss von den Kommentarzeichen befreit werden. Denn der lädt den Polyfill. Evtl. muss der Pfad angepasst werden.
Das Menüscript sieht dann so aus:
window.addEventListener("DOMContentLoaded",function() {
"use strict"
// Das Navigationselement
var navele = document.querySelector("#sitenav");
if(!navele) return;
// Polyfill für IE und Edge
var native_details = ('open' in document.createElement("details"));
if (!native_details) {
var script = document.createElement('script');
script.src = "details-polyfill.js";
document.getElementsByTagName('head')[0].appendChild(script);
}
// Alle details und summary
var details = navele.querySelectorAll("details");
var summary = navele.querySelectorAll("summary");
... hier weiter wie im Beispiel, bis einschließlich
});
und sollte in eine Datei menue.js ausgelagert werden. Ebenso sollte das css in eine Datei menue.css ausgelagert werden.
Gruß
Jürgen
Hallo Jürgen, 😀jetzt funktioniert alles, 1000 Dank für die detaillierten Tipps!
Du empfiehlst, das Menü in eine menue.js auszulagern, entsprechend das css. Bislang habe ich das komplette Menüscript auf allen Seiten im <head> eingefügt. Wenn ich dieses in eine eigene Datei auslagere, muss ich dann nicht einen Verweis in den head aufnehmen?
Und kann ich die menue.css direkt unter meiner bisherige css einfügen, also so: <link rel="stylesheet" type="text/css" href="standard.css"> <link rel="stylesheet" type="menue/css" hraf="menue.css">?
Jetzt hab ich noch eine weitere Frage zu den Menüunterpunkten: Auf kleinen Bildschirmen sollen die <li> nicht rechts neben dem <ul> angeordnet werden, sondern darunter. Ich habe die Ränder mit margin verändert, das Ergebnis ist aber leider, dass auf großen Bildschirmen die komplette Zeile nun farblich hinterlegt ist und nicht nur der Unterpunkt. Viele Grüße Anita
Hallo Anita,
Du empfiehlst, das Menü in eine menue.js auszulagern, entsprechend das css. Bislang habe ich das komplette Menüscript auf allen Seiten im <head> eingefügt.
wenn du mal am css oder am Javascript etwas ändern musst, musst du das dann nur an einer Stelle machen. Auch werden CSS und Javascript wegen des Browsercaches nur einmal übertragen.
Wenn ich dieses in eine eigene Datei auslagere, muss ich dann nicht einen Verweis in den head aufnehmen?
Ja, das musst du.
<link rel="stylesheet" href="menue.css" type="text/css">
<script src="menue.js"></script>
Und kann ich die menue.css direkt unter meiner bisherige css einfügen, also so: <link rel="stylesheet" type="text/css" href="standard.css"> <link rel="stylesheet" type="menue/css" hraf="menue.css">?
Ja, das sollte (bis auf den Tippfehler hraf) gehen. Ich habe auf meiner Seite das Seiten-css und das Menue-css sogar in einer Datei zusammengefasst.
Jetzt hab ich noch eine weitere Frage zu den Menüunterpunkten:
Hier wäre jetzt ein Link zu deiner (Test-)Seite ganz hilfreich. Denn so richtig kann ich mir nicht vorstellen, was du da vorhast.
Gruß
Jürgen
Hallo Jürgen, danke, dann werde ich die Scripte noch auslagern.
Zu den Menüunterpunkten
Ich habe einen Tippfehler beim Anpassen der CSS vermutet, deshalb habe ich nochmal deine CSS kopiert und will sie neu anpassen.
Da ich das Menü aber nicht ganz oben auf meiner Seite stehen haben will, habe ich
#sitenav.withjs { position: absolute; }
#sitenav.withjs ul { position: absolute; }
in "#sitenav..... relative; }" geändert,
jetzt steht die Nav auf meiner Seite https://m-bubenheim.de/ zwar an der gewünschten Stelle, aber wenn man auf "Meine Schwerpunkte" klickt, öffnen sich die Menüunterpunkte einschließlich Hintergrundfarbe über die ganze Bildschirmbreite.
Hallo,
wie du schon gemerkt hast, hat die Änderung von absolute auf relative Nebenwirkungen. Versuch mal folgendes:
Leg um die Navi ein div:
<div id="umnavi">
<nav …> … </nav>
</div>
und ergänze das css um
#umnavi { position: relative; height: 3.5em; }
So reservierst du Platz für die Navigation, kannst sie aber beliebig positionieren.
Du musst dich auch noch um das Umschalten von breiter auf schmale Navigation kümmern. Dazu musst du im Script im Bereich
// Auf Seitenbreite reagieren und bei breiten Viewports Klasse "large" setzen
var format;
var mq = window.matchMedia("screen and (min-width:45em)");
mq.addListener(mq_handler);
mq_handler();
die min-width:45em
an deine Bedürfnisse anpassen.
Gruß
Jürgen
Hallo Jürgen, dank Deiner Tipps passt jetzt alles 😀
Ganz herzlichen Dank für Deine Hilfe!
Gruß Anita
@@atina
passt jetzt alles 😀
Nö, das tut es nicht.
In deinem Stylesheet steht:
A:link, A:active, A:visited, A:hover {
text-decoration: none;
color: #e6e6e6;
}
Damit setzst du die Textfarbe von Links auf die Hintergrundfarbe; Textlinks sind also nicht sichtbar. Das betrifft auch die Textalternative von Bildlinks wie du sie verwendest: wenn das Bild nicht geladen wird, ist der Alternativtext unsichtbar, der Link also so gut wie nicht vorhanden.
Außerdem ist die Textfarbe (currentColor
) der Defaultwert für outline-color
in Browsern, die invert
nicht unterstützen. Das hat zur Folge, dass im Firefox bei Tastaturnavigation der Rahmen um den gerade fokussierten Link nicht sichtbar ist, der Nutzer also nicht weiß, wo er sich befindet. (Chromia und WebKits sind davon nicht betroffen, da sie eine andere Kennzeichnung als outline
für :focus
verwenden.)
Lass die Angabe unbedingt weg! Außerdem kannst du outline: 1px solid #375add
nicht nur innerhalb von #sitenav
, sondern für alle Links gelten lassen.
Warum schreibst du überhaupt den Linktext in die Bilder hinein anstatt Text als Text auf die Seite zu setzen? Zum einen sieht das unschön aus; der Text erscheint verwaschen (auf hochauflösenden Bildschirmen, die heutzutage schon die Mehrheit der Nutzer haben dürfte).
Zum anderen ist das schlechter wartbar: Bei Textänderungen müsstest du ein Grafikprogramm verwenden.
Nochwas zum Markup:
<div class="container">
ist „bedauerlich bis ärgerlich“ – jedenfalls überflüssig.
<div class="eins">
<img src="../imga/logo.gif" class="bild1" alt="Martin Bubenheim Moderne Führungskonzepte" />
</div>
<div class="zwei">
<div id="umnavi">
<nav id="sitenav">
⋮
</nav>
</div>
</div>
Das alles wäre der <header>
. ☞ Seitenstrukturierung
Mindestens eins der beiden <div class="zwei">
und <div id="umnavi">
ist auch überflüssig; <div class="eins">
vermutlich auch.
Wie so verwendest du Klassen (eins
, zwei
, …), um Elemente eindeutig zu kennzeichnen, wofür doch IDs da sind?
<div class="zwoelf">
<p class="foot"><a class="style1" href="impressum.html" title="Impressum">Impressum</a> <a class="style1" href="datenschutz.html" title="Datenschutz">Datenschutz</a></p>
<p class="foot"></p>
</div>
Das wäre der <footer>
.
Was soll das leere <p class="foot"></p>
da? Und die ganzen
? Für Abstände ist CSS da.
Alles zwischen Header und Footer käme ins <main>
-Element.
Aber nochmal zurück zu ersterem:
<summary>
☰
</summary>
Da fehlt Text, der vom Screenreader wiedergegeben werden kann: „Menü“. Der kann visuell versteckt werden. (Warum eigentlich? Die Beschriftung hilft auch allen, die mit dem Hamburger-Icon nichts anzufangen wissen.)
Zu
siehe oben. Und vor </nav>
fehlt noch ein schließendes </ul>
.
Und warum verstümmelst du alle Umlaute? Das ist überhaupt nicht nötig.
LLAP 🖖
Hallo Gunnar,
so genau wollte ich meine Seite gar nicht "auseinandergenommen" haben😉
Zum Aufbau mit Grid hab ich mir ein Youtube-Video angeschaut, davon mehr oder weniger alles übernommen, dann noch was gelesen von 12 columns (oder waren es sogar mehr)?, die man unbedingt haben müsste, und dann einfach mal losgelegt und das auch noch mit nem Weaverslave-Editor 🙈
Nochwas zum Markup:
<div class="container">
ist „bedauerlich bis ärgerlich“ – jedenfalls überflüssig.>
Wer bedauert das oder wer ist darüber ärgerlich? Wahrscheinlich muss statt class id="..." stehen oder?
Warum schreibst du überhaupt den Linktext in die Bilder hinein anstatt Text als Text auf die Seite zu setzen? Zum einen sieht das unschön aus; der Text erscheint verwaschen (auf hochauflösenden Bildschirmen, die heutzutage schon die Mehrheit der Nutzer haben dürfte).<
Weil ich es mit css nicht hinkriege, Text mit Hintergrundfarbe teilweise in die Fotos reinzusetzen. M.E. geht das immer nur neben- oder untereinander. Das kriege ich mit Photoshop schneller hin.
Welche Vorteile hat es denn mit dem header, main und footer? Mit den divs klappt es doch auch.
Und warum verstümmelst du alle Umlaute? Das ist überhaupt nicht nötig.<
Da geh ich auf jeden Fall sicher, dass nicht diese kleinen schwarzen Rauten mit nem Fragezeichen drin auftauchen.
Das größere Problem ist, dass ich Bilder und nebenstehenden Text "gefloatet" habe. Weißt du eine Lösung, bei dem bei breiten Bildschirmen Text und Foto nebeneinander stehen und bei kleineren untereinander? (Mein grid-container hat folgende Angabe: grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));) Über eine Hilfe zu diesem Problem würde ich mich sehr freuen.
P.S. Es gibt einen schönen Handwerkerspruch: Silikon macht das schon - genauso verhält es sich mit dem 😉
Danke, Anita
@@atina
so genau wollte ich meine Seite gar nicht "auseinandergenommen" haben😉
Das gibt’s hier gratis dazu. 😆
… dann noch was gelesen von 12 columns (oder waren es sogar mehr)?, die man unbedingt haben müsste
Das ist Unsinn. (Es sei denn, man möchte sich völlig unnötigerweise den Beschränkungen von Bootstrap unterwerfen.)
<div class="container">
ist „bedauerlich bis ärgerlich“ – jedenfalls überflüssig.> Wer bedauert das oder wer ist darüber ärgerlich? Wahrscheinlich muss statt class id="..." stehen oder?
Nein. Das div
an sich ist überflüssig. Mit html
und body
stehen bereits zwei Container-Elemente zur Verfügung, die sich auch zum Stylen nutzen lassen.
☞ Beispiel (wenn auch schon etwas betagt)
Weil ich es mit css nicht hinkriege, Text mit Hintergrundfarbe teilweise in die Fotos reinzusetzen. M.E. geht das immer nur neben- oder untereinander.
Welche Vorteile hat es denn mit dem header, main und footer? Mit den divs klappt es doch auch.
Nutzern, die Seiten nicht (nur) visuell wahrnehmen, geben die Rollen, die Elementen wie header
, main
und footer
inherent sind, wertvolle Orientierungshilfen.
Außerdem macht es den Code besser lesbar, wenn man sprechende Elementtyp-Bezeichner hat anstatt unzählige div
s.
Und warum verstümmelst du alle Umlaute? Das ist überhaupt nicht nötig.<
Da geh ich auf jeden Fall sicher, dass nicht diese kleinen schwarzen Rauten mit nem Fragezeichen drin auftauchen.
Mit UTF-8 als Zeichencodierung bist du bereits auf der sicheren Seite.
Das größere Problem ist, dass ich Bilder und nebenstehenden Text "gefloatet" habe. Weißt du eine Lösung, bei dem bei breiten Bildschirmen Text und Foto nebeneinander stehen und bei kleineren untereinander? (Mein grid-container hat folgende Angabe: grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));)
Meinst du sowas in der Art?
LLAP 🖖
Hallo Anita,
nach deiner Antwort hab ich mir deine Seite auch noch mal angesehen:
https://validator.w3.org/nu/?doc=https%3A%2F%2Fm-bubenheim.de%2F
https://jigsaw.w3.org/css-validator/validator?uri=https%3A%2F%2Fm-bubenheim.de&profile=css3svg&usermedium=all&warning=1&vextwarning=&lang=de
Du solltest dich um die HTML-Warnung und die HTML- und CSS-Fehler kümmern.
Zum Thema Text über Bildern: Das würde ich mal mit Hintergrundbildern versuchen.
Zum Thema HTML: HTML ist eine Textauszeichnungssprache. Durch Setzen von Textbausteinen in die dafür vorgesehenen Elemente bekommt der Text einen Sinn. Gerade Besucher, die auf assistive Techniken angewiesen sind, und auch Suchmaschinen (!) freuen sich über die richtige Wahl der HTML-Elemente. Ein div ist in den meisten Fällen die falsche Wahl.
Du solltest dir die Seite auch mal mit einem Smartphone ansehen. Einige Texte, vor allem in Bildern, sind schon arg klein.
Gruß
Jürgen
Hallo Gunnar, hallo Jürgen,
danke für die ganzen Tipps 😀👍
Zum Thema HTML: HTML ist eine Textauszeichnungssprache. Durch Setzen von Textbausteinen in die dafür vorgesehenen Elemente bekommt der Text einen Sinn. Gerade Besucher, die auf assistive Techniken angewiesen sind, und auch Suchmaschinen (!) freuen sich über die richtige Wahl der HTML-Elemente. Ein div ist in den meisten Fällen die falsche Wahl.
... in dem Grid-Tutorial wimmelte es nur so von divs -
dann werd ich meine Seiten noch entsprechend überarbeiten.
https://validator.w3.org/nu/?doc=https%3A%2F%2Fm-bubenheim.de%2F
Die Überprüfung hab ich beim letzten Überarbeiten in der Tat verschludert😬
Den css-validator kannte ich bislang nicht.
Viele Grüße,
Anita
Hallo atina,
Ein div ist in den meisten Fällen die falsche Wahl.
... in dem Grid-Tutorial wimmelte es nur so von divs -
Ein div-Element ist ein Element ohne inhaltliche Bedeutung. In einem Tutorial kann es durchaus die richtige Wahl sein, weil es etwa um Dinge geht, die von der Wahl der Elemente unabhängig sind. Zum Beispiel kann man das grid-Konzept mit div-Elementen gut erklären.
Wenn ich aber eine Liste von Bildern habe, verwende ich dafür das HTML-Element ul
, wenn die Reihenfolge nicht wichtig ist oder ol
, wenn die Reihenfolge wichtig ist, etwa bei einer Bildergeschichte. Diese Liste kann ich nun mit grid als Raster anordnen, genauso wie ich das im Tutorial gelernt habe.
Bis demnächst
Matthias
@@JürgenB
wenn du mal am css oder am Javascript etwas ändern musst, musst du das dann nur an einer Stelle machen.
Wenn man den HTML-Code serverseitig generiert, lässt sich CSS und JavaScript von jeweils einer Stelle auch in die HTML-Ressourcen einfügen.
Auch werden CSS und Javascript wegen des Browsercaches nur einmal übertragen.
Die Abwägung, ob es günstiger ist, CSS und JavaScript ins HTML zu setzen und damit insb. beim ersten Seitenaufruf von der Website HTTP-Requests zu sparen, oder ob man beim ersten Seitenaufruf längere Wartezeit inkauf nimmt und bei zeitnah(!) folgenden Seitenaufrufen von der Website etwas spart, hängt auch vom Umfang des CSS- und JavaScript-Codes ab.
Ich habe auf meiner Seite das Seiten-css und das Menue-css sogar in einer Datei zusammengefasst.
Ja, das sollte man tun, um einen HTTP-Request zu sparen.
LLAP 🖖
@@JürgenB
https://wiki.selfhtml.org/wiki/JavaScript/Tutorials/zugängliche_Dropdown-Navigation
🤔 Wenn man da von „Seite 1.3“ zu „Bereich 2“ weitertabbt, sollte sich das Untermenü „Bereich 1“ dann nicht schließen?
LLAP 🖖
Hallo Gunnar,
https://wiki.selfhtml.org/wiki/JavaScript/Tutorials/zugängliche_Dropdown-Navigation
🤔 Wenn man da von „Seite 1.3“ zu „Bereich 2“ weitertabbt, sollte sich das Untermenü „Bereich 1“ dann nicht schließen?
die Frage habe ich mir auch gestellt und keine zwingende Antwort gefunden.
So wie es jetzt ist, kann man, wenn man „zuviel“ getabbt hat, mit Shift-Tab wieder zurück tabben.
Wenn man die Sub-Menüs beim Verlassen schließt, geht das nicht mehr, bzw. man muss sich merken, ob über oder durch das Submenü getabbt wurde.
Im Moment gefällt mir die erste Variante besser.
Gruß
Jürgen