Skip to content

Commit 4f15808

Browse files
committed
improve mobile navbar rendering
1 parent f0553fe commit 4f15808

File tree

2 files changed

+173
-25
lines changed

2 files changed

+173
-25
lines changed

src/_layouts/base.njk

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,70 @@
2727
<div class="nav-logo">
2828
<a href="/"><span class="logo-prefix">≡</span>codeGROOVE</a>
2929
</div>
30+
<button class="nav-hamburger" aria-label="Toggle menu" aria-expanded="false">
31+
<span class="hamburger-line"></span>
32+
<span class="hamburger-line"></span>
33+
<span class="hamburger-line"></span>
34+
</button>
3035
<ul class="nav-links">
3136
<li><a href="/about/">about</a></li>
32-
<li><a href="/products/ready-to-review/">products</a></li>
37+
<li><a href="/products/ready-to-review/">Ready to Review</a></li>
3338
<li><a href="/support/">support</a></li>
3439
<li><a href="/security/">security</a></li>
3540
<li><a href="/opensource/">opensource</a></li>
3641
</ul>
3742
</nav>
43+
<div class="nav-overlay"></div>
3844

3945
<main id="main-content">
4046
{{ content | safe }}
4147
</main>
48+
49+
<script>
50+
(function() {
51+
const hamburger = document.querySelector('.nav-hamburger');
52+
const navLinks = document.querySelector('.nav-links');
53+
const overlay = document.querySelector('.nav-overlay');
54+
const body = document.body;
55+
56+
function toggleMenu() {
57+
const isOpen = navLinks.classList.contains('nav-links--open');
58+
59+
if (isOpen) {
60+
navLinks.classList.remove('nav-links--open');
61+
overlay.classList.remove('nav-overlay--visible');
62+
body.classList.remove('nav-open');
63+
hamburger.classList.remove('nav-hamburger--active');
64+
hamburger.setAttribute('aria-expanded', 'false');
65+
} else {
66+
navLinks.classList.add('nav-links--open');
67+
overlay.classList.add('nav-overlay--visible');
68+
body.classList.add('nav-open');
69+
hamburger.classList.add('nav-hamburger--active');
70+
hamburger.setAttribute('aria-expanded', 'true');
71+
}
72+
}
73+
74+
hamburger.addEventListener('click', toggleMenu);
75+
overlay.addEventListener('click', toggleMenu);
76+
77+
// Close menu when clicking a link
78+
const links = navLinks.querySelectorAll('a');
79+
links.forEach(link => {
80+
link.addEventListener('click', () => {
81+
if (navLinks.classList.contains('nav-links--open')) {
82+
toggleMenu();
83+
}
84+
});
85+
});
86+
87+
// Close menu on escape key
88+
document.addEventListener('keydown', (e) => {
89+
if (e.key === 'Escape' && navLinks.classList.contains('nav-links--open')) {
90+
toggleMenu();
91+
}
92+
});
93+
})();
94+
</script>
4295
</body>
4396
</html>

src/assets/css/style.css

Lines changed: 119 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,72 @@ body {
151151
color: var(--cyan);
152152
}
153153

154+
/* Hamburger Menu */
155+
.nav-hamburger {
156+
display: none;
157+
position: absolute;
158+
right: 16px;
159+
top: 50%;
160+
transform: translateY(-50%);
161+
flex-direction: column;
162+
justify-content: center;
163+
gap: 5px;
164+
width: 30px;
165+
height: 30px;
166+
background: transparent;
167+
border: none;
168+
cursor: pointer;
169+
padding: 0;
170+
z-index: 103;
171+
transition: transform 0.3s ease;
172+
}
173+
174+
.hamburger-line {
175+
width: 24px;
176+
height: 2.5px;
177+
background: var(--black);
178+
border-radius: 1px;
179+
transition: all 0.3s ease;
180+
transform-origin: center;
181+
}
182+
183+
.nav-hamburger--active .hamburger-line:nth-child(1) {
184+
transform: translateY(7.5px) rotate(45deg);
185+
}
186+
187+
.nav-hamburger--active .hamburger-line:nth-child(2) {
188+
opacity: 0;
189+
}
190+
191+
.nav-hamburger--active .hamburger-line:nth-child(3) {
192+
transform: translateY(-7.5px) rotate(-45deg);
193+
}
194+
195+
/* Mobile Menu Overlay */
196+
.nav-overlay {
197+
display: none;
198+
position: fixed;
199+
top: 0;
200+
left: 0;
201+
width: 100%;
202+
height: 100%;
203+
background: rgba(0, 0, 0, 0.7);
204+
z-index: 98;
205+
opacity: 0;
206+
pointer-events: none;
207+
transition: opacity 0.3s ease;
208+
}
209+
210+
.nav-overlay--visible {
211+
opacity: 1;
212+
pointer-events: all;
213+
}
214+
215+
/* Prevent body scroll when menu is open */
216+
body.nav-open {
217+
overflow: hidden;
218+
}
219+
154220

