prepare for optional menu drawer

This commit is contained in:
madrilene 2024-02-14 07:37:10 +01:00
parent 623cf96ff9
commit efaec51f23
4 changed files with 176 additions and 2 deletions

View file

@ -30,7 +30,13 @@ module.exports = {
description: description:
'Tell the word what you are writing about in your blog. It will show up on feed readers.', 'Tell the word what you are writing about in your blog. It will show up on feed readers.',
// feed links are looped over in the head. You may add more to the array. // feed links are looped over in the head. You may add more to the array.
feedLinks: [{title: 'Atom Feed', url: '/feed.xml', type: 'application/atom+xml'}], feedLinks: [
{
title: 'Atom Feed',
url: '/feed.xml',
type: 'application/atom+xml'
}
],
// Tags // Tags
tagSingle: 'Tag', tagSingle: 'Tag',
tagPlural: 'Tags', tagPlural: 'Tags',
@ -51,7 +57,8 @@ module.exports = {
ariaTop: 'Main', ariaTop: 'Main',
ariaBottom: 'Complementary', ariaBottom: 'Complementary',
ariaPlatforms: 'Platforms', ariaPlatforms: 'Platforms',
closedText: 'Menu' closedText: 'Menu',
drawerMenu: true
}, },
themeSwitch: { themeSwitch: {
title: 'Theme', title: 'Theme',

View file

@ -0,0 +1,16 @@
<!-- template element holding a button that needs to be injected when JavaScript is finally available. -->
<!-- based on an article by Manuel Matuzovic, https://web.dev/website-navigation/ -->
<!-- see also: https://kittygiraudel.com/2022/09/30/templating-in-html/ -->
<template id="burger-template">
<button type="button" aria-expanded="false" aria-label="Menu" aria-controls="mainnav">
<span>Menu</span>
<svg width="24" height="24" aria-hidden="true">
<path
fill-rule="evenodd"
d="M12 3.75a.75.75 0 01.75.75v6.75h6.75a.75.75 0 010 1.5h-6.75v6.75a.75.75 0 01-1.5 0v-6.75H4.5a.75.75 0 010-1.5h6.75V4.5a.75.75 0 01.75-.75z"
clip-rule="evenodd"
/>
</svg>
</button>
</template>

View file

@ -0,0 +1,117 @@
@media (min-width: 38em) {
nav.navbar {
--nav-button-display: none;
--nav-position: static;
}
nav.navbar ul {
--nav-list-background: transparent;
--nav-list-layout: row;
--nav-list-position: static;
--nav-list-padding: 0;
--nav-list-height: auto;
--nav-list-width: 100%;
--nav-list-shadow: none;
--nav-list-transform: none;
--nav-list-visibility: visible;
}
}
/* set on parent div to get the right z-index context */
.ontop {
z-index: 1;
position: relative;
}
nav.navbar {
position: var(--nav-position, absolute);
/* inset-block-start: 0.5rem; */
inset-inline-end: 0.1rem;
}
/* Remove default list styling and create layout for list */
nav.navbar ul {
background: var(--nav-list-background, var(--color-light));
box-shadow: var(--nav-list-shadow, -5px 0 11px 0 rgb(0 0 0 / 0.2));
display: flex;
flex-direction: var(--nav-list-layout, column);
gap: var(--space-s);
block-size: var(--nav-list-height, 100vh);
list-style: none;
margin: 0;
padding: var(--nav-list-padding, var(--space-l) var(--space-s));
position: var(--nav-list-position, fixed);
inset-block-start: 0; /* Logical property. Equivalent to top: 0; */
inset-inline-end: 0; /* Logical property. Equivalent to right: 0; */
inline-size: var(--nav-list-width, min(22rem, 100vw));
visibility: var(--nav-list-visibility, visible);
}
nav.navbar [aria-expanded='false'] + ul {
transform: var(--nav-list-transform, translateX(100%));
visibility: var(--nav-list-visibility, hidden);
}
/* animates ul only when opening to avoid flash on page load, svg always */
@media (prefers-reduced-motion: no-preference) {
nav.navbar [aria-expanded='true'] + ul,
nav.navbar svg {
transition: transform 0.4s cubic-bezier(0.68, -0.55, 0.27, 1.55),
visibility 0.05s linear;
}
}
/* Basic link styling */
nav.navbar a {
--text-color: var(--color-dark);
color: var(--text-color);
padding: 0.1rem;
text-decoration: none;
display: block;
text-decoration-line: underline;
text-decoration-color: var(--border-color, transparent);
text-decoration-thickness: 3px;
text-underline-offset: 0.3em;
}
/* Change the border-color on :hover and :focus */
nav.navbar a:where(:hover, :focus) {
--border-color: var(--text-color);
}
/* Change border-color and color for the active page */
nav.navbar [aria-current='page'] {
--border-color: var(--color-primary);
--text-color: var(--color-primary);
}
/* Reset button styling */
nav.navbar button {
all: unset;
display: var(--nav-button-display, flex);
align-items: center;
position: relative;
z-index: 2;
cursor: pointer;
align-items: center;
padding: var(--space-xs) 0;
}
nav.navbar span {
font-size: var(--size-step-min-1);
font-weight: bold;
text-transform: uppercase;
padding-inline-end: var(--space-2xs);
}
nav.navbar svg {
block-size: 100%;
inline-size: auto;
}
header svg {
transform: translateY(-0.1em);
}
nav.navbar [aria-expanded='true'] svg {
transform: var(--nav-list-rotate, rotate(45deg));
}

View file

@ -0,0 +1,34 @@
// © Manuel Matuzović: https://web.dev/website-navigation/
const nav = document.querySelector('nav');
const list = nav.querySelector('ul');
const burgerClone = document.querySelector('#burger-template').content.cloneNode(true);
const svg = nav.querySelector('svg');
const button = burgerClone.querySelector('button');
button.addEventListener('click', e => {
const isOpen = button.getAttribute('aria-expanded') === 'true';
button.setAttribute('aria-expanded', !isOpen);
});
// avoid DRY: disabling menu
const disableMenu = () => {
button.setAttribute('aria-expanded', false);
};
// close on escape
nav.addEventListener('keyup', e => {
if (e.code === 'Escape') {
disableMenu();
}
});
// close if clicked outside of event target
document.addEventListener('click', e => {
const isClickInsideElement = nav.contains(e.target);
if (!isClickInsideElement) {
disableMenu();
}
});
nav.insertBefore(burgerClone, list);