Clearer focus ring for all elements

This commit is contained in:
Benji Grant 2023-06-09 02:59:42 +10:00
parent c6875b0332
commit c4d47cd034
13 changed files with 115 additions and 74 deletions

View file

@ -52,6 +52,11 @@
border-top-left-radius: 5px; border-top-left-radius: 5px;
border-top-right-radius: 5px; border-top-right-radius: 5px;
cursor: pointer; cursor: pointer;
&:focus-visible {
outline: var(--focus-ring);
outline-offset: 2px;
}
} }
.tabSelected { .tabSelected {

View file

@ -20,7 +20,6 @@ export const generateMetadata = async ({ params }: PageProps): Promise<Metadata>
const event = await getEvent(params.id).catch(() => undefined) const event = await getEvent(params.id).catch(() => undefined)
const { t } = await useTranslation('event') const { t } = await useTranslation('event')
// TODO: More metadata
return { return {
title: event?.name ?? t('error.title'), title: event?.name ?? t('error.title'),
} }

View file

@ -89,6 +89,7 @@ body {
background: var(--background); background: var(--background);
color: var(--text); color: var(--text);
font-weight: var(--font-weight); font-weight: var(--font-weight);
--focus-ring: 2px solid var(--secondary);
} }
.light { .light {
@ -131,6 +132,11 @@ body {
a { a {
color: var(--primary); color: var(--primary);
border-radius: .2em;
}
a:focus-visible {
outline: var(--focus-ring);
outline-offset: 2px;
} }
*::-webkit-scrollbar { *::-webkit-scrollbar {

View file

@ -146,6 +146,11 @@
cursor: pointer; cursor: pointer;
padding: 2px 8px; padding: 2px 8px;
user-select: none; user-select: none;
&:focus-visible {
outline: var(--focus-ring);
outline-offset: 2px;
}
} }
.personSelected { .personSelected {

View file

@ -1,50 +1,57 @@
.button { .button {
position: relative;
display: inline-flex;
align-items: center;
justify-content: center;
text-align: center;
cursor: pointer; cursor: pointer;
border: 0; border: 0;
text-decoration: none; text-decoration: none;
font: inherit; font: inherit;
box-sizing: border-box; padding: 0;
background: var(--override-surface-color, var(--primary)); margin: 0;
color: var(--override-text-color, var(--background)); background: none;
font-weight: 600;
transition: transform 150ms cubic-bezier(0, 0, 0.58, 1);
border-radius: 3px; border-radius: 3px;
padding: .6em 1.5em;
transform-style: preserve-3d;
margin-bottom: 5px;
& svg, & img { & > div {
height: 1.2em; position: relative;
width: 1.2em; display: inline-flex;
margin-right: .5em; align-items: center;
} justify-content: center;
text-align: center;
&::before { box-sizing: border-box;
content: ''; background: var(--override-surface-color, var(--primary));
position: absolute; color: var(--override-text-color, var(--background));
height: 100%; font-weight: 600;
width: 100%; transition: transform 150ms cubic-bezier(0, 0, 0.58, 1);
top: 0;
left: 0;
background: var(--override-shadow-color, var(--shadow));
border-radius: inherit; border-radius: inherit;
transform: translate3d(0, 5px, -1em); padding: .6em 1.5em;
transition: transform 150ms cubic-bezier(0, 0, 0.58, 1), box-shadow 150ms cubic-bezier(0, 0, 0.58, 1); transform-style: preserve-3d;
margin-bottom: 5px;
& svg, & img {
height: 1.2em;
width: 1.2em;
margin-right: .5em;
}
&::before {
content: '';
position: absolute;
height: 100%;
width: 100%;
top: 0;
left: 0;
background: var(--override-shadow-color, var(--shadow));
border-radius: inherit;
transform: translate3d(0, 5px, -1em);
transition: transform 150ms cubic-bezier(0, 0, 0.58, 1), box-shadow 150ms cubic-bezier(0, 0, 0.58, 1);
}
} }
&:hover, &:focus { &:hover > div, &:focus > div {
transform: translate(0, 1px); transform: translate(0, 1px);
&::before { &::before {
transform: translate3d(0, 4px, -1em); transform: translate3d(0, 4px, -1em);
} }
} }
&:active { &:active > div {
transform: translate(0, 5px); transform: translate(0, 5px);
&::before { &::before {
transform: translate3d(0, 0, -1em); transform: translate3d(0, 0, -1em);
@ -52,13 +59,18 @@
} }
@media print { @media print {
&::before { & > div::before {
display: none; display: none;
} }
} }
&:focus-visible {
outline: var(--focus-ring);
outline-offset: 2px;
}
} }
.iconButton { .iconButton > div {
height: 30px; height: 30px;
width: 30px; width: 30px;
padding: 0; padding: 0;
@ -68,14 +80,17 @@
} }
} }
.small { .small > div {
padding: .4em 1.3em; padding: .4em 1.3em;
} }
.loading { .loading {
color: transparent;
cursor: wait; cursor: wait;
& > div {
color: transparent;
}
& img { & img {
opacity: 0; opacity: 0;
} }
@ -89,7 +104,7 @@
} }
} }
&::after { & > div::after {
content: ''; content: '';
position: absolute; position: absolute;
top: calc(50% - 12px); top: calc(50% - 12px);
@ -103,7 +118,7 @@
} }
@media (prefers-reduced-motion: reduce) { @media (prefers-reduced-motion: reduce) {
&::after { & > div::after {
content: 'loading...'; content: 'loading...';
color: var(--override-text-color, var(--background)); color: var(--override-text-color, var(--background));
animation: none; animation: none;
@ -122,19 +137,21 @@
} }
.secondary { .secondary {
background: transparent; & > div {
border: 1px solid var(--override-surface-color, var(--secondary)); background: transparent;
color: var(--override-surface-color, var(--secondary)); border: 1px solid var(--override-surface-color, var(--secondary));
margin-bottom: 0; color: var(--override-surface-color, var(--secondary));
margin-bottom: 0;
&::before { @media print {
box-shadow: 0 4px 0 0 var(--override-shadow-color, var(--secondary));
}
}
& > div::before {
content: none; content: none;
} }
&:hover, &:active, &:focus { &:hover > div, &:active > div, &:focus > div {
transform: none; transform: none;
} }
@media print {
box-shadow: 0 4px 0 0 var(--override-shadow-color, var(--secondary));
}
} }

View file

@ -44,7 +44,7 @@ const Button: React.FC<ButtonProps> = ({
...shadowColor && { '--override-shadow-color': shadowColor }, ...shadowColor && { '--override-shadow-color': shadowColor },
...style, ...style,
}, },
children: <>{icon}{children}</>, children: <div>{icon}{children}</div>,
...props, ...props,
} }

View file

@ -63,6 +63,13 @@
padding: 10px 0; padding: 10px 0;
user-select: none; user-select: none;
touch-action: none; touch-action: none;
position: relative;
&:focus-visible {
outline: var(--focus-ring);
outline-offset: 2px;
z-index: 1;
}
@media (prefers-reduced-motion: reduce) { @media (prefers-reduced-motion: reduce) {
transition: none; transition: none;

View file

@ -8,16 +8,14 @@
border: 1px solid var(--primary); border: 1px solid var(--primary);
box-shadow: inset 0 0 0 0 var(--primary); box-shadow: inset 0 0 0 0 var(--primary);
border-radius: 3px; border-radius: 3px;
outline: none;
transition: border-color .15s, box-shadow .15s;
appearance: none; appearance: none;
background-image: url('data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20100%20100%22%3E%3CforeignObject%20width%3D%22100px%22%20height%3D%22100px%22%3E%3Cdiv%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxhtml%22%20style%3D%22color%3A%23F79E00%3Bfont-size%3A60px%3Bdisplay%3Aflex%3Balign-items%3Acenter%3Bjustify-content%3Acenter%3Bheight%3A100%25%3Bwidth%3A100%25%3B%22%3E%E2%96%BC%3C%2Fdiv%3E%3C%2FforeignObject%3E%3C%2Fsvg%3E'); background-image: url('data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20100%20100%22%3E%3CforeignObject%20width%3D%22100px%22%20height%3D%22100px%22%3E%3Cdiv%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxhtml%22%20style%3D%22color%3A%23F79E00%3Bfont-size%3A60px%3Bdisplay%3Aflex%3Balign-items%3Acenter%3Bjustify-content%3Acenter%3Bheight%3A100%25%3Bwidth%3A100%25%3B%22%3E%E2%96%BC%3C%2Fdiv%3E%3C%2FforeignObject%3E%3C%2Fsvg%3E');
background-repeat: no-repeat; background-repeat: no-repeat;
background-position: right 10px center; background-position: right 10px center;
background-size: 1em; background-size: 1em;
&:focus { &:focus-visible {
border: 1px solid var(--secondary); outline: var(--focus-ring);
box-shadow: inset 0 -3px 0 0 var(--secondary); outline-offset: 2px;
} }
} }

View file

@ -17,6 +17,10 @@
transition: transform .15s; transition: transform .15s;
padding: 0; padding: 0;
&:focus-visible {
outline: var(--focus-ring);
}
@media (prefers-reduced-motion: reduce) { @media (prefers-reduced-motion: reduce) {
transition: none; transition: none;
} }

View file

@ -9,11 +9,9 @@
box-shadow: inset 0 0 0 0 var(--primary); box-shadow: inset 0 0 0 0 var(--primary);
border-radius: 3px; border-radius: 3px;
font-size: 18px; font-size: 18px;
outline: none;
transition: border-color .15s, box-shadow .15s;
&:focus { &:focus-visible {
border: 1px solid var(--secondary); outline: var(--focus-ring);
box-shadow: inset 0 -3px 0 0 var(--secondary); outline-offset: 2px;
} }
} }

View file

@ -48,6 +48,11 @@
white-space: nowrap; white-space: nowrap;
padding-inline: var(--extra-padding); padding-inline: var(--extra-padding);
} }
&:focus-visible {
outline: var(--focus-ring);
outline-offset: 2px;
}
} }
.selected { .selected {

View file

@ -1,23 +1,15 @@
.toggleContainer { .toggleContainer {
display: flex; display: flex;
border: 1px solid var(--primary);
border-radius: 3px; border-radius: 3px;
overflow: hidden;
--focus-color: var(--primary);
transition: border .15s;
&:focus-within {
--focus-color: var(--secondary);
border: 1px solid var(--focus-color);
& label {
box-shadow: inset 0 -3px 0 0 var(--focus-color);
}
}
& > div:first-of-type label { & > div:first-of-type label {
border-inline-start: 1px solid var(--primary);
border-end-start-radius: 2px; border-end-start-radius: 2px;
border-start-start-radius: 2px;
} }
& > div:last-of-type label { & > div:last-of-type label {
border-inline-end: 1px solid var(--primary);
border-start-end-radius: 2px;
border-end-end-radius: 2px; border-end-end-radius: 2px;
} }
} }
@ -38,7 +30,11 @@
&:checked + label { &:checked + label {
color: var(--background); color: var(--background);
background-color: var(--focus-color); background-color: var(--primary);
}
&:focus-visible + label {
outline: var(--focus-ring);
outline-offset: 2px;
} }
} }
@ -52,5 +48,5 @@
box-sizing: border-box; box-sizing: border-box;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
transition: box-shadow .15s, background-color .15s; border-block: 1px solid var(--primary);
} }

View file

@ -20,6 +20,7 @@
max-width: 400px; max-width: 400px;
margin: 0 auto; margin: 0 auto;
transition: transform .15s; transition: transform .15s;
border-radius: 10px;
&:hover, &:focus { &:hover, &:focus {
transform: translateY(-2px); transform: translateY(-2px);
@ -31,7 +32,7 @@
img { img {
width: 100%; width: 100%;
display: block; display: block;
border-radius: 10px; border-radius: inherit;
background-color: #CCC; background-color: #CCC;
} }
span { span {