Simplify code to have an off-canvas menu

While Foundations's off-canvas menu allows us to forget about writing
CSS, it also leads to complicated HTML.

Ideally Foundation would provide an easy way to simplify what we're
doing, but I haven't found anything in the documentation.

We could simplify the HTML a bit more if we used a CSS grid layout
instead of a flex one, but old browsers have better support for the
latter.

Note we're using `breakpoint(medium)` so we can group the CSS for small
screens and follow SCSS-Lint rules at the same time.

Also note behavior of the main area when the menu appears on small
screens is slightly different: it doesn't move the main content to the
right. I've done it this way so we don't have any overflow issues,
unlike the previous version.

There's a small issue using a label and a checkbox to enable/disable the
menu: sighted keyboard users with a small screen might not be able to
enable the menu. So we're adding the `:focus-within` pseudoclass so the
menu can be normally navigated using the keyboard. Even if old browsers
don't support this pseudoclass, we believe the probability of a sighted
user using a small screen, navigating with the keyboard and using an old
browser is really low, particularly in the admin area.

We're also adding the `aria-hidden` attribute on the label, since the
menu is never hidden for screen readers and so having a control to show
it could be confusing. Since the label is not focusable, we're complying
with the fourth ARIA rule:

> Do not use role="presentation" or aria-hidden="true" on a focusable
> element .
>
> Using either of these on a focusable element will result in some users
> focusing on 'nothing'.
This commit is contained in:
Javi Martín
2020-04-30 16:51:24 +02:00
parent 2363aa4c76
commit 125106f9c0
8 changed files with 453 additions and 452 deletions

View File

@@ -7,34 +7,22 @@
</head>
<body class="admin">
<div class="off-canvas-wrapper">
<div class="off-canvas-wrapper-inner" data-off-canvas-wrapper>
<div class="off-canvas position-left" id="offCanvas" data-off-canvas>
<%= render "layouts/admin_header" %>
<div class="show-for-small-only">
<%= side_menu %>
</div>
</div>
<div class="menu-and-content no-margin-top">
<%= check_box_tag :show_menu, nil, false, role: "switch" %>
<div class="off-canvas-content" data-off-canvas-content>
<%= render "layouts/admin_header" %>
<nav id="side_menu" class="admin-sidebar">
<%= side_menu %>
</nav>
<div class="menu-and-content no-margin-top">
<div id="side_menu" class="hide-for-small-only">
<%= side_menu %>
</div>
<div class="admin-content">
<%= label_tag :show_menu, t("admin.menu.admin"),
"aria-hidden": true, class: "button hollow expanded" %>
<div class="admin-content">
<div class="show-for-small-only">
<button type="button" class="button hollow expanded" data-toggle="offCanvas"><%= t("admin.menu.admin") %></button>
</div>
<%= render "layouts/flash" %>
<%= render "layouts/officing_booth" if controller.class.parent == Officing && session[:booth_id].present? %>
<%= yield %>
</div>
</div>
</div>
<%= render "layouts/flash" %>
<%= render "layouts/officing_booth" if controller.class.parent == Officing && session[:booth_id].present? %>
<%= yield %>
</div>
</div>
</body>