HILFE bei der Erstellung eines langsam seitlich einslidernde Menue?
Wie in meiner Überschrift schon beschrieben möchte ich ein Menü bauen, das seitlich von rechts langsam einslidert. Für das Menü möchte ich <details> /<summary> verwenden.
So soll es mal aussehen:
Meine html-Struktur von der Navigation:
<nav id='sitenav' aria-labelledby='sitenav-label'>
<h2 id='sitenav-label' class='visually-hidden'>Site-Navigation</h2>
<details>
<summary>Menü</summary>
<ul>
<li aria-current='page'>
<details>
<summary>Impressum & rechtliches</summary>
<ul>
<li aria-current='sub-page' tabindex=0>
<details>
<summary>Impressum</summary>
<ul>
<li><a href=''>Kontakt</a></li>
<li><a href=''>Fotodokumentationen</a></li>
<li><a href=''>Links</a></li>
</ul>
</details>
</li>
<li><a href=''>Nutzungsbedingungen</a></li>
<li><a href=''>Datenschutz & Urheberrecht</a></li>
</ul>
</details>
</li>
<li><a href=''>Website Erika Mustermann</a></li>
<li><a href=''>Blog Max Mustermann</a></li>
<li><a href=''>VLog Erika Mostermann</a></li>
</ul>
</details>
</nav>
Der sichtbare Hamburger Button (mit den Pseudoelementen ::after und ::before bei details / summery) ist position: sticky;
Nun könnte mir jemand bitte zeigen wie ich nun mein <ul> von rechts langsam einslidern lasse. Stoppen soll das Untermenü dann links vom Button.
Es geht mir um das Prinzip wie man es macht. Kann mir dies bitte jemand an einem einfachen Beispiel zeigen?
1 Antwort
Mit HTML , Java und CSS würd ich das machen,
das wäre die HTML Struktur:
<nav id='sitenav' aria-labelledby='sitenav-label'>
<h2 id='sitenav-label' class='visually-hidden'>Site-Navigation</h2>
<details>
<summary>Menü</summary>
<ul>
<li aria-current='page'>
<details>
<summary>Impressum & rechtliches</summary>
<ul>
<li aria-current='sub-page' tabindex=0>
<details>
<summary>Impressum</summary>
<ul>
<li><a href=''>Kontakt</a></li>
<li><a href=''>Fotodokumentationen</a></li>
<li><a href=''>Links</a></li>
</ul>
</details>
</li>
<li><a href=''>Nutzungsbedingungen</a></li>
<li><a href=''>Datenschutz & Urheberrecht</a></li>
</ul>
</details>
</li>
<li><a href=''>Website Erika Mustermann</a></li>
<li><a href=''>Blog Max Mustermann</a></li>
<li><a href=''>VLog Erika Mostermann</a></li>
</ul>
</details>
</nav>
CSS:
nav #sitenav details > ul {
position: absolute;
right: -100%;
transition: right 0.5s ease;
}
nav #sitenav details[open] > ul {
right: 0;
}
nav details {
position: relative;
display: inline-block;
}
nav details summary::after {
content: '\25BC';
display: inline-block;
margin-left: 0.5em;
}
nav details[open] summary::after {
content: '\25B2';
}
Javaaaaaaa:
document.addEventListener('DOMContentLoaded', (event) => {
const detailsElements = document.querySelectorAll('nav #sitenav details');
detailsElements.forEach(details => {
details.addEventListener('toggle', () => {
const ul = details.querySelector('ul');
if (details.open) {
ul.style.right = '0';
} else {
ul.style.right = '-100%';
}
});
});
});
Die Verwendung von
<details>
und
<summary>
ist gut für Zugänglichkeit, da sie standardmäßig unterstützt werden und von Screenreadern gut interpretiert werden können. Sie bieten eine native Möglichkeit, Inhalte zu verstecken und anzuzeigen, was die Zugänglichkeit verbessert. Wenn jedoch zusätzliche Funktionen oder komplexe Interaktionen benötigt werden, könnten Buttons mit entsprechenden ARIA-Attributen besser geeignet sein.
Um ein sanftes Einsliden zu erreichen, kannst du CSS-Transitions verwenden.
body {
font-family: Arial, sans-serif;
}
.wrapper {
display: grid;
grid-template-columns: 1fr 3fr;
}
nav {
position: fixed;
top: 0;
left: -100%;
width: 300px;
height: 100%;
background: #333;
color: white;
overflow-y: auto;
transition: left 0.3s ease-in-out;
}
nav.open {
left: 0;
}
nav a {
color: white;
text-decoration: none;
display: block;
padding: 10px;
}
summary {
cursor: pointer;
list-style: none;
}
details[open] summary::after {
content: '\f00d';
}
details summary::after {
content: '\f0c9';
font-family: FontAwesome;
padding-left: 10px;
}
.visually-hidden {
position: absolute;
width: 1px;
height: 1px;
margin: -1px;
padding: 0;
overflow: hidden;
clip: rect(0, 0, 0, 0);
border: 0;
}
Javascript:
document.querySelector('summary').addEventListener('click', function() {
const nav = document.querySelector('nav');
nav.classList.toggle('open');
});
Die ARIA-Attribute sollten korrekt und sinnvoll verwendet werden.
<div class="wrapper">
<nav aria-labelledby="sitenav-label" id="sitenav">
<h2 id="sitenav-label" class="visually-hidden">Site-Navigation</h2>
<details aria-label="öffne Haupt-Navigations-Liste" aria-controls="main-navigations-list">
<summary>Menü</summary>
<ul id="main-navigations-list" class="main-menue">
<li aria-current="page">
<details>
<summary><a href="#">Impressum & rechtliches</a></summary>
<ul>
<li aria-current="sub-page" tabindex="0">
<details>
<summary><a href="#">Impressum</a></summary>
<ul>
<li><a href="#">Kontakt</a></li>
<li><a href="#">Fotodokumentationen</a></li>
<li><a href="#">Links</a></li>
</ul>
</details>
</li>
<li aria-current="sub-page" tabindex="0"><a href="#">Nutzungsbedingungen</a></li>
<li aria-current="sub-page" tabindex="0"><a href="#">Datenschutz & Urheberrecht</a></li>
</ul>
</details>
</li>
<li aria-current="page"><a href="#">Website Erika Mustermann</a></li>
<li aria-current="page"><a href="#">Blog Max Mustermann</a></li>
<li aria-current="page"><a href="#">VLog Erika Mustermann</a></li>
</ul>
</details>
</nav>
</div>
Falls Responsive ein Ding ist , CSS für responsive:
@media (max-width: 600px) {
.wrapper {
grid-template-columns: 1fr;
}
nav {
width: 100%;
}
}
Kurz und Knapp:
Verwendung von <details> und <summary>: Gut für Zugänglichkeit , aber wenn mehr Kontrolle benötigt wird , könnten Buttons mit ARIA-Attributes besser sein.
Smooth Sliding Effekt: CSS Transitions
ARIA-Attribute: Korrekt verwenden für bessere Zugänglichkeit.
Responsive: Media Queries für besser Darstellung auf allen Geräten.
Im Grunde alles GUT und PRIMA so, DANKE Dir, in meinem PEN funktioniert es auch komplett. Nur bei meiner Anwenderseite bei bplaced (LINK : http://misanthrop.bplaced.net/test/open-public/Testseite-V11b1__26-06-24.html ) will es nicht funktionieren.
Ja, die Anwendung ist wohl hier ein wenig komplizierter. Anscheinend müssen hier mehrere verschachtelte div-Boxen zu Anwendung kommen.
WEIL: Ich musste mir überlegen, was mache ich mit der Hauptnavigation:
...bei einem wirklich schmalen Browserfenster, also sagen wir mal alles was UNTER 20rem ist:
---- lasse ich offen und ohne jeglichen Button untereinander plan anzeigen
und das oberhalb vom "Inhalt"
--- Anmerkung dazu... , zum "Inhalt": Das ist ein Seiten internes Sprungmenü zu einem bestimmten nach Datum geordneten Artikel. Bisher habe ich noch keine bessere Bezeichnung dafür gefunden. Irgendeine Idee dafür?
Aber zurück zur Hauptnavigation, bei breiterem Browserfenster:
Noch " liegt es auf der Ebene von der ID="navigations", alternativ habe ich mir überlegt es "über" dem MAIN-Content zu legen:
.main-content-wrapper {
display: grid;
grid: "main-head main-head" auto
"navigations navigations" auto
"main-content main-content" 1fr
"main-footer main-footer" auto
/ minmax(0, auto) [main-nav-start] 5em [main-nav-end];
}
#navigations {
grid-area: navigations;
grid-column-end: main-nav;
}
#main-nav {
grid-area: navigations / main-nav;
position: relative;
outline: thin solid red;
margin: 0;
padding: 0;
z-index: 100;
}
Was ja auch möglich ist. Aber lassen wir es erstmals bei "navigations":
a) ... sollte das Hauptmenu sticky wie irgendwann mal der seitliche "Nach-Oben" Button sein... ist nur erstmal eine überlegung ob überhaupt? ...
b) ... wichtiger ist mir allerding: Das nach dem auszuklappenden Inhalt des Hamburger Menüs, das auszuklappende wohl position absolut sein muss und eben seitlich von rechts aus dem Rand herausslidet.
Ja, es darf Teile von Hauptcontent und auch anderes überragen wenn es ausgeklappt wird.
Ich fürchte, das man doch mehrere DIVs ineinanderschachten müsste, also schon die html-Struktur muss anders sein.
Solche Überlegungen übersteigen meine Synapsenbahnen.
Aber mal persönlich gefragt: Wäre für Dich das Hauptmenü schon zu komplex? ich meine, sollte man da schon Buttons mit entsprechenden ARIA-Attributen wählen? Hier mal ein PEN-Beispiel : https://codepen.io/Seb-B-/pen/wvbjMJm oder noch mehr im Rohbau : https://codepen.io/Seb-B-/pen/dyEeYpE
Was meinst Du? Ich weiß, das alles ist viel, aber hoffentlich kannst Du mir weiterhelfen.
Die HTML Struktur kann man auf jedenfall mit mehreren verschachtelten div boxen optimieren. Ich würde transform und transition benutzen für "sanftere" Animationen. Dann muss man natürlich auch sicherstellen das responsive ist.
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Testseite</title>
<link rel="stylesheet" href="style.css">
<script defer src="script.js"></script>
<style>
body {
font-family: Arial, sans-serif;
}
.wrapper {
display: grid;
grid-template-columns: 1fr 3fr;
}
nav {
position: fixed;
top: 0;
right: -300px; /* Start outside of the view */
width: 300px;
height: 100%;
background: #333;
color: white;
overflow-y: auto;
transition: transform 0.3s ease-in-out;
transform: translateX(100%); /* Slide in effect */
}
nav.open {
transform: translateX(0);
}
nav a {
color: white;
text-decoration: none;
display: block;
padding: 10px;
}
summary {
cursor: pointer;
list-style: none;
}
details[open] summary::after {
content: '\f00d';
}
details summary::after {
content: '\f0c9';
font-family: FontAwesome;
padding-left: 10px;
}
.visually-hidden {
position: absolute;
width: 1px;
height: 1px;
margin: -1px;
padding: 0;
overflow: hidden;
clip: rect(0, 0, 0, 0);
border: 0;
}
@media (max-width: 600px) {
.wrapper {
grid-template-columns: 1fr;
}
nav {
width: 100%;
}
}
</style>
</head>
<body>
<div class="wrapper">
<nav aria-labelledby="sitenav-label" id="sitenav">
<h2 id="sitenav-label" class="visually-hidden">Site-Navigation</h2>
<details aria-label="öffne Haupt-Navigations-Liste" aria-controls="main-navigations-list">
<summary>Menü</summary>
<ul id="main-navigations-list" class="main-menue">
<li aria-current="page">
<details>
<summary><a href="#">Impressum & rechtliches</a></summary>
<ul>
<li aria-current="sub-page" tabindex="0">
<details>
<summary><a href="#">Impressum</a></summary>
<ul>
<li><a href="#">Kontakt</a></li>
<li><a href="#">Fotodokumentationen</a></li>
<li><a href="#">Links</a></li>
</ul>
</details>
</li>
<li aria-current="sub-page" tabindex="0"><a href="#">Nutzungsbedingungen</a></li>
<li aria-current="sub-page" tabindex="0"><a href="#">Datenschutz & Urheberrecht</a></li>
</ul>
</details>
</li>
<li aria-current="page"><a href="#">Website Erika Mustermann</a></li>
<li aria-current="page"><a href="#">Blog Max Mustermann</a></li>
<li aria-current="page"><a href="#">VLog Erika Mustermann</a></li>
</ul>
</details>
</nav>
</div>
<script>
document.querySelector('summary').addEventListener('click', function() {
const nav = document.querySelector('nav');
nav.classList.toggle('open');
});
</script>
</body>
</html>
Also verstehe ich es richtig, das ich mein seitliches grid #main-nav
#main-nav {
grid-area: navigations / main-nav;
position: relative;
outline: thin solid red;
margin: 0;
padding: 0;
z-index: 100;
}
nocheinmal mit einem grid unterteile, wie Du das mit Deinem zusätzlichen wrapper machst?
http://misanthrop.bplaced.net/test/open-public/open-IMG/screen__1.jpg
http://misanthrop.bplaced.net/test/open-public/open-IMG/screen__2.jpg
So sieht es momentan bei mir aus oder direkt zur Ansicht:
http://misanthrop.bplaced.net/test/open-public/Testseite-V11b1__26-06-24.html
Ich werde es mal versuchen, mal sehen was passiert...
Wenn es den Effekt hat das rechts nach dem Hamburger Botton seitlich das Menü einslidert, dann wäre es prima. Ich fürchte aber eher nicht.
Habe es genauso eingesetzt mit der WIRKUNG = 0 Life-Beispiel: http://misanthrop.bplaced.net/test/open-public/Testseite-V11b2__27-06-24.html Bringt NIX, kein menü wird dort angezeigt. Irgendetwas ist da falsch.
Wobei bei dieser Vor-Version (von gestern) wenigstens noch etwas funktioniert : http://misanthrop.bplaced.net/test/open-public/Testseite-V11b1__26-06-24.html
Hi MasterFAQ, habe inzwischen ein wenig weitergearbeitet, soll ich den Link dazu nun posten? Melde Dich bitte mal... M.
Im Prinzip finde ich es gut, anscheinend funktioniert nichts mehr OHNE JS. Mit checkboxen arbeitet man ja nicht mehr da es "NICHT ausreichend Zugänglich" wäre und es dahingehend Probleme gibt.
Die eingefügten Dreiecke eingefügt mit Pseudoelementen hinter summary irritierten mich ein wenig, deshalb habe ich sie ersetzt mit '\f0c9' und '\f00d'. Kann man ja ganz leicht machen und ich denke Du weißt welche Zeichen es sind.
Aber, würdest du sagen das es richtig ist bei einem Hauptmenue mir details/summary zu arbeiten, ich meine schon wegen der Zugänglichkeit oder wäre es besser mit einem üblichen Button-Menue? Was sagst Du dazu?
Ich möchte es jedenfals "leicht" haben".
Leider kommt der Effekt des "smooth einsliderns" nicht so rüber, es geht sehr schnell und es wirkt nicht so das es von rechts einslidert.
Wie verhält es sich nun mit der aria-Beschriftung, reicht es so aus?
Oder müsste ich beim Startbutton:
Und entspechend bei den Sub-Menüs:
Habe da wohl zuviel darüber gelesen (w3.org). Aber zum Teil auch nicht ganz verstanden.
Wenn ich nun mit padding und margin das Menü gestalte, kann es ganz gut funktionieren.
Jedenfalls, anwenden möchte ich das Menü in einem zweispaltigen grid-raster, rechts der Content links, entsprechend schmaler der Münübutton.
Ich DANKE Dir schonmal.