docbrown/app/assets/stylesheets/components/header.scss
Marcy Sutton f072730f0f
Header navigation dropdown accessibility (#11509)
* Improve keyboard a11y of header menu dropdown

This commit also includes some cleanup of unnecessary functions that seemed to degrade performance.

Closes https://github.com/forem/forem/issues/1154

* Add temporary focus style on navigation-button

* Put menu items in a list

* Adjust menu button based on VoiceOver testing

* Refactor menu logic to be reusable/work on touch

* Preserve admin link visibility

* Focus on first item on menu open

* Clean up some HTML and CSS

* Apply suggestions from code review

Co-authored-by: ludwiczakpawel <ludwiczakpawel@gmail.com>

* Ensure menu hides on click outside

* Rename toggle function and adjust formatting

* Update nav button focus style

* Clean up padding on header avatar focus style

* Make button show focus state for keyboard only

Using .focus-visible:focus targets keyboard focus and eliminates a flash of the blue border on click before focus is moved to the child item (which also has no focus style on mouse click)

* Update app/views/layouts/_top_bar.html.erb

Co-authored-by: ludwiczakpawel <ludwiczakpawel@gmail.com>

* Add some defensive programming

* Removed initializeTouchDevice from base.js.erb

* navigation-butt ID is now member-menu-button

* Moved all the logic from initializeTouchDevice.js into a pack file/utilities.

* committing re-ordered schema after setup

* add tests for initializeTouchDevice

* remove some unneeded html setup

* make sure menu doesn't close if user tabs back from sign out

* Revert "committing re-ordered schema after setup"

This reverts commit a41a1c861cca3b97d8a7b8a99268b8afaae9f028.

* optimized code

* small tweaks, only show outline when focused

Co-authored-by: ludwiczakpawel <ludwiczakpawel@gmail.com>
Co-authored-by: rhymes <rhymes@hey.com>
Co-authored-by: Nick Taylor <nick@dev.to>
Co-authored-by: Suzanne Aitchison <suzanne@forem.com>
2021-01-27 09:39:17 +00:00

236 lines
4.7 KiB
SCSS

@import '../config/import';
.crayons-header {
--indicator-outline: var(--header-bg);
height: var(--header-height);
background: var(--header-bg);
box-shadow: 0 1px 1px var(--header-shadow);
z-index: var(--z-sticky);
.default-header & {
position: fixed;
top: 0px;
left: 0px;
right: 0px;
}
&__container {
max-width: var(--site-width);
padding: 0 var(--layout-padding);
margin: auto;
display: flex;
align-items: center;
position: relative;
height: var(--header-height);
}
.crayons-indicator {
position: absolute;
top: calc(var(--su-1) * -1);
right: 0;
box-shadow: 0 0 0 2px var(--indicator-outline);
}
}
// Search bar
.crayons-header--search {
max-width: 420px;
flex: 1 auto;
margin: 0 var(--su-2);
display: none;
@media (min-width: $breakpoint-m) {
margin: 0 var(--su-4);
display: block;
}
}
.crayons-header__link {
margin: 0 var(--su-1);
&:hover,
&:focus {
--indicator-outline: var(--header-bg-hover);
color: var(--header-icons-color-hover);
background: var(--header-bg-hover);
}
&--current {
--indicator-outline: var(--header-bg-current);
color: var(--header-icons-color-hover);
background: var(--header-bg-current) !important;
.crayons-indicator {
display: none;
}
}
}
// Dropdown under profile picture / hamburger icon
.crayons-header__menu {
--trigger-color: var(--header-icons-color);
--trigger-border-color: transparent;
height: 100%;
display: flex;
align-items: center;
@media (min-width: $breakpoint-s) {
perspective: 1000px;
}
&__trigger {
all: unset;
padding: calc(var(--su-1) / 2);
margin: 0 var(--su-2);
border-radius: 50%;
color: var(--trigger-color);
cursor: pointer;
// hold space for interaction style
border: 2px solid var(--trigger-border-color);
}
&__dropdown {
transform-style: preserve-3d;
top: var(--header-height);
transform-origin: top right;
transition: all var(--transition-props);
transition-delay: var(--dropdown-delay, 0.25s);
transform: var(
--dropdown-transform,
translateY(calc(1 * var(--su-1))) rotateX(-10deg)
);
opacity: var(--dropdown-opacity, 0);
visibility: var(--dropdown-visibility, hidden);
}
&.showing,
&.desktop:hover {
--trigger-border-color: var(--header-bg-hover);
--trigger-color: var(--header-icons-color-hover);
--dropdown-transform: translateY(0) rotateX(0);
--dropdown-delay: 0;
--dropdown-opacity: 1;
--dropdown-visibility: visible;
}
.focus-visible:focus {
--trigger-border-color: var(--header-button-focus-color);
--trigger-color: var(--header-button-focus-color);
}
}
.skip-content-link {
position: absolute;
top: 0;
left: 50%;
transform: translate(-50%, -100px);
background: var(--body-color);
color: var(--body-color-inverted);
z-index: var(--z-popover);
padding: var(--su-4);
pointer-events: none;
opacity: 0;
border-radius: var(--radius);
outline: 0;
&:focus {
pointer-events: auto;
opacity: 1;
transform: translate(-50%, var(--header-height) / 2);
}
}
.pwa-nav-buttons {
height: 100%;
display: none;
padding-left: var(--su-2);
button {
all: unset;
padding: 0 var(--su-2);
color: var(--header-icons-color);
&:hover {
color: var(--header-icons-color-hover);
}
}
@media (min-width: $breakpoint-m) {
&.pwa-nav-buttons--showing {
display: flex;
}
}
}
.authentication-header {
&__container {
padding: var(--su-6);
}
&__image-container {
width: var(--su-8);
height: var(--su-8);
margin-bottom: var(--su-2);
}
&__image {
border-radius: var(--radius);
transform: rotate(-10deg);
height: auto;
width: 100%;
}
&__title {
color: var(--card-color);
font-size: var(--fs-2xl);
line-height: var(--lh-tight);
@media (min-width: $breakpoint-s) {
font-size: var(--fs-3xl);
}
}
&__description {
color: var(--card-color-secondary);
margin-bottom: var(--su-4);
}
&__actions {
display: grid;
grid-gap: var(--su-1);
@media (min-width: $breakpoint-s) {
display: flex;
flex-direction: column;
width: max-content;
justify-self: center;
}
}
}
.navigation-progress {
--duration: 3600ms;
--delay: 250ms;
position: fixed;
top: 0;
background: var(--accent-brand);
z-index: var(--z-popover);
height: var(--su-1);
width: 0;
&.showing {
display: block;
animation: showProgressBar var(--duration) ease-in-out;
animation-delay: var(--delay);
animation-fill-mode: forwards;
}
}
@keyframes showProgressBar {
0% {
width: 0;
}
100% {
width: 100%;
}
}