>From a53732d132ecdb91d5a8bc9f792aaf96d86cbcb0 Mon Sep 17 00:00:00 2001 From: Florian Pelz Date: Sun, 15 Sep 2019 21:42:01 +0200 Subject: [PATCH 7/8] website: Make dropdowns accessible to keyboard and touch input. * website/apps/base/templates/components.scm (horizontal-line): New procedure. (navbar, menu-dropdown): Adapt to use CSS for accessibility. * website/static/base/css/navbar.css: Adapt CSS to new dropdowns. --- website/apps/base/templates/components.scm | 77 +++++++++++++++++----- website/static/base/css/navbar.css | 61 ++++++++++++----- 2 files changed, 108 insertions(+), 30 deletions(-) diff --git a/website/apps/base/templates/components.scm b/website/apps/base/templates/components.scm index 6b5ec21..1653c1e 100644 --- a/website/apps/base/templates/components.scm +++ b/website/apps/base/templates/components.scm @@ -21,6 +21,7 @@ button-little contact-preview contact->shtml + horizontal-line horizontal-separator link-more link-subtle @@ -179,6 +180,13 @@ `(src ,(guix-url "static/base/img/h-separator-dark.png"))) (alt "")))) +(define (horizontal-line) + "Return SHTML for a visible separator to be used in a dropdown menu +like a menu item." + `(img (@ (class "hline") + (src ,(guix-url "static/base/img/h-separator.png")) + (alt "")))) + (define* (link-more #:key (label "More") (url "#") (light #false)) "Return an SHTML a element that looks like a 'more →' link. @@ -285,19 +293,52 @@ manual. ITEMS (list of menu items) A list of menu items as returned by the menu-item procedure in this same module. If not provided, the value defaults to an empty list." - `(li - (@ (class "dropdown")) - (a - (@ (class - ,(if (string=? (string-downcase label) (string-downcase active-item)) - "menu-item menu-item-active dropdown-btn" - "menu-item dropdown-btn")) - (href ,url)) - ,label) - (div - (@ (class "submenu")) - (div (@ (class "submenu-triangle")) " ") - (ul ,@items)))) + (let ((label-hash (number->string (string-hash label)))) + `(li + (@ (class ,(if (string=? (string-downcase label) + (string-downcase active-item)) + "menu-item menu-item-active dropdown dropdown-btn" + "menu-item dropdown dropdown-btn"))) + ,@(let ((id (string-append "visible-dropdown-" label-hash))) + `(;; show dropdown when button is checked: + (style ,(string-append "#" id ":checked ~ #submenu-" label-hash " +{ + width: initial; + height: initial; + min-width: 150px; + overflow: initial; +}")) + ;; show uncheck version of button iff button is checked + (style ,(string-append "#" id ":checked \ +~ label[for=all-dropdowns-hidden] +{ + display: initial; +}")) + (style "label[for=all-dropdowns-hidden] +{ + display: none; +}") + ;; show check version of button iff button is unchecked + (style ,(string-append "#" id ":checked ~ label[for=" id "] +{ + display: none; +}")) + (input (@ (class "menu-hidden-input") + (type "radio") + (name "dropdown") + (id ,id))) + (label + (@ (for ,id)) + ,label) + (label + (@ (for "all-dropdowns-hidden")) + ,label))) + (div + (@ (class "submenu") + (id ,(string-append "submenu-" label-hash))) + (div (@ (class "submenu-triangle")) + " ") + (ul ,@items))))) (define* (menu-item #:key (label "Item") (active-item "") (url "#")) @@ -338,7 +379,11 @@ manual. ;; Menu. (nav (@ (class "menu")) - ,(G_ `(h2 (@ (class "a11y-offset")) "website menu:")) + ,(G_ `(h2 (@ (class "a11y-offset")) "website menu:")) + (input (@ (class "menu-hidden-input") + (type "radio") + (name "dropdown") + (id "all-dropdowns-hidden"))) (ul ,(C_ "website menu" (menu-item #:label "Overview" #:active-item active-item #:url (guix-url))) ,(C_ "website menu" (menu-item #:label "Download" #:active-item active-item #:url (guix-url "download/"))) @@ -347,9 +392,11 @@ manual. ,(C_ "website menu" (menu-item #:label "Help" #:active-item active-item #:url (guix-url "help/"))) ,(C_ "website menu" (menu-item #:label "Donate" #:active-item active-item #:url (guix-url "donate/"))) - ,(menu-dropdown #:label (C_ "website menu" "About") #:active-item active-item #:url (guix-url "about/") + ,(menu-dropdown #:label (C_ "website menu" "About") #:active-item active-item #:items (list + (C_ "website menu" (menu-item #:label "About" #:active-item active-item #:url (guix-url "about/"))) + (horizontal-line) (C_ "website menu" (menu-item #:label "Contact" #:active-item active-item #:url (guix-url "contact/"))) (C_ "website menu" (menu-item #:label "Contribute" #:active-item active-item #:url (guix-url "contribute/"))) (C_ "website menu" (menu-item #:label "Security" #:active-item active-item #:url (guix-url "security/"))) diff --git a/website/static/base/css/navbar.css b/website/static/base/css/navbar.css index d699d89..c8a6bd8 100644 --- a/website/static/base/css/navbar.css +++ b/website/static/base/css/navbar.css @@ -53,8 +53,13 @@ position: relative; } +.menu-hidden-input { + display: none; +} + .menu-item:link, -.menu-item:visited { +.menu-item:visited, +label.menu-item { background-color: transparent; background-image: url("../img/link-arrow.png"); background-position: 97% 50%; @@ -104,6 +109,10 @@ background-position: top; } +.hline { + display: none; +} + @@ -134,11 +143,11 @@ text-align: center; } - .menu-item:active, - .menu-item:focus, - .menu-item:hover, - .menu-item-active:link, - .menu-item-active:visited { + a.menu-item:active, + a.menu-item:focus, + a.menu-item:hover, + a.menu-item-active:link, + a.menu-item-active:visited { background-image: url("../img/menu-item-active-bg.png"); background-position: bottom center; background-repeat: no-repeat; @@ -149,31 +158,53 @@ } .dropdown:hover .submenu { - display: block; - right: 0px; + width: initial; + height: initial; + min-width: 150px; + overflow: initial; } - .dropdown-btn:link, - .dropdown-btn:visited { + .dropdown-btn { background-image: url("../img/dropdown-bg.png"); background-position: bottom right; background-repeat: no-repeat; padding-right: 13px; + cursor: pointer; } .dropdown-btn:active, - .dropdown-btn:focus, .dropdown-btn:hover { - background-position: top right; + background-image: url("../img/dropdown-bg.png"); + background-position: top right; + } + + label[for=all-dropdowns-hidden] { + text-shadow: #fff 0px -2px 15px, #fff 0px -2px 10px; + } + + .hline { + display: block; + width: 100%; + height: 1px; } .submenu { background-color: transparent; - display: none; - min-width: 150px; + z-index: 10; + display: block; + overflow: hidden; + width: 0; + height: 0; padding-top: 20px; position: absolute; - z-index: 10; + right: 0px; + } + + .submenu:focus-within { + width: initial; + height: initial; + min-width: 150px; + overflow: initial; } .submenu-triangle { -- 2.23.0