Skip to content

Commit c275964

Browse files
Anima-t3dljharb
authored andcommittedJul 11, 2020
[Docs] anchor-is-valid: general cleanup
- swap `div` for `span`, since `a` is an inline element.
1 parent 3df059e commit c275964

File tree

1 file changed

+54
-33
lines changed

1 file changed

+54
-33
lines changed
 

‎docs/rules/anchor-is-valid.md

+54-33
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,17 @@ This is exacerbated by the expectation sighted users have of how _buttons_ and _
1919
We are aware that sometimes _anchors_ are used instead of _buttons_ to achieve a specific visual design. When using the `<button>` element this can still be achieved with styling but, due to the meaning many people attach to the standard underlined `<a>` due its appearance, please reconsider this in the design.
2020

2121
Consider the following:
22+
2223
```jsx
23-
<a href="javascript:void(0)" onClick={foo} >Perform action</a>
24-
<a href="#" onClick={foo} >Perform action</a>
25-
<a onClick={foo} >Perform action</a>
24+
<a href="javascript:void(0)" onClick={foo}>Perform action</a>
25+
<a href="#" onClick={foo}>Perform action</a>
26+
<a onClick={foo}>Perform action</a>
2627
```
2728

2829
All these _anchor_ implementations indicate that the element is only used to execute JavaScript code. All the above should be replaced with:
30+
2931
```jsx
30-
<button onClick={foo} >Perform action</button>
32+
<button onClick={foo}>Perform action</button>
3133
```
3234

3335
### Case: I want navigable links
@@ -37,51 +39,60 @@ An `<a>` element without an `href` attribute no longer functions as a hyperlink.
3739
To properly function as a hyperlink, the `href` attribute should be present and also contain a valid _URL_. _JavaScript_ strings, empty values or using only **#** are not considered valid `href` values.
3840

3941
Valid `href` attributes values are:
42+
4043
```jsx
41-
<a href="/some/valid/uri" >Navigate to page</a>
42-
<a href="/some/valid/uri#top" >Navigate to page and location</a>
43-
<a href="#top" >Navigate to internal page location</a>
44+
<a href="/some/valid/uri">Navigate to page</a>
45+
<a href="/some/valid/uri#top">Navigate to page and location</a>
46+
<a href="#top">Navigate to internal page location</a>
4447
```
4548

46-
4749
### Case: I need the HTML to be interactive, don't I need to use an a tag for that?
48-
An `<a>` tag is not inherently interactive. Without an href attribute, it really is no different to a `<div>`.
50+
51+
An `<a>` tag is not inherently interactive. Without an href attribute, it really is no different from a `<span>`.
4952

5053
Let's look at an example that is not accessible by all users:
54+
5155
```jsx
5256
<a
53-
className={'thing'}
54-
onMouseEnter={() => this.setState({showSomething: true})}>
57+
className="thing"
58+
onMouseEnter={() => this.setState({ showSomething: true })}
59+
>
5560
{label}
5661
</a>
5762
```
5863

5964
If you need to create an interface element that the user can click on, consider using a button:
65+
6066
```jsx
6167
<button
62-
className={'thing'}
63-
onClick={() => this.setState({showSomething: true})}>
68+
className="thing"
69+
onClick={() => this.setState({ showSomething: true })}
70+
>
6471
{label}
6572
</button>
6673
```
6774

6875
If you want to navigate while providing the user with extra functionality, for example in the `onMouseEnter` event, use an anchor with an `href` attribute containing a URL or path as its value.
76+
6977
```jsx
7078
<a
7179
href={someValidPath}
72-
className={'thing'}
73-
onMouseEnter={() => this.setState({showSomething: true})}>
80+
className="thing"
81+
onMouseEnter={() => this.setState({ showSomething: true })}
82+
>
7483
{label}
7584
</a>
7685
```
7786

