style: polish mobile nav menu for better UX

This commit is contained in:
2026-02-09 15:56:10 +08:00
parent e084973c52
commit 64ed7bb140

View File

@@ -16,6 +16,14 @@ function getNavLinkClass(itemId: string) {
}
return `${baseClass} text-gray-600 hover:text-primary hover:bg-primary/10`;
}
function getMobileNavLinkClass(itemId: string) {
const baseClass = 'flex flex-col items-center justify-center py-2 px-2 min-w-[4.5rem] rounded-xl transition-all duration-300';
if (itemId === activeNav) {
return `${baseClass} bg-primary text-white`;
}
return `${baseClass} text-gray-600 hover:bg-primary/10`;
}
---
<html lang="zh-CN">
@@ -28,7 +36,7 @@ function getNavLinkClass(itemId: string) {
</head>
<body class="font-inter text-dark bg-slate-50">
<header id="navbar" class="fixed w-full top-0 z-50 transition-all duration-300 bg-white/95 backdrop-blur-md shadow-lg border-b border-gray-100">
<div class="max-w-7xl mx-auto px-4 lg:px-0 py-3 flex items-center justify-between">
<div class="max-w-7xl mx-auto px-4 lg:px-0 py-3 flex items-center justify-between hidden lg:flex">
<a href="/" class="flex items-center space-x-3">
<img src="/img/logo.png" alt="浙江贝凡 Logo" class="h-10 w-auto">
</a>
@@ -46,41 +54,109 @@ function getNavLinkClass(itemId: string) {
<i class="fa fa-phone"></i>
<span>立即咨询</span>
</a>
<button id="menu-toggle" class="lg:hidden text-gray-800 focus:outline-none p-3 rounded-xl hover:bg-gray-100 border border-gray-200">
<i class="fa fa-bars text-xl"></i>
</button>
</div>
<div id="mobile-menu" class="hidden lg:hidden bg-white border-t border-gray-200 shadow-xl pb-4">
<div class="max-w-7xl mx-auto px-4 pt-4 space-y-2">
<!-- Mobile Header - First Row -->
<div id="mobile-header-row" class="lg:hidden flex items-center justify-between px-4 py-3 bg-white border-b border-gray-100">
<a href="/" class="flex items-center space-x-2">
<img src="/img/logo.png" alt="浙江贝凡 Logo" class="h-8 w-auto">
</a>
</div>
</header>
<!-- Mobile Navigation Row - Separate from header -->
<div id="mobile-nav-container" class="lg:hidden fixed left-0 right-0 z-40 bg-gray-50 border-b border-gray-200 transition-all duration-300" style="top: 60px;">
<div class="flex items-center justify-between px-2 py-2">
<div class="flex items-center gap-1 overflow-x-auto no-scrollbar">
{
navItems.map(item => (
<a href={item.href} class={`flex items-center gap-4 p-4 rounded-xl transition-all ${item.id === activeNav ? 'bg-primary/10 border-2 border-primary' : 'hover:bg-gray-50 border-2 border-transparent'}`}>
<div class={`w-12 h-12 rounded-xl flex items-center justify-center ${item.id === activeNav ? 'bg-primary' : 'bg-gray-100'}`}>
<i class={`fa ${item.icon} text-xl ${item.id === activeNav ? 'text-white' : 'text-gray-600'}`}></i>
</div>
<div class="flex-1">
<span class={`text-base font-bold block ${item.id === activeNav ? 'text-primary' : 'text-gray-800'}`}>{item.label}</span>
</div>
{
item.id === activeNav && <i class="fa fa-check-circle text-primary text-xl"></i>
}
<a href={item.href} class={getMobileNavLinkClass(item.id)}>
<i class={`fa ${item.icon} text-lg mb-1`}></i>
<span class="text-xs font-medium whitespace-nowrap">{item.label}</span>
</a>
))
}
<a href="/#contact-info" class="flex items-center gap-4 p-4 rounded-xl bg-primary text-white mt-4">
<i class="fa fa-phone text-xl"></i>
<span class="text-base font-bold">立即咨询</span>
<i class="fa fa-arrow-right ml-auto"></i>
</div>
<a href="/#contact-info" class="flex items-center justify-center py-2 px-3 bg-primary text-white rounded-xl min-w-[3rem] ml-1">
<i class="fa fa-phone text-lg"></i>
</a>
</div>
</div>
</header>
</div>
<!-- Spacer for mobile to prevent content overlap (header 3.5rem + nav 2.5rem) -->
<div class="lg:hidden h-[6rem] transition-all duration-300"></div>
<slot />
<Footer />
<button id="back-to-top" class="fixed bottom-8 right-8 w-12 h-12 bg-primary rounded-full flex items-center justify-center text-white shadow-lg opacity-0 invisible transition-all duration-300 hover:bg-primary/90">
<button id="back-to-top" class="fixed bottom-8 right-8 w-12 h-12 bg-primary rounded-full flex items-center justify-center text-white shadow-lg opacity-0 invisible transition-all duration-300 hover:bg-primary/90 z-50">
<i class="fa fa-arrow-up"></i>
</button>
<script is:inline src="/js/script.js"></script>
<script>
// Mobile navigation scroll behavior
(function() {
var navContainer = document.getElementById('mobile-nav-container');
var headerRow = document.getElementById('mobile-header-row');
var spacer = document.querySelector('.lg\\:hidden.h-\\[6rem\\]');
var lastScrollTop = 0;
var scrollThreshold = 50;
// Set correct top position based on actual header height
function updateNavPosition() {
if (headerRow && navContainer && window.innerWidth < 1024) {
var headerHeight = headerRow.getBoundingClientRect().height;
navContainer.style.top = headerHeight + 'px';
}
}
// Update on load and resize
updateNavPosition();
window.addEventListener('resize', updateNavPosition);
window.addEventListener('load', updateNavPosition);
window.addEventListener('scroll', function() {
var scrollTop = window.pageYOffset || document.documentElement.scrollTop;
// Only apply on mobile
if (window.innerWidth >= 1024) return;
if (scrollTop > lastScrollTop && scrollTop > scrollThreshold) {
// Scrolling down - hide second row
if (navContainer) {
navContainer.style.transform = 'translateY(-100%)';
navContainer.style.opacity = '0';
}
// Reduce spacer height
if (spacer) {
(spacer as HTMLElement).style.height = '3.5rem';
}
} else {
// Scrolling up - show second row
if (navContainer) {
navContainer.style.transform = 'translateY(0)';
navContainer.style.opacity = '1';
}
// Restore spacer height
if (spacer) {
(spacer as HTMLElement).style.height = '6rem';
}
}
lastScrollTop = scrollTop;
}, { passive: true });
})();
</script>
<style>
.no-scrollbar {
-ms-overflow-style: none;
scrollbar-width: none;
}
.no-scrollbar::-webkit-scrollbar {
display: none;
}
</style>
</body>
</html>