UX improvements

main
Síle Ekaterin Liszka 2024-01-27 14:08:07 -08:00
parent 09cefeb12d
commit eca4da86c3
Signed by: VulpineAmethyst
SSH Key Fingerprint: SHA256:VcHwQ6SUfi/p0Csfxe3SabX/TImWER0PhoJqkt+GlmE
5 changed files with 223 additions and 22 deletions

View File

@ -16,11 +16,7 @@
</head>
<body>
<header>
<nav>
<ul>{{ range .Site.Menus.main }}
<li><a href="{{ .URL | relURL }}">{{ .Name }}</a></li>{{ end }}
</ul>
</nav>
{{ partial "nav.html" . }}
</header>
{{ block "main" . }} {{ end }}
<hr/>

View File

@ -0,0 +1,17 @@
<script src="/js/clicky-menus.js"></script>
<nav id="navigation">
<ul class="clicky-menu no-js">
<li><a href="/">Home</a></li>
<li><a href="/about">About</a></li>
<li><a href="https://acefox.life" rel="me">Blog</a></li>
<li><a href="#">Projects</a>
<ul>
<li><a href="/commissions">Art</a></li>
<li><a href="/programs">Programs</a></li>
<li><a href="/recipe">Recipes</a></li>
<li><a href="/translations">Translations</a></li>
</ul></li>
<li><a href="/system">System Reference</a></li>
<li><a href="/links">Links</a></li>
</ul>
</nav>

View File

@ -2,6 +2,9 @@ html {
font-family: var(--font);
}
article, hr, footer {
max-width: 40em;
margin: 0 auto;
width: 48em;
margin-left: calc(3em / 5);
}
article p {
text-indent: 3em;
}

View File

