Skip to content

Commit 93b502a

Browse files
committed
Fix mobile navigation and improve UX
- Fixed burger menu z-index hierarchy (overlay: 998, nav: 1000, burger: 1001) - Moved sort dropdown from top bar to filters sidebar for better mobile layout - Added hover and focus states to sort dropdown - Improved mobile navigation with slide-out menu - Fixed click-through issues with mobile overlay - Enhanced mobile UX by grouping all filter/sort controls in sidebar
1 parent b01bf35 commit 93b502a

1 file changed

Lines changed: 202 additions & 28 deletions

File tree

.publish/templates/site/index.html

Lines changed: 202 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,44 @@
340340
font-weight: 400;
341341
}
342342

343+
/* Burger Menu */
344+
.burger-menu {
345+
display: none;
346+
flex-direction: column;
347+
justify-content: space-around;
348+
width: 2rem;
349+
height: 2rem;
350+
background: transparent;
351+
border: none;
352+
cursor: pointer;
353+
padding: 0;
354+
z-index: 1001;
355+
margin-left: auto;
356+
}
357+
358+
.burger-menu span {
359+
width: 2rem;
360+
height: 0.2rem;
361+
background: var(--text-primary);
362+
border-radius: 10px;
363+
transition: all 0.3s linear;
364+
position: relative;
365+
transform-origin: 1px;
366+
}
367+
368+
.burger-menu.active span:nth-child(1) {
369+
transform: rotate(45deg);
370+
}
371+
372+
.burger-menu.active span:nth-child(2) {
373+
opacity: 0;
374+
transform: translateX(20px);
375+
}
376+
377+
.burger-menu.active span:nth-child(3) {
378+
transform: rotate(-45deg);
379+
}
380+
343381
.header-nav {
344382
display: flex;
345383
align-items: center;
@@ -835,13 +873,9 @@
835873
gap: 0.75rem;
836874
}
837875

838-
.sort-label {
839-
color: var(--text-muted);
840-
font-size: 0.85rem;
841-
}
842-
843876
.sort-select {
844-
padding: 0.5rem 2rem 0.5rem 0.875rem;
877+
width: 100%;
878+
padding: 0.75rem 2.5rem 0.75rem 0.875rem;
845879
border-radius: 8px;
846880
border: 1px solid var(--border-color);
847881
background: var(--bg-secondary);
@@ -853,11 +887,17 @@
853887
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23606070' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
854888
background-repeat: no-repeat;
855889
background-position: right 0.75rem center;
890+
transition: all var(--transition-base);
891+
}
892+
893+
.sort-select:hover {
894+
border-color: var(--accent-primary);
856895
}
857896

858897
.sort-select:focus {
859898
outline: none;
860899
border-color: var(--accent-primary);
900+
box-shadow: 0 0 0 3px var(--shadow-color);
861901
}
862902

863903
.view-toggle {
@@ -999,31 +1039,98 @@
9991039
}
10001040
}
10011041

