mirror of
https://github.com/kevinveenbirkenbach/homepage.veen.world.git
synced 2025-01-15 19:23:58 +01:00
Optimized menus for smartphone
This commit is contained in:
parent
1eb673454c
commit
573a3be360
@ -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>
|
||||||
|
Loading…
Reference in New Issue
Block a user