155221
/* Accessibility: Focus Indicators */
156222
a:focus-visible,
@@ -1359,28 +1425,62 @@ button,
13591425
height: 34px;
13601426
}
13611427

1428+
/* Show hamburger menu on mobile */
1429+
.nav-hamburger {
1430+
display: flex;
1431+
}
1432+
1433+
/* Show overlay on mobile */
1434+
.nav-overlay {
1435+
display: block;
1436+
}
1437+
1438+
/* Mobile menu - slide in from right */
13621439
.nav-links {
1363-
position: relative;
1364-
right: auto;
1365-
gap: 4px;
1366-
font-size: 12px;
1367-
margin-left: auto;
1368-
margin-right: 8px;
1369-
height: 34px;
1440+
position: fixed;
1441+
top: 0;
1442+
right: -100%;
1443+
width: 280px;
1444+
height: 100vh;
1445+
background: var(--yellow);
1446+
flex-direction: column;
1447+
justify-content: flex-start;
1448+
align-items: stretch;
1449+
padding: 80px 0 40px;
1450+
gap: 0;
1451+
margin: 0;
1452+
z-index: 99;
1453+
box-shadow: -4px 0 12px rgba(0, 0, 0, 0.3);
1454+
transition: right 0.3s ease;
1455+
overflow-y: auto;
1456+
}
1457+
1458+
.nav-links--open {
1459+
right: 0;
1460+
}
1461+
1462+
.nav-links li {
1463+
width: 100%;
1464+
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
13701465
}
13711466

13721467
.nav-links li:not(:last-child)::after {
1373-
margin-left: 4px;
1374-
font-size: 12px;
1468+
display: none;
13751469
}
13761470

13771471
.nav-links a {
1378-
padding: 8px 12px;
1379-
min-height: 34px;
1380-
min-width: 44px;
1381-
display: flex;
1382-
align-items: center;
1383-
justify-content: center;
1472+
width: 100%;
1473+
padding: 18px 24px;
1474+
font-size: 16px;
1475+
font-weight: 700;
1476+
text-align: left;
1477+
min-height: 60px;
1478+
transition: background 0.2s, padding-left 0.2s;
1479+
}
1480+
1481+
.nav-links a:hover {
1482+
background: rgba(0, 0, 0, 0.05);
1483+
padding-left: 32px;
13841484
}
13851485

13861486
.hero {
@@ -1621,21 +1721,16 @@ button,
16211721
/* Extra small screens (iPhone SE, etc) */
16221722
@media (max-width: 374px) {
16231723
.nav-logo a {
1624-
font-size: 16px;
1724+
font-size: 14px;
16251725
}
16261726

16271727
.nav-accent-angle {
1628-
width: 8em;
1728+
width: 7.5em;
16291729
}
16301730

1731+
/* Mobile menu width adjustment for very small screens */
16311732
.nav-links {
1632-
gap: 2px;
1633-
font-size: 11px;
1634-
margin-right: 4px;
1635-
}
1636-
1637-
.nav-links a {
1638-
padding: 8px 10px;
1733+
width: 260px;
16391734
}
16401735

16411736
.hero-content {

0 commit comments

Comments
 (0)