1002-
/* Mobile navigation responsive fixes */
1003-
@media (max-width: 640px) {
1042+
/* Mobile burger menu and navigation */
1043+
@media (max-width: 768px) {
1044+
/* Show burger menu on mobile */
1045+
.burger-menu {
1046+
display: flex;
1047+
}
1048+
1049+
/* Hide and transform navigation into slide-out menu */
10041050
.header-nav {
1005-
gap: 0.375rem;
1051+
position: fixed;
1052+
top: 0;
1053+
right: -100%;
1054+
height: 100vh;
1055+
width: 280px;
1056+
background: var(--bg-secondary);
1057+
flex-direction: column;
1058+
align-items: stretch;
1059+
gap: 0;
1060+
padding: 5rem 1.5rem 2rem;
1061+
box-shadow: -4px 0 20px var(--shadow-color);
1062+
transition: right 0.3s ease-in-out;
1063+
z-index: 1000;
1064+
overflow-y: auto;
1065+
}
1066+
1067+
.header-nav.active {
1068+
right: 0;
10061069
}
10071070

10081071
.nav-btn {
1009-
padding: 0.5rem 0.75rem;
1010-
font-size: 0.85rem;
1072+
padding: 1rem;
1073+
font-size: 1rem;
1074+
width: 100%;
1075+
justify-content: flex-start;
1076+
border-radius: 8px;
1077+
margin-bottom: 0.5rem;
10111078
}
10121079

10131080
.nav-btn .count {
1014-
font-size: 0.7rem;
1015-
padding: 0.1rem 0.4rem;
1081+
margin-left: auto;
1082+
}
1083+
1084+
.github-link {
1085+
padding: 1rem;
1086+
width: 100%;
1087+
justify-content: flex-start;
1088+
border-radius: 8px;
1089+
margin-bottom: 0.5rem;
10161090
}
10171091

10181092
.github-link span {
1019-
display: none;
1093+
display: inline;
10201094
}
10211095

1022-
.github-link {
1023-
padding: 0.5rem;
1096+
.theme-switcher {
1097+
width: 100%;
1098+
margin-top: 0.5rem;
1099+
}
1100+
1101+
.theme-btn {
1102+
width: 100%;
1103+
padding: 1rem;
1104+
justify-content: center;
1105+
}
1106+
1107+
.theme-dropdown {
1108+
position: static;
1109+
width: 100%;
1110+
margin-top: 0.5rem;
10241111
}
10251112
}
10261113

1114+
/* Mobile overlay for burger menu */
1115+
.mobile-overlay {
1116+
display: none;
1117+
position: fixed;
1118+
top: 0;
1119+
left: 0;
1120+
width: 100%;
1121+
height: 100%;
1122+
background: rgba(0, 0, 0, 0.5);
1123+
z-index: 998;
1124+
opacity: 0;
1125+
transition: opacity 0.3s ease-in-out;
1126+
pointer-events: none;
1127+
}
1128+
1129+
.mobile-overlay.active {
1130+
display: block;
1131+
opacity: 1;
1132+
}
1133+
10271134
/* Project card */
10281135
.project-card {
10291136
background: var(--bg-card);
@@ -1851,15 +1958,25 @@
18511958
<body>
18521959
<div class="bg-gradient"></div>
18531960

1961+
<!-- Mobile Menu Overlay -->
1962+
<div class="mobile-overlay" id="mobile-overlay"></div>
1963+
18541964
<!-- Header -->
18551965
<header class="header">
18561966
<div class="header-content">
18571967
<a href="#" class="logo">
18581968
<div class="logo-icon">☁️</div>
18591969
<div class="logo-text">CloudProjects <span>Index</span></div>
18601970
</a>
1861-
1862-
<nav class="header-nav">
1971+
1972+
<!-- Burger Menu Button (Mobile Only) -->
1973+
<button class="burger-menu" id="burger-menu" aria-label="Toggle menu">
1974+
<span></span>
1975+
<span></span>
1976+
<span></span>
1977+
</button>
1978+
1979+
<nav class="header-nav" id="header-nav">
18631980
<button class="nav-btn active" data-view="all">
18641981
All Projects
18651982
<span class="count" id="all-count">0</span>
@@ -2006,6 +2123,20 @@
20062123
</div>
20072124
</div>
20082125

2126+
<!-- Sort -->
2127+
<div class="sidebar-section">
2128+
<div class="sidebar-title">Sort By</div>
2129+
<select class="sort-select" id="sort-select">
2130+
<option value="name-asc">Name (A-Z)</option>
2131+
<option value="name-desc">Name (Z-A)</option>
2132+
<option value="difficulty-asc">Difficulty (Easy first)</option>
2133+
<option value="difficulty-desc">Difficulty (Hard first)</option>
2134+
<option value="duration-asc">Duration (Quick first)</option>
2135+
<option value="duration-desc">Duration (Long first)</option>
2136+
<option value="provider">Provider</option>
2137+
</select>
2138+
</div>
2139+
20092140
<!-- Categories -->
20102141
<div class="sidebar-section">
20112142
<div class="sidebar-title">Categories</div>
@@ -2052,16 +2183,6 @@
20522183
</svg>
20532184
</button>
20542185
</div>
2055-
<span class="sort-label">Sort by</span>
2056-
<select class="sort-select" id="sort-select">
2057-
<option value="name-asc">Name (A-Z)</option>
2058-
<option value="name-desc">Name (Z-A)</option>
2059-
<option value="difficulty-asc">Difficulty (Easy first)</option>
2060-
<option value="difficulty-desc">Difficulty (Hard first)</option>
2061-
<option value="duration-asc">Duration (Quick first)</option>
2062-
<option value="duration-desc">Duration (Long first)</option>
2063-
<option value="provider">Provider</option>
2064-
</select>
20652186
</div>
20662187
</div>
20672188

@@ -2750,13 +2871,66 @@ <h3 class="learning-path-title">${path.name}</h3>
27502871
loadTheme();
27512872
}
27522873

2874+
function initBurgerMenu() {
2875+
const burgerBtn = document.getElementById('burger-menu');
2876+
const headerNav = document.getElementById('header-nav');
2877+
const mobileOverlay = document.getElementById('mobile-overlay');
2878+
2879+
function toggleMenu() {
2880+
burgerBtn.classList.toggle('active');
2881+
headerNav.classList.toggle('active');
2882+
mobileOverlay.classList.toggle('active');
2883+
document.body.style.overflow = headerNav.classList.contains('active') ? 'hidden' : '';
2884+
}
2885+
2886+
function closeMenu() {
2887+
burgerBtn.classList.remove('active');
2888+
headerNav.classList.remove('active');
2889+
mobileOverlay.classList.remove('active');
2890+
document.body.style.overflow = '';
2891+
}
2892+
2893+
// Toggle menu on burger button click
2894+
burgerBtn.addEventListener('click', (e) => {
2895+
e.stopPropagation();
2896+
toggleMenu();
2897+
});
2898+
2899+
// Close menu when clicking outside of navigation
2900+
document.addEventListener('click', (e) => {
2901+
if (headerNav.classList.contains('active')) {
2902+
// Check if click is outside both burger button and navigation menu
2903+
if (!headerNav.contains(e.target) && !burgerBtn.contains(e.target)) {
2904+
closeMenu();
2905+
}
2906+
}
2907+
});
2908+
2909+
// Close menu when navigation items are clicked (except theme switcher)
2910+
document.querySelectorAll('.nav-btn').forEach(btn => {
2911+
btn.addEventListener('click', () => {
2912+
if (window.innerWidth <= 768) {
2913+
closeMenu();
2914+
}
2915+
});
2916+
});
2917+
2918+
// Close menu on window resize if screen becomes larger
2919+
window.addEventListener('resize', () => {
2920+
if (window.innerWidth > 768) {
2921+
closeMenu();
2922+
}
2923+
});
2924+
}
2925+
27532926
// =====================================================
27542927
// INITIALIZATION
27552928
// =====================================================
27562929

27572930
function init() {
27582931
loadFromStorage();
27592932
initThemeSwitcher();
2933+
initBurgerMenu();
27602934

27612935
// Render initial state
27622936
updateProviderCounts();

0 commit comments

Comments
 (0)