From 7fc823a69f022ddde29537016544e0fb40a25749 Mon Sep 17 00:00:00 2001 From: dendencat <33782903+dendencat@users.noreply.github.com> Date: Tue, 16 Sep 2025 16:07:29 +0900 Subject: [PATCH] Improve mobile header spacing and menu animation --- techblog_cms/static/css/style.css | 58 ++++++++++++++++++- techblog_cms/static/js/main.js | 51 +++++++++++----- techblog_cms/templates/components/header.html | 9 +-- 3 files changed, 96 insertions(+), 22 deletions(-) diff --git a/techblog_cms/static/css/style.css b/techblog_cms/static/css/style.css index bf3b62c..286489c 100644 --- a/techblog_cms/static/css/style.css +++ b/techblog_cms/static/css/style.css @@ -1,14 +1,61 @@ /* Custom styles that extend Tailwind */ body { - padding-top: 80px; + padding-top: 9rem; + padding-top: calc(9rem + env(safe-area-inset-top)); min-height: 100vh; } +#mobile-menu-button { + position: relative; +} + +#mobile-menu-button .hamburger-line { + position: absolute; + left: 50%; + width: 1.5rem; + height: 0.125rem; + background-color: currentColor; + border-radius: 9999px; + transform: translate(-50%, -50%); + transition: transform 0.25s ease, opacity 0.2s ease, top 0.25s ease; +} + +#mobile-menu-button .hamburger-line-top { + top: calc(50% - 0.45rem); +} + +#mobile-menu-button .hamburger-line-middle { + top: 50%; +} + +#mobile-menu-button .hamburger-line-bottom { + top: calc(50% + 0.45rem); +} + +#mobile-menu-button.open .hamburger-line-top, +#mobile-menu-button.open .hamburger-line-bottom { + top: 50%; +} + +#mobile-menu-button.open .hamburger-line-top { + transform: translate(-50%, -50%) rotate(45deg); +} + +#mobile-menu-button.open .hamburger-line-middle { + opacity: 0; +} + +#mobile-menu-button.open .hamburger-line-bottom { + transform: translate(-50%, -50%) rotate(-45deg); +} + /* Sidebar styles */ .sidebar { position: sticky; - top: 80px; - height: calc(100vh - 80px); + top: 5rem; + top: calc(5rem + env(safe-area-inset-top)); + height: calc(100vh - 5rem); + height: calc(100vh - (5rem + env(safe-area-inset-top))); overflow-y: auto; background-color: white; padding: 1rem; @@ -35,6 +82,11 @@ body { /* Responsive breakpoints */ @media (min-width: 768px) { + body { + padding-top: 5rem; + padding-top: calc(5rem + env(safe-area-inset-top)); + } + .article-card { flex: 0 0 calc(50% - 0.5rem); } diff --git a/techblog_cms/static/js/main.js b/techblog_cms/static/js/main.js index 5175c52..066af2b 100644 --- a/techblog_cms/static/js/main.js +++ b/techblog_cms/static/js/main.js @@ -1,4 +1,4 @@ -document.addEventListener('DOMContentLoaded', function() { +document.addEventListener('DOMContentLoaded', () => { const menuButton = document.getElementById('mobile-menu-button'); const mobileMenu = document.getElementById('mobile-menu'); @@ -6,27 +6,40 @@ document.addEventListener('DOMContentLoaded', function() { return; } - const closeMenu = () => { - mobileMenu.classList.add('hidden'); - menuButton.setAttribute('aria-expanded', 'false'); - }; - - menuButton.addEventListener('click', (event) => { - event.preventDefault(); - const isHidden = mobileMenu.classList.contains('hidden'); + const openLabel = 'メインメニューを開く'; + const closeLabel = 'メインメニューを閉じる'; + const srLabel = menuButton.querySelector('[data-menu-button-label]'); - if (isHidden) { + const setMenuState = (shouldOpen) => { + if (shouldOpen) { mobileMenu.classList.remove('hidden'); menuButton.setAttribute('aria-expanded', 'true'); + menuButton.classList.add('open'); + menuButton.setAttribute('aria-label', closeLabel); + if (srLabel) { + srLabel.textContent = closeLabel; + } } else { - closeMenu(); + mobileMenu.classList.add('hidden'); + menuButton.setAttribute('aria-expanded', 'false'); + menuButton.classList.remove('open'); + menuButton.setAttribute('aria-label', openLabel); + if (srLabel) { + srLabel.textContent = openLabel; + } } + }; + + const closeMenu = () => setMenuState(false); + + menuButton.addEventListener('click', (event) => { + event.preventDefault(); + const shouldOpen = mobileMenu.classList.contains('hidden'); + setMenuState(shouldOpen); }); mobileMenu.querySelectorAll('a').forEach((link) => { - link.addEventListener('click', () => { - closeMenu(); - }); + link.addEventListener('click', closeMenu); }); document.addEventListener('click', (event) => { @@ -38,4 +51,12 @@ document.addEventListener('DOMContentLoaded', function() { closeMenu(); } }); -}); \ No newline at end of file + + document.addEventListener('keydown', (event) => { + if (event.key === 'Escape') { + closeMenu(); + } + }); + + setMenuState(false); +}); diff --git a/techblog_cms/templates/components/header.html b/techblog_cms/templates/components/header.html index 64d43fc..45c2679 100644 --- a/techblog_cms/templates/components/header.html +++ b/techblog_cms/templates/components/header.html @@ -26,11 +26,12 @@