mirror of
				https://github.com/kevinveenbirkenbach/homepage.veen.world.git
				synced 2025-11-04 09:27:58 +00:00 
			
		
		
		
	Optimized menus for smartphone
This commit is contained in:
		@@ -502,6 +502,7 @@ navigation:
 | 
				
			|||||||
    - link: accounts
 | 
					    - link: accounts
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
  - name: Imprint
 | 
					  - name: Imprint
 | 
				
			||||||
 | 
					    description: Check out the imprint information
 | 
				
			||||||
    icon:
 | 
					    icon:
 | 
				
			||||||
        class: fa-solid fa-scale-balanced
 | 
					        class: fa-solid fa-scale-balanced
 | 
				
			||||||
    url: https://s.veen.world/imprint
 | 
					    url: https://s.veen.world/imprint
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -78,66 +78,39 @@ h3.card-title {
 | 
				
			|||||||
h3.footer-title {
 | 
					h3.footer-title {
 | 
				
			||||||
  font-size: 1.3em;
 | 
					  font-size: 1.3em;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					/* Dropdown-Menüs verstecken */
 | 
				
			||||||
/* Dropdown menu styles */
 | 
					 | 
				
			||||||
.dropdown-menu {
 | 
					.dropdown-menu {
 | 
				
			||||||
  position: absolute !important;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.dropdown-menu-footer {
 | 
					 | 
				
			||||||
  position: absolute !important;
 | 
					 | 
				
			||||||
  top: auto !important;
 | 
					 | 
				
			||||||
  bottom: 100%; /* Positions the menu above the trigger */
 | 
					 | 
				
			||||||
  transform: translateY(-10px); /* Optional spacing for smoother appearance */
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Dropdown submenu styles */
 | 
					 | 
				
			||||||
.dropdown-submenu {
 | 
					 | 
				
			||||||
  position: relative;
 | 
					 | 
				
			||||||
  list-style: none;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.dropdown-submenu > .dropdown-menu {
 | 
					 | 
				
			||||||
  position: absolute;
 | 
					 | 
				
			||||||
  top: 0;
 | 
					 | 
				
			||||||
  left: 100%; /* Default position: open to the right */
 | 
					 | 
				
			||||||
  margin-top: -1px;
 | 
					 | 
				
			||||||
  z-index: 1050;
 | 
					 | 
				
			||||||
  transition: opacity 0.3s ease-in-out; /* Smooth opacity transition */
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Handle collapse behavior for dropdowns */
 | 
					 | 
				
			||||||
.dropdown-menu.collapse {
 | 
					 | 
				
			||||||
  display: none;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.dropdown-menu.collapse.show {
 | 
					 | 
				
			||||||
  display: block;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Ensure submenus are hidden by default */
 | 
					 | 
				
			||||||
.dropdown-submenu .dropdown-menu {
 | 
					 | 
				
			||||||
  display: none;
 | 
					  display: none;
 | 
				
			||||||
  opacity: 0;
 | 
					  opacity: 0;
 | 
				
			||||||
  transition: opacity 0.3s ease-in-out;
 | 
					  visibility: hidden;
 | 
				
			||||||
  position: absolute;
 | 
					  transition: opacity 0.3s ease, visibility 0.3s ease;
 | 
				
			||||||
  left: 100%;
 | 
					 | 
				
			||||||
  top: 0;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Show submenu on hover */
 | 
					/* Dropdown-Menü beim Hover anzeigen */
 | 
				
			||||||
 | 
					.nav-item.dropdown:hover > .dropdown-menu,
 | 
				
			||||||
.dropdown-submenu:hover > .dropdown-menu {
 | 
					.dropdown-submenu:hover > .dropdown-menu {
 | 
				
			||||||
  display: block;
 | 
					  display: block;
 | 
				
			||||||
  opacity: 1;
 | 
					  opacity: 1;
 | 
				
			||||||
 | 
					  visibility: visible;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Ensure submenu remains visible when hovered over */
 | 
					/* Dropdown-Menü bei der Klasse "open" anzeigen */
 | 
				
			||||||
.dropdown-submenu:hover > .dropdown-menu:hover {
 | 
					.nav-item.dropdown.open > .dropdown-menu,
 | 
				
			||||||
 | 
					.dropdown-submenu.open > .dropdown-menu {
 | 
				
			||||||
  display: block;
 | 
					  display: block;
 | 
				
			||||||
  opacity: 1;
 | 
					  opacity: 1;
 | 
				
			||||||
 | 
					  visibility: visible;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Handle dynamic submenu positioning */
 | 
					/* Positionierung von Submenüs */
 | 
				
			||||||
.dropdown-submenu > .dropdown-menu[style*="right: 100%"] {
 | 
					.dropdown-submenu > .dropdown-menu {
 | 
				
			||||||
  left: auto; /* Override left position for leftward opening */
 | 
					  position: absolute;
 | 
				
			||||||
 | 
					  top: 0;
 | 
				
			||||||
 | 
					  left: 100%; /* Rechts ausklappen */
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.dropdown-submenu.open > .dropdown-menu {
 | 
				
			||||||
 | 
					  display: block;
 | 
				
			||||||
 | 
					  opacity: 1;
 | 
				
			||||||
 | 
					  visibility: visible;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,41 +1,53 @@
 | 
				
			|||||||
document.addEventListener('DOMContentLoaded', () => {
 | 
					document.addEventListener('DOMContentLoaded', () => {
 | 
				
			||||||
    const dropdownSubmenus = document.querySelectorAll('.dropdown-submenu');
 | 
					  const menuItems = document.querySelectorAll('.nav-item.dropdown, .dropdown-submenu');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    dropdownSubmenus.forEach(submenu => {
 | 
					  menuItems.forEach(item => {
 | 
				
			||||||
        let timeout;
 | 
					    let timeout;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Zeige das Submenü beim Hover
 | 
					    // Öffnen beim Hovern
 | 
				
			||||||
        submenu.addEventListener('mouseenter', () => {
 | 
					    item.addEventListener('mouseenter', () => {
 | 
				
			||||||
            clearTimeout(timeout);
 | 
					      clearTimeout(timeout);
 | 
				
			||||||
            const menu = submenu.querySelector('.dropdown-menu');
 | 
					      openMenu(item);
 | 
				
			||||||
            if (menu) {
 | 
					 | 
				
			||||||
                // Dynamische Positionierung
 | 
					 | 
				
			||||||
                const rect = menu.getBoundingClientRect();
 | 
					 | 
				
			||||||
                const viewportWidth = window.innerWidth;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                // Überprüfen, ob Platz nach rechts ist, sonst nach links öffnen
 | 
					 | 
				
			||||||
                if (rect.right > viewportWidth) {
 | 
					 | 
				
			||||||
                    menu.style.left = 'auto';
 | 
					 | 
				
			||||||
                    menu.style.right = '100%';
 | 
					 | 
				
			||||||
                } else {
 | 
					 | 
				
			||||||
                    menu.style.left = '100%';
 | 
					 | 
				
			||||||
                    menu.style.right = 'auto';
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                menu.style.display = 'block';
 | 
					 | 
				
			||||||
                menu.style.opacity = '1';
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Verstecke das Submenü nach 0.5 Sekunden
 | 
					 | 
				
			||||||
        submenu.addEventListener('mouseleave', () => {
 | 
					 | 
				
			||||||
            const menu = submenu.querySelector('.dropdown-menu');
 | 
					 | 
				
			||||||
            if (menu) {
 | 
					 | 
				
			||||||
                timeout = setTimeout(() => {
 | 
					 | 
				
			||||||
                    menu.style.display = 'none';
 | 
					 | 
				
			||||||
                    menu.style.opacity = '0';
 | 
					 | 
				
			||||||
                }, 500); // 0.5 Sekunden Verzögerung
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Verzögertes Schließen beim Verlassen
 | 
				
			||||||
 | 
					    item.addEventListener('mouseleave', () => {
 | 
				
			||||||
 | 
					      timeout = setTimeout(() => closeMenu(item), 500);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Offen lassen beim Klicken
 | 
				
			||||||
 | 
					    item.addEventListener('click', (e) => {
 | 
				
			||||||
 | 
					      e.stopPropagation(); // Verhindert das Schließen von Menüs bei Klick
 | 
				
			||||||
 | 
					      if (item.classList.contains('open')) {
 | 
				
			||||||
 | 
					        closeMenu(item);
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        openMenu(item);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Globale Klick-Listener, um Menüs zu schließen, wenn außerhalb geklickt wird
 | 
				
			||||||
 | 
					  document.addEventListener('click', () => {
 | 
				
			||||||
 | 
					    menuItems.forEach(item => closeMenu(item));
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function openMenu(item) {
 | 
				
			||||||
 | 
					    item.classList.add('open');
 | 
				
			||||||
 | 
					    const submenu = item.querySelector('.dropdown-menu');
 | 
				
			||||||
 | 
					    if (submenu) {
 | 
				
			||||||
 | 
					      submenu.style.display = 'block';
 | 
				
			||||||
 | 
					      submenu.style.opacity = '1';
 | 
				
			||||||
 | 
					      submenu.style.visibility = 'visible';
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function closeMenu(item) {
 | 
				
			||||||
 | 
					    item.classList.remove('open');
 | 
				
			||||||
 | 
					    const submenu = item.querySelector('.dropdown-menu');
 | 
				
			||||||
 | 
					    if (submenu) {
 | 
				
			||||||
 | 
					      submenu.style.display = 'none';
 | 
				
			||||||
 | 
					      submenu.style.opacity = '0';
 | 
				
			||||||
 | 
					      submenu.style.visibility = 'hidden';
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
    {% for subitem in subitems %}
 | 
					    {% for subitem in subitems %}
 | 
				
			||||||
        {% if subitem.subitems %}
 | 
					        {% if subitem.subitems %}
 | 
				
			||||||
            <li class="dropdown-submenu position-relative">
 | 
					            <li class="dropdown-submenu position-relative">
 | 
				
			||||||
                <a class="dropdown-item dropdown-toggle" href="#" title="{{ subitem.description }}">
 | 
					                <a class="dropdown-item dropdown-toggle" title="{{ subitem.description }}">
 | 
				
			||||||
                    {% if subitem.icon is defined and subitem.icon.class is defined %}
 | 
					                    {% if subitem.icon is defined and subitem.icon.class is defined %}
 | 
				
			||||||
                        <i class="{{ subitem.icon.class }}"></i> {{ subitem.name }}
 | 
					                        <i class="{{ subitem.icon.class }}"></i> {{ subitem.name }}
 | 
				
			||||||
                    {% else %}
 | 
					                    {% else %}
 | 
				
			||||||
@@ -33,8 +33,7 @@
 | 
				
			|||||||
        {% endif %}
 | 
					        {% endif %}
 | 
				
			||||||
    {% endfor %}
 | 
					    {% endfor %}
 | 
				
			||||||
{% endmacro %}
 | 
					{% endmacro %}
 | 
				
			||||||
 | 
					<!-- Navigation Bar -->
 | 
				
			||||||
 <!-- Navigation Bar -->
 | 
					 | 
				
			||||||
<nav class="navbar navbar-expand-lg navbar-light bg-light">
 | 
					<nav class="navbar navbar-expand-lg navbar-light bg-light">
 | 
				
			||||||
    <div class="container-fluid">
 | 
					    <div class="container-fluid">
 | 
				
			||||||
        <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav{{menu_type}}" aria-controls="navbarNav{{menu_type}}" aria-expanded="false" aria-label="Toggle navigation">
 | 
					        <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav{{menu_type}}" aria-controls="navbarNav{{menu_type}}" aria-expanded="false" aria-label="Toggle navigation">
 | 
				
			||||||
@@ -53,14 +52,14 @@
 | 
				
			|||||||
                    {% else %}
 | 
					                    {% else %}
 | 
				
			||||||
                        <!-- Dropdown Menu -->
 | 
					                        <!-- Dropdown Menu -->
 | 
				
			||||||
                        <li class="nav-item dropdown">
 | 
					                        <li class="nav-item dropdown">
 | 
				
			||||||
                            <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown{{ loop.index }}" role="button" data-bs-toggle="dropdown" data-bs-display="dynamic" data-popper-placement="top" title="{{ item.description }}" aria-expanded="false">
 | 
					                            <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown{{ loop.index }}" role="button" data-bs-toggle="dropdown" aria-expanded="false">
 | 
				
			||||||
                                {% if item.icon is defined and item.icon.class is defined %}
 | 
					                                {% if item.icon is defined and item.icon.class is defined %}
 | 
				
			||||||
                                    <i class="{{ item.icon.class }}" data-bs-toggle="tooltip"></i> {{ item.name }}
 | 
					                                    <i class="{{ item.icon.class }}"></i> {{ item.name }}
 | 
				
			||||||
                                {% else %}
 | 
					                                {% else %}
 | 
				
			||||||
                                    <p>Missing icon in item: {{ item }}</p>
 | 
					                                    <p>Missing icon in item: {{ item }}</p>
 | 
				
			||||||
                                {% endif %}
 | 
					                                {% endif %}
 | 
				
			||||||
                            </a>
 | 
					                            </a>
 | 
				
			||||||
                            <ul class="dropdown-menu dropdown-menu-{{menu_type}}" aria-labelledby="navbarDropdown{{ loop.index }}">
 | 
					                            <ul class="dropdown-menu">
 | 
				
			||||||
                                {{ render_subitems(item.subitems) }}
 | 
					                                {{ render_subitems(item.subitems) }}
 | 
				
			||||||
                            </ul>
 | 
					                            </ul>
 | 
				
			||||||
                        </li>
 | 
					                        </li>
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user