Hallo einsiedler,
oookay. Ich musste jetzt erstmal die CSS-Visibility-Steuerung mit der hidden-Visibibility Steuerung konsolidieren. Und dann musste ich rausfinden, warum die Toggle-Buttons sich nicht ordentlich ausrichten ließen. Das lag an deinem margin-left für das main-Menü.
Als Script würde ich Dir dies empfehlen:
document.addEventListener('DOMContentLoaded', function () {
flyoutExtension('menu-toggle');
flyoutExtension('titel-toggle');
function flyoutExtension (toggleId) {
const toggle = document.getElementById(toggleId);
// aria-controls Attribut verwenden, um den Flyout-Inhalt zu finden
// Vorsicht: aria-controls darf grundsätzlich mehrere IDs enthalten, aber NICHT für das flyout-Widget.
const menu = document.getElementById(toggle.getAttribute("aria-controls"));
toggle.addEventListener('click', function() {
// Neuen expanded-Zustand aus altem Zustand herleiten. Kann ein bool sein.
const newExpanded = toggle.getAttribute('aria-expanded') !== 'true';
// Da das Verstecken erst im transitionend Event erfolgt, kann hier stumpf hidden auf false gesetzt werden
menu.hidden = false;
// Wichtig: aria-expanded erst in der nächsten Layout-Runde setzen, sonst funktioniert die Animation
// beim Einblenden nicht
requestAnimationFrame(function() {
toggle.setAttribute('aria-expanded', newExpanded);
});
});
menu.addEventListener("transitionend", function(endEvent) {
// Nach Transitionsende den hidden-Zustand an den expanded-Zustand anpassen
menu.hidden = toggle.getAttribute('aria-expanded') !== 'true';
});
// Korrekte Anfangswerte sicherstellen
toggle.setAttribute("aria-expanded", false);
menu.hidden = true;
}
});
Der transitionend Eventhandler verzögert das Verstecken des Flyout-Inhalts, bis die Animation zu Ende ist, und setzt den hidden-Zustand dann gemäß des aria-expanded-Zustand des Toggles. Das Gefummel mit requestAnimationFrame ist nötig, um das Setzen von aria-expanded (was per CSS die Transition auslöst) zu verzögern. Verzichtet man darauf, erfolgt bei mir keine Transition mehr; das Menü ist dann sofort sichtbar. Um das vom Toggle kontrollierte Flyout-Element zu finden, verwende ich das aria-controls Attribut. Sehr praktisch 😉.
Im CSS sieht das CSS für das Flyout-Widget so aus:
.flyout-box {
display: flex;
gap: var(--flyout-gap);
justify-content: end;
overflow: hidden;
}
.flyout-box > .flyout-toggle[aria-expanded] {
background: transparent;
color: transparent;
border: none;
margin: 0.7rem;
}
.flyout-box > .flyout-content {
width: var(--flyout-width);
margin-right: calc(0em - var(--flyout-gap, 0em) - var(--flyout-width));
transition: margin-right 0.85s;
}
.flyout-box [aria-expanded="true"] ~ .flyout-content {
margin-right: 0;
}
[hidden] { display: none !important; }
Mehr braucht's erstmal nicht. Die Sichtbarkeitssteuerung erfolgt nach Gunnars Vorschlag über das hidden-Attribut. Aber: Die zu verwendenden Maße müssen vorgegeben werden, dafür habe ich jetzt zwei custom-properties: --flyout-width für die Breite des Flyout-Inhalts und --flyout-gap, um optional einen Abstand zwischen Toggle und Inhalt zu setzen. Den muss das Flyout berücksichtigen.
Der Esel hat dann dieses CSS. --flyout-gap verwendet er nicht. FALLS du noch Abstand zwischen Esel und Link erzeugen willst, füge --flyout-gap analog zur main-nav hinzu. SETZE KEINE MARGINS für den Flyout-Inhalt. Ob man den Button hier als .flyout-toggle oder als button anspricht, ist relativ egal, aber man sollte es einheitlich tun. Die Farb- und Randeinstellungen für den Button sind 'raus, das macht schon das Flyout-CSS.
#icon-nav {
--flyout-width: 10em;
grid-column: 2 / 3;
justify-self: end;
display: flex;
align-items: center;
}
#icon-nav .flyout-toggle {
width: 5em;
height: 7.5em;
}
#icon-nav .flyout-toggle[aria-expanded] {
background-image: url(http://misanthrop.bplaced.net/test/open-public__july24/images/svg/esel-icon.png);
background-position: center;
background-repeat: no-repeat;
}
#icon-link {
font-size: 1.95rem;
padding: 0.4em 0.5em;
}
Schließlich die main-Navigation:
Der Hintergrund kann immer orange sein. Und der Abstand zwischen Button und Menü erfolgt über --flyout-gap, diese Variable wird vom CSS für das Flyout-Widget verwendet, um per gap-Eigenschaft einen Abstand zu erzeugen.
#main-nav {
--flyout-width: 10em;
--flyout-gap: 0.5em;
font-size: 1.55rem;
font-weight: bold;
}
#main-nav .flyout-toggle {
width: 45px;
height: 45px;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 9 9'%3E%3Cpath d='M1,2 h7 M1,5 h7 M1,8 h7' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E");
}
#main-nav [aria-expanded="true"] {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 9 9'%3E%3Cpath d='M2,2 l6,6 M8,2 l-6,6' fill='none' stroke='%23c82f04' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E");
}
#navi-span {
grid-column: 2 / 3;
display: flex;
justify-content: end;
width: 100%;
position: absolute;
}
#main-nav > ul {
margin-top: 0.6em;
padding: 0.35em 0.55em;
border: dashed 5px red;
background: orange;
}
Ich hoffe, damit passt es dann.
Rolf
sumpsi - posui - obstruxi