@ -2,6 +2,8 @@
:root {
--font: Consolas, Menlo, Monaco, "Andale Mono", "Ubuntu Mono", monospace;
--font-size: 14pt;
/* for whatever reason, this is how wide a character is. 1em is wider. */
--char-width: calc(3em / 5);
/* colours */
--normal-red: #B00;
@ -29,10 +31,12 @@
--bold: var(--bright-white);
--italic: var(--normal-purple);
}
body {
html {
background-color: var(--terminal-bg);
color: var(--terminal-fg);
font-size: var(--font-size);
}
body {
margin: 0;
}
h1, h2, h3, h4, h5, h6 {
@ -63,33 +67,48 @@ a:visited {
nav a {
text-decoration: none;
}
nav a:link, nav a:visited, nav {
nav button {
font-family: var(--font);
font-size: var(--font-size);
border: none;
padding: 0;
}
nav a:link, nav a:visited, nav, nav button {
color: var(--normal-black);
background-color: var(--normal-white);
}
nav a:hover, nav a:active, nav a:visited:hover {
nav a:hover, nav a:active, nav a:visited:hover, nav button:hover {
color: var(--bright-white);
background-color: var(--normal-black);
}
nav > ul {
list-style-type: none;
margin: 0;
padding-left: 0;
padding: 0;
}
nav li {
display: inline-block;
margin-left: 1em;
margin-right: 1em;
padding-left: 0;
padding-right: 0;
}
article, hr, footer {
margin: 0 auto;
margin: 0 var(--char-width);
padding: 0;
margin-top: 2ex;
margin-bottom: 2ex;
margin-left: 2em;
margin-right: 2em;
}
nav li > ul {
position: absolute;
padding: 12px 0;
background-color: var(--normal-white);
visibility: hidden;
}
nav li > ul li {
display: block;
}
nav li:hover.no-js > ul {
visibility: visible;
}
nav li:focus-within.no-js > ul { /* separate from above for older browsers. */
visibility: visible;
}
/* JavaScript menus */
nav ul[aria-hidden="false"] {
visibility: visible;
}
article ul {
list-style-type: '- ';

View File

@ -0,0 +1,166 @@
/**
* Object for creating click-triggered navigation submenus
*
* Thanks for the inspiration:
* - https://www.lottejackson.com/learning/a-reusable-javascript-toggle-pattern
* - https://codepen.io/lottejackson/pen/yObQRM
*
* from https://github.com/mrwweb/clicky-menus
*/
( function() {
'use strict';
const ClickyMenus = function( menu ) {
// DOM element(s)
const container = menu.parentElement;
let currentMenuItem,
i,
len;
this.init = function() {
menuSetup();
document.addEventListener( 'click', closeOpenMenu );
};
/*===================================================
= Menu Open / Close Functions =
===================================================*/
function toggleOnMenuClick( e ) {
const button = e.currentTarget;
// close open menu if there is one
if ( currentMenuItem && button !== currentMenuItem ) {
toggleSubmenu( currentMenuItem );
}
toggleSubmenu( button );
}
function toggleSubmenu( button ) {
const submenu = document.getElementById( button.getAttribute( 'aria-controls' ) );
if ( 'true' === button.getAttribute( 'aria-expanded' ) ) {
button.setAttribute( 'aria-expanded', false );
submenu.setAttribute( 'aria-hidden', true );
currentMenuItem = false;
} else {
button.setAttribute( 'aria-expanded', true );
submenu.setAttribute( 'aria-hidden', false );
preventOffScreenSubmenu( submenu );
currentMenuItem = button;
}
}
function preventOffScreenSubmenu( submenu ) {
const screenWidth = window.innerWidth ||
document.documentElement.clientWidth ||
document.body.clientWidth,
parent = submenu.offsetParent,
menuLeftEdge = parent.getBoundingClientRect().left,
menuRightEdge = menuLeftEdge + submenu.offsetWidth;
if ( menuRightEdge + 32 > screenWidth ) { // adding 32 so it's not too close
submenu.classList.add( 'sub-menu--right' );
}
}
function closeOnEscKey( e ) {
if ( 27 === e.keyCode ) {
// we're in a submenu item
if ( null !== e.target.closest( 'ul[aria-hidden="false"]' ) ) {
currentMenuItem.focus();
toggleSubmenu( currentMenuItem );
// we're on a parent item
} else if ( 'true' === e.target.getAttribute( 'aria-expanded' ) ) {
toggleSubmenu( currentMenuItem );
}
}
}
function closeOpenMenu( e ) {
if ( currentMenuItem && ! e.target.closest( '#' + container.id ) ) {
toggleSubmenu( currentMenuItem );
}
}
/*===========================================================
= Modify Menu Markup & Bind Listeners =
=============================================================*/
function menuSetup() {
menu.classList.remove( 'no-js' );
const submenuSelector = 'clickySubmenuSelector' in menu.dataset ? menu.dataset.clickySubmenuSelector : 'ul';
menu.querySelectorAll( submenuSelector ).forEach( ( submenu ) => {
const menuItem = submenu.parentElement;
if ( 'undefined' !== typeof submenu ) {
const button = convertLinkToButton( menuItem );
setUpAria( submenu, button );
// bind event listener to button
button.addEventListener( 'click', toggleOnMenuClick );
menu.addEventListener( 'keyup', closeOnEscKey );
}
} );
}
/**
* Why do this? See https://justmarkup.com/articles/2019-01-21-the-link-to-button-enhancement/
*
* @param {HTMLElement} menuItem An element representing a link to be converted to a button
*/
function convertLinkToButton( menuItem ) {
const link = menuItem.getElementsByTagName( 'a' )[ 0 ],
linkHTML = link.innerHTML,
linkAtts = link.attributes,
button = document.createElement( 'button' );
if ( null !== link ) {
// copy button attributes and content from link
button.innerHTML = linkHTML.trim();
for ( i = 0, len = linkAtts.length; i < len; i++ ) {
const attr = linkAtts[ i ];
if ( 'href' !== attr.name ) {
button.setAttribute( attr.name, attr.value );
}
}
menuItem.replaceChild( button, link );
}
return button;
}
function setUpAria( submenu, button ) {
const submenuId = submenu.getAttribute( 'id' );
let id;
if ( null === submenuId ) {
id = button.textContent.trim().replace( /\s+/g, '-' ).toLowerCase() + '-submenu';
} else {
id = submenuId + '-submenu';
}
// set button ARIA
button.setAttribute( 'aria-controls', id );
button.setAttribute( 'aria-expanded', false );
// set submenu ARIA
submenu.setAttribute( 'id', id );
submenu.setAttribute( 'aria-hidden', true );
}
};
/* Create a ClickMenus object and initiate menu for any menu with .clicky-menu class */
document.addEventListener( 'DOMContentLoaded', function() {
const menus = document.querySelectorAll( '.clicky-menu' );
menus.forEach( ( menu ) => {
const clickyMenu = new ClickyMenus( menu );
clickyMenu.init();
} );
} );
}() );