7887
If you need to create an interface element that the user can mouse over or mouse out of, consider using a div element. In this case, you may need to apply a role of presentation or an interactive role. Interactive ARIA roles include `button`, `link`, `checkbox`, `menuitem`, `menuitemcheckbox`, `menuitemradio`, `option`, `radio`, `searchbox`, `switch` and `textbox`.
88+
7989
```jsx
8090
<div
8191
role="menuitem"
82-
className={'thing'}
83-
onClick={() => this.setState({showSomething: true})}>
84-
onMouseEnter={() => this.setState({showSomething: true})}>
92+
className="thing"
93+
onClick={() => this.setState({ showSomething: true })}
94+
onMouseEnter={() => this.setState({ showSomething: true })}
95+
>
8596
{label}
8697
</div>
8798
```
@@ -118,16 +129,17 @@ We recommend, without reserve, that elements resembling anchors should navigate.
118129

119130
However, we understand that developers are not always in total control of the visual design of web applications. In cases where it is imperative to provide an element resembling an anchor that purely acts as a click target with no navigation as result, we would like to recommend a compromise.
120131

121-
Again change the element to a `<button>`:
132+
Again change the element to a `<button>`:
122133

123134
```jsx
124-
<button
135+
<button
125136
type="button"
126-
className="link-button"
127-
onClick={() => this.setState({showSomething: true})}>
128-
Press me, I look like a link
137+
className="link-button"
138+
onClick={() => this.setState({ showSomething: true })}
139+
>
140+
Press me, I look like a link
129141
</button>
130-
```
142+
```
131143

132144
Then use styling to change its appearance to that of a link:
133145

@@ -144,7 +156,7 @@ Then use styling to change its appearance to that of a link:
144156

145157
.link-button:hover,
146158
.link-button:focus {
147-
text-decoration: none;
159+
text-decoration: none;
148160
}
149161
```
150162

@@ -158,13 +170,16 @@ This rule takes one optional object argument of type object:
158170

159171
```json
160172
{
161-
"rules": {
162-
"jsx-a11y/anchor-is-valid": [ "error", {
163-
"components": [ "Link" ],
164-
"specialLink": [ "hrefLeft", "hrefRight" ],
165-
"aspects": [ "noHref", "invalidHref", "preferButton" ]
166-
}]
167-
}
173+
"rules": {
174+
"jsx-a11y/anchor-is-valid": [
175+
"error",
176+
{
177+
"components": ["Link"],
178+
"specialLink": ["hrefLeft", "hrefRight"],
179+
"aspects": ["noHref", "invalidHref", "preferButton"]
180+
}
181+
]
182+
}
168183
}
169184
```
170185

@@ -193,11 +208,12 @@ For the `aspects` option, these strings determine which sub-rules are run. This
193208

194209
The option can be used on its own or with the `components` and `specialLink` options.
195210

196-
If omitted, all sub-rule aspects will be run by default. This is the recommended configuration for all cases except where the rule becomes unusable due to well founded restrictions.
211+
If omitted, all sub-rule aspects will be run by default. This is the recommended configuration for all cases except where the rule becomes unusable due to well founded restrictions.
197212

198213
The option must contain at least one `aspect`.
199214

200215
### Succeed
216+
201217
```jsx
202218
<a href="https://github.com" />
203219
<a href="#section" />
@@ -214,6 +230,7 @@ The option must contain at least one `aspect`.
214230
### Fail
215231

216232
Anchors should be a button:
233+
217234
```jsx
218235
<a onClick={foo} />
219236
<a href="#" onClick={foo} />
@@ -225,13 +242,15 @@ Anchors should be a button:
225242
```
226243

227244
Missing `href` attribute:
245+
228246
```jsx
229247
<a />
230248
<a href={undefined} />
231249
<a href={null} />
232250
```
233251

234252
Invalid `href` attribute:
253+
235254
```jsx
236255
<a href="#" />
237256
<a href={"#"} />
@@ -242,9 +261,11 @@ Invalid `href` attribute:
242261
```
243262

244263
## Accessibility guidelines
264+
245265
- [WCAG 2.1.1](https://www.w3.org/WAI/WCAG21/Understanding/keyboard)
246266

247267
### Resources
268+
248269
- [WebAIM - Introduction to Links and Hypertext](http://webaim.org/techniques/hypertext/)
249270
- [Links vs. Buttons in Modern Web Applications](https://marcysutton.com/links-vs-buttons-in-modern-web-applications/)
250271
- [Using ARIA - Notes on ARIA use in HTML](https://www.w3.org/TR/using-aria/#NOTES)

0 commit comments

Comments
 (0)