Antwort an „Rolf B“ verfassen

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
freiwillig, öffentlich sichtbar
freiwillig, öffentlich sichtbar
freiwillig, öffentlich sichtbar

Ihre Identität in einem Cookie zu speichern erlaubt es Ihnen, Ihre Beiträge zu editieren. Außerdem müssen Sie dann bei neuen Beiträgen nicht mehr die Felder Name, E-Mail und Homepage ausfüllen.

abbrechen