Skip to content

Commit 43d1d94

Browse files
AlmeroSteynbeefancohen
authored andcommitted
Add link-type styling recommendation to anchor-is-valid
1 parent 71819a0 commit 43d1d94

File tree

3 files changed

+47
-6
lines changed

3 files changed

+47
-6
lines changed

__tests__/src/rules/anchor-is-valid-test.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@ import rule from '../../../src/rules/anchor-is-valid';
1818

1919
const ruleTester = new RuleTester();
2020

21-
const preferButtonErrorMessage = 'Anchor used as a button. Anchors are primarily expected to navigate. Use the button element instead.';
21+
const preferButtonErrorMessage = 'Anchor used as a button. Anchors are primarily expected to navigate. Use the button element instead. Learn more: https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/anchor-is-valid.md';
2222

23-
const noHrefErrorMessage = 'The href attribute is required on an anchor. Provide a valid, navigable address as the href value.';
23+
const noHrefErrorMessage = 'The href attribute is required for an anchor to be keyboard accessible. Provide a valid, navigable address as the href value. If you cannot provide an href, but still need the element to resemble a link, use a button and change it with appropriate styles. Learn more: https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/anchor-is-valid.md';
2424

25-
const invalidHrefErrorMessage = 'The href attribute requires a valid address. Provide a valid, navigable address as the href value.';
25+
const invalidHrefErrorMessage = 'The href attribute requires a valid value to be accessible. Provide a valid, navigable address as the href value. If you cannot provide a valid href, but still need the element to resemble a link, use a button and change it with appropriate styles. Learn more: https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/anchor-is-valid.md';
2626

2727
const preferButtonexpectedError = {
2828
message: preferButtonErrorMessage,

docs/rules/anchor-is-valid.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,47 @@ If you need to create an interface element that the user can mouse over or mouse
8888

8989
In the example immediately above an `onClick` event handler was added to provide the same experience mouse users enjoy to keyboard-only and touch-screen users. Never fully rely on mouse events alone to expose functionality.
9090

91+
### Case: I understand the previous cases but still need an element resembling a link that is purely clickable
92+
93+
We recommend, without reserve, that elements resembling anchors should navigate. This will provide a superior user experience to a larger group of users out there.
94+
95+
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.
96+
97+
Again change the element to a `<button>`:
98+
99+
```jsx
100+
<button
101+
type="button"
102+
className="link-button"
103+
onClick={() => this.setState({showSomething: true})}>
104+
Press me, I look like a link
105+
</button>
106+
```
107+
108+
Then use styling to change its appearance to that of a link:
109+
110+
```css
111+
.link-button {
112+
background-color: transparent;
113+
border: none;
114+
cursor: pointer;
115+
text-decoration: underline;
116+
display: inline;
117+
margin: 0;
118+
padding: 0;
119+
}
120+
121+
.link-button:hover,
122+
.link-button:focus {
123+
text-decoration: none;
124+
}
125+
```
126+
127+
This button element can now also be used inline in text.
128+
129+
Once again we stress that this is an inferior implementation and some users will encounter difficulty to use your website, however, it will allow a larger group of people to interact with your website than the alternative of ignoring the rule's warning.
130+
131+
91132
### References
92133
1. [WebAIM - Introduction to Links and Hypertext](http://webaim.org/techniques/hypertext/)
93134
1. [Links vs. Buttons in Modern Web Applications](https://marcysutton.com/links-vs-buttons-in-modern-web-applications/)

src/rules/anchor-is-valid.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@ import { generateObjSchema, arraySchema, enumArraySchema } from '../util/schemas
1515

1616
const allAspects = ['noHref', 'invalidHref', 'preferButton'];
1717

18-
const preferButtonErrorMessage = 'Anchor used as a button. Anchors are primarily expected to navigate. Use the button element instead.';
18+
const preferButtonErrorMessage = 'Anchor used as a button. Anchors are primarily expected to navigate. Use the button element instead. Learn more: https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/anchor-is-valid.md';
1919

20-
const noHrefErrorMessage = 'The href attribute is required on an anchor. Provide a valid, navigable address as the href value.';
20+
const noHrefErrorMessage = 'The href attribute is required for an anchor to be keyboard accessible. Provide a valid, navigable address as the href value. If you cannot provide an href, but still need the element to resemble a link, use a button and change it with appropriate styles. Learn more: https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/anchor-is-valid.md';
2121

22-
const invalidHrefErrorMessage = 'The href attribute requires a valid address. Provide a valid, navigable address as the href value.';
22+
const invalidHrefErrorMessage = 'The href attribute requires a valid value to be accessible. Provide a valid, navigable address as the href value. If you cannot provide a valid href, but still need the element to resemble a link, use a button and change it with appropriate styles. Learn more: https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/anchor-is-valid.md';
2323

2424
const schema = generateObjSchema({
2525
components: arraySchema,

0 commit comments

Comments
 (0)