Skip to content

Commit c08dcc1

Browse files
fix: fix focus
1 parent bdf0c6c commit c08dcc1

File tree

12 files changed

+214
-16
lines changed

12 files changed

+214
-16
lines changed

src/components/AuthLogin/styles.module.scss

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,13 @@
2121
top: 50%;
2222
transform: translate(-50%, -50%);
2323
overflow: auto;
24-
outline: none;
2524
background: var(--modal-bg-color-primary);
25+
26+
/* Enhanced focus styles for modal accessibility */
27+
&:focus-visible {
28+
outline: 2px solid var(--focus-outline-color-light);
29+
outline-offset: 2px;
30+
}
2631
width: 60%;
2732
padding: 1.4rem;
2833
border-radius: 1rem;

src/components/Card.module.scss

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,13 @@
7676
opacity: 1;
7777
}
7878
}
79+
80+
border: 2px solid transparent;
81+
82+
&:focus {
83+
border: 2px solid var(--focus-outline-color-light);
84+
outline: none;
85+
}
7986
}
8087

8188
.shape {

src/components/Card.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,13 @@ export type CardItem = {
1818
buttonIcon?: 'arrow-right' | 'external-arrow'
1919
}
2020

21-
export default function Card({ title, href, description, theme, buttonIcon = "arrow-right" }: CardItem) {
21+
export default function Card({
22+
title,
23+
href,
24+
description,
25+
theme,
26+
buttonIcon = 'arrow-right',
27+
}: CardItem) {
2228
const [isHovered, setIsHovered] = useState(false)
2329

2430
return (
@@ -47,7 +53,7 @@ export default function Card({ title, href, description, theme, buttonIcon = "ar
4753

4854
{href && (
4955
<Button
50-
as="button"
56+
as="div"
5157
label={false}
5258
type={theme === 'dark' ? 'secondary' : 'primary'}
5359
icon={buttonIcon}

src/components/Input/input.module.scss

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,16 @@
3535
overflow: hidden;
3636
color: var(--input-color);
3737
font-style: normal;
38-
outline: none;
3938
width: 100%;
4039
margin-bottom: 4px;
4140

41+
/* Enhanced focus styles for better accessibility */
42+
&:focus-visible {
43+
outline: 2px solid var(--focus-outline-color-light);
44+
outline-offset: 1px;
45+
border-color: var(--focus-outline-color-light);
46+
}
47+
4248
&:disabled {
4349
opacity: 0.5;
4450
pointer-events: none;

src/components/ParserOpenRPC/InteractiveBox/styles.module.scss

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -285,8 +285,11 @@
285285
background-color: var(--general-gray-dark);
286286
}
287287
}
288-
.formControl:focus {
289-
outline: none;
288+
/* Enhanced focus styles for better accessibility */
289+
.formControl:focus-visible {
290+
outline: 2px solid var(--focus-outline-color-light);
291+
outline-offset: 1px;
292+
border-color: var(--focus-outline-color-light);
290293
}
291294
.formControl[type='number'] {
292295
border-color: transparent;
@@ -382,11 +385,16 @@
382385
background: none;
383386
padding: 0;
384387
border: 0;
385-
outline: none;
386388
color: var(--general-gray-mid);
387389
font-size: inherit;
388390
line-height: 1;
389391
cursor: pointer;
392+
393+
/* Enhanced focus styles for interactive buttons */
394+
&:focus-visible {
395+
outline: 2px solid var(--focus-outline-color-light);
396+
outline-offset: 2px;
397+
}
390398
}
391399
.addItemIcon {
392400
display: inline-flex;

src/components/elements/buttons/button/button.module.scss

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,13 @@
123123

124124
mask-image: radial-gradient(white, black);
125125

126+
border: 2px solid transparent;
127+
128+
&:focus {
129+
border: 2px solid var(--focus-outline-color-light);
130+
outline: none;
131+
}
132+
126133
&:before {
127134
content: '';
128135

src/components/elements/buttons/button/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ interface ButtonProps {
2121
href?: string
2222
onClick?: () => void
2323
disabled?: boolean
24-
as?: 'link' | 'a' | 'button'
24+
as?: 'link' | 'a' | 'button' | 'div'
2525
external?: boolean
2626
rel?: string | boolean
2727
download?: boolean | string

src/scss/app.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
@import 'commons/reset';
2+
@import 'commons/focus';
23
@import 'commons/typescale';
34
@import 'commons/utils';
45
@import 'commons/animations';

src/scss/commons/_focus.scss

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
/* Focus Management System - WCAG 2.4.7 & 1.4.11 Compliant */
2+
3+
/*
4+
* Focus indicators with proper contrast ratios (minimum 3:1)
5+
* Uses focus-visible for better UX (keyboard navigation only)
6+
*/
7+
8+
:root {
9+
/* Focus indicator colors with high contrast */
10+
--focus-outline-color-light: #0066cc; /* Blue with high contrast */
11+
--focus-outline-color-dark: #4da6ff; /* Lighter blue for dark mode */
12+
--focus-outline-width: 2px;
13+
--focus-outline-offset: 2px;
14+
--focus-outline-style: solid;
15+
16+
/* Alternative focus colors for different contexts */
17+
--focus-outline-warning: #ff6b00; /* Orange for warnings/errors */
18+
--focus-outline-success: #00a651; /* Green for success states */
19+
20+
/* Box shadow focus for cases where outline doesn't work well */
21+
--focus-shadow-light: 0 0 0 2px #ffffff, 0 0 0 4px #0066cc;
22+
--focus-shadow-dark: 0 0 0 2px #0a0a0a, 0 0 0 4px #4da6ff;
23+
}
24+
25+
[data-theme='dark'] {
26+
--focus-outline-color-light: var(--focus-outline-color-dark);
27+
--focus-shadow-light: var(--focus-shadow-dark);
28+
}
29+
30+
/* Remove default focus styles only when we provide alternatives */
31+
*:focus {
32+
outline: auto;
33+
}
34+
35+
/* Apply focus-visible for keyboard navigation */
36+
*:focus-visible {
37+
outline: var(--focus-outline-width) var(--focus-outline-style) var(--focus-outline-color-light);
38+
outline-offset: var(--focus-outline-offset);
39+
}
40+
41+
/* Enhanced focus for interactive elements */
42+
a:focus-visible,
43+
button:focus-visible,
44+
[role='button']:focus-visible,
45+
[role='link']:focus-visible,
46+
[tabindex]:focus-visible {
47+
outline: var(--focus-outline-width) var(--focus-outline-style) var(--focus-outline-color-light);
48+
outline-offset: var(--focus-outline-offset);
49+
}
50+
51+
/* Form controls need special handling */
52+
input:focus-visible,
53+
textarea:focus-visible,
54+
select:focus-visible {
55+
outline: var(--focus-outline-width) var(--focus-outline-style) var(--focus-outline-color-light);
56+
outline-offset: 1px; /* Tighter offset for form controls */
57+
}
58+
59+
/* Checkbox and radio buttons */
60+
input[type='checkbox']:focus-visible,
61+
input[type='radio']:focus-visible {
62+
outline: var(--focus-outline-width) var(--focus-outline-style) var(--focus-outline-color-light);
63+
outline-offset: 2px;
64+
}
65+
66+
/* For elements where outline might be cut off, use box-shadow */
67+
.focus-shadow:focus-visible {
68+
outline: none;
69+
box-shadow: var(--focus-shadow-light);
70+
}
71+
72+
/* High contrast mode support */
73+
@media (prefers-contrast: high) {
74+
*:focus-visible {
75+
outline-width: 3px;
76+
outline-color: highlight;
77+
}
78+
}
79+
80+
/* Focus for elements that might have complex backgrounds */
81+
.focus-high-contrast:focus-visible {
82+
outline: 3px solid var(--focus-outline-color-light);
83+
outline-offset: 2px;
84+
background-color: rgba(255, 255, 255, 0.9);
85+
86+
[data-theme='dark'] & {
87+
background-color: rgba(0, 0, 0, 0.9);
88+
}
89+
}
90+
91+
/* Skip link focus (for screen reader users) */
92+
.skip-link:focus-visible {
93+
position: absolute;
94+
top: 10px;
95+
left: 10px;
96+
z-index: 9999;
97+
padding: 8px 16px;
98+
background: var(--focus-outline-color-light);
99+
color: white;
100+
text-decoration: none;
101+
border-radius: 4px;
102+
outline: 2px solid white;
103+
outline-offset: 2px;
104+
}
105+
106+
/* Ensure focus is visible even when using custom components */
107+
.custom-focus:focus-visible {
108+
position: relative;
109+
}
110+
111+
.custom-focus:focus-visible::after {
112+
content: '';
113+
position: absolute;
114+
top: -2px;
115+
right: -2px;
116+
bottom: -2px;
117+
left: -2px;
118+
border: var(--focus-outline-width) var(--focus-outline-style) var(--focus-outline-color-light);
119+
border-radius: inherit;
120+
pointer-events: none;
121+
}
122+
123+
/* Focus indicators that work well with rounded corners */
124+
.focus-rounded:focus-visible {
125+
outline: var(--focus-outline-width) var(--focus-outline-style) var(--focus-outline-color-light);
126+
outline-offset: var(--focus-outline-offset);
127+
border-radius: inherit;
128+
}
129+
130+
/* Error state focus */
131+
.focus-error:focus-visible {
132+
outline-color: var(--focus-outline-warning);
133+
}
134+
135+
/* Success state focus */
136+
.focus-success:focus-visible {
137+
outline-color: var(--focus-outline-success);
138+
}
139+
140+
/* Reduced motion support */
141+
@media (prefers-reduced-motion: no-preference) {
142+
*:focus-visible {
143+
transition: outline-color 0.15s ease-in-out;
144+
}
145+
}

src/scss/commons/_reset.scss

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -152,12 +152,6 @@ button {
152152
background: none;
153153
}
154154

155-
a,
156-
li,
157-
button {
158-
outline-color: var(--general-white);
159-
}
160-
161155
input,
162156
select,
163157
button,
@@ -168,7 +162,6 @@ textarea {
168162

169163
appearance: none;
170164
border: none;
171-
outline: none;
172165
}
173166

174167
input[type='submit'] {

0 commit comments

Comments
 (0)