Skip to content

Commit 0f99edd

Browse files
Dale KunceDale Kunce
authored andcommitted
feat: comprehensive mobile improvements across site
- Improved mobile blog layout with responsive cards and pagination - Added mobile-first breakpoints (768px, 480px) throughout - Increased button touch targets - Enhanced mobile footer and landing page responsiveness - Improved mobile typography scaling and spacing - Added better mobile menu interactions and accessibility features - All components now fully responsive with touch-friendly interfaces
1 parent dc735a6 commit 0f99edd

File tree

5 files changed

+415
-43
lines changed

5 files changed

+415
-43
lines changed

app/assets/scripts/mobile-menu.js

Lines changed: 69 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/**
22
* Mobile Navigation Menu
3-
* Handles touch/click events for mobile devices where hover doesn't work properly
3+
* Enhanced mobile navigation with improved touch interactions and accessibility
44
*/
55
(function () {
66
'use strict';
@@ -9,40 +9,100 @@
99
// Find the mobile dropdown toggle
1010
const mobileDropdown = document.querySelector('.resp-nav-dropdown');
1111
const dropdownContent = document.querySelector('.resp-dropdown-content');
12+
const menuButton = mobileDropdown?.querySelector('p');
1213

1314
if (!mobileDropdown || !dropdownContent) {
1415
return;
1516
}
1617

17-
// Add click event listener to toggle mobile menu
18-
mobileDropdown.addEventListener('click', (e) => {
18+
// Add ARIA attributes for accessibility
19+
mobileDropdown.setAttribute('role', 'button');
20+
mobileDropdown.setAttribute('aria-expanded', 'false');
21+
mobileDropdown.setAttribute('aria-haspopup', 'true');
22+
mobileDropdown.setAttribute('tabindex', '0');
23+
dropdownContent.setAttribute('role', 'menu');
24+
25+
// Update menu button text and ARIA state
26+
function updateMenuState(isOpen) {
27+
const isExpanded = isOpen ? 'true' : 'false';
28+
mobileDropdown.setAttribute('aria-expanded', isExpanded);
29+
30+
if (menuButton) {
31+
menuButton.textContent = isOpen ? 'CLOSE' : 'MENU';
32+
}
33+
}
34+
35+
// Toggle mobile menu
36+
function toggleMenu(e) {
1937
e.preventDefault();
2038
e.stopPropagation();
2139

22-
// Toggle the show class
23-
dropdownContent.classList.toggle('show');
40+
const isOpen = dropdownContent.classList.toggle('show');
41+
updateMenuState(isOpen);
42+
43+
// Add/remove body scroll lock on mobile
44+
if (isOpen) {
45+
document.body.style.overflow = 'hidden';
46+
} else {
47+
document.body.style.overflow = '';
48+
}
49+
}
50+
51+
// Close menu
52+
function closeMenu() {
53+
dropdownContent.classList.remove('show');
54+
updateMenuState(false);
55+
document.body.style.overflow = '';
56+
}
57+
58+
// Enhanced event listeners
59+
mobileDropdown.addEventListener('click', toggleMenu);
60+
mobileDropdown.addEventListener('touchstart', (e) => {
61+
// Prevent double-tap zoom on iOS
62+
e.preventDefault();
63+
});
64+
65+
// Keyboard support
66+
mobileDropdown.addEventListener('keydown', (e) => {
67+
if (e.key === 'Enter' || e.key === ' ') {
68+
toggleMenu(e);
69+
}
2470
});
2571

2672
// Close menu when clicking outside
2773
document.addEventListener('click', (e) => {
28-
if (!mobileDropdown.contains(e.target)) {
29-
dropdownContent.classList.remove('show');
74+
if (!mobileDropdown.contains(e.target) && !dropdownContent.contains(e.target)) {
75+
closeMenu();
3076
}
3177
});
3278

3379
// Close menu when pressing escape key
3480
document.addEventListener('keydown', (e) => {
3581
if (e.key === 'Escape') {
36-
dropdownContent.classList.remove('show');
82+
closeMenu();
3783
}
3884
});
3985

4086
// Close menu when window is resized to desktop size
4187
window.addEventListener('resize', () => {
4288
if (window.innerWidth > 650) {
43-
dropdownContent.classList.remove('show');
89+
closeMenu();
4490
}
4591
});
92+
93+
// Enhanced touch handling for mobile menu items
94+
const menuItems = dropdownContent.querySelectorAll('.nav-item, .lang');
95+
menuItems.forEach(item => {
96+
item.addEventListener('touchstart', function() {
97+
this.style.backgroundColor = 'rgba(255,255,255,0.1)';
98+
});
99+
100+
item.addEventListener('touchend', function() {
101+
setTimeout(() => {
102+
this.style.backgroundColor = '';
103+
}, 150);
104+
});
105+
});
46106
}
47107

48108
// Initialize when DOM is ready

0 commit comments

Comments
 (0)