mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
* Remove Kibana a11y styleguide in favor of EUI and moving auxilary content to CONTRIBUTING.md and STYLEGUIDE.md Co-Authored-By: Tim Roes <mail@timroes.de>
This commit is contained in:
parent
f6b43b46a8
commit
850e520072
3 changed files with 101 additions and 314 deletions
|
@ -27,6 +27,7 @@ A high level overview of our contributing guidelines.
|
|||
- [Instrumenting with Elastic APM](#instrumenting-with-elastic-apm)
|
||||
- [Debugging Unit Tests](#debugging-unit-tests)
|
||||
- [Unit Testing Plugins](#unit-testing-plugins)
|
||||
- [Automated Accessibility Testing](#automated-accessibility-testing)
|
||||
- [Cross-browser compatibility](#cross-browser-compatibility)
|
||||
- [Testing compatibility locally](#testing-compatibility-locally)
|
||||
- [Running Browser Automation Tests](#running-browser-automation-tests)
|
||||
|
@ -542,6 +543,23 @@ yarn test:mocha
|
|||
yarn test:browser --dev # remove the --dev flag to run them once and close
|
||||
```
|
||||
|
||||
### Automated Accessibility Testing
|
||||
|
||||
To run the tests locally:
|
||||
|
||||
1. In one terminal window run `node scripts/functional_tests_server --config test/accessibility/config.ts`
|
||||
2. In another terminal window run `node scripts/functional_test_runner.js --config test/accessibility/config.ts`
|
||||
|
||||
To run the x-pack tests, swap the config file out for `x-pack/test/accessibility/config.ts`.
|
||||
|
||||
After the server is up, you can go to this instance of Kibana at `localhost:5620`.
|
||||
|
||||
The testing is done using [axe](https://github.com/dequelabs/axe-core). The same thing that runs in CI,
|
||||
can be run locally using their browser plugins:
|
||||
|
||||
- [Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US)
|
||||
- [Firefox](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/)
|
||||
|
||||
### Cross-browser Compatibility
|
||||
|
||||
#### Testing Compatibility Locally
|
||||
|
|
111
STYLEGUIDE.md
111
STYLEGUIDE.md
|
@ -6,7 +6,7 @@ recommended for the development of all Kibana plugins.
|
|||
Besides the content in this style guide, the following style guides may also apply
|
||||
to all development within the Kibana project. Please make sure to also read them:
|
||||
|
||||
- [Accessibility style guide](style_guides/accessibility_guide.md)
|
||||
- [Accessibility style guide](https://elastic.github.io/eui/#/guidelines/accessibility)
|
||||
- [SASS style guide](https://elastic.github.io/eui/#/guidelines/sass)
|
||||
|
||||
## General
|
||||
|
@ -45,10 +45,7 @@ This part contains style guide rules around general (framework agnostic) HTML us
|
|||
Use camel case for the values of attributes such as `id` and `data-test-subj` selectors.
|
||||
|
||||
```html
|
||||
<button
|
||||
id="veryImportantButton"
|
||||
data-test-subj="clickMeButton"
|
||||
>
|
||||
<button id="veryImportantButton" data-test-subj="clickMeButton">
|
||||
Click me
|
||||
</button>
|
||||
```
|
||||
|
@ -74,6 +71,59 @@ It's important that when you write CSS/SASS selectors using classes, IDs, and at
|
|||
capitalization in the CSS matches that used in the HTML. HTML and CSS follow different case sensitivity rules, and we can avoid subtle gotchas by ensuring we use the
|
||||
same capitalization in both of them.
|
||||
|
||||
### How to generate ids?
|
||||
|
||||
When labeling elements (and for some other accessibility tasks) you will often need
|
||||
ids. Ids must be unique within the page i.e. no duplicate ids in the rendered DOM
|
||||
at any time.
|
||||
|
||||
Since we have some components that are used multiple times on the page, you must
|
||||
make sure every instance of that component has a unique `id`. To make the generation
|
||||
of those `id`s easier, you can use the `htmlIdGenerator` service in the `@elastic/eui`.
|
||||
|
||||
A React component could use it as follows:
|
||||
|
||||
```jsx
|
||||
import { htmlIdGenerator } from '@elastic/eui';
|
||||
|
||||
render() {
|
||||
// Create a new generator that will create ids deterministic
|
||||
const htmlId = htmlIdGenerator();
|
||||
return (<div>
|
||||
<label htmlFor={htmlId('agg')}>Aggregation</label>
|
||||
<input id={htmlId('agg')}/>
|
||||
</div>);
|
||||
}
|
||||
```
|
||||
|
||||
Each id generator you create by calling `htmlIdGenerator()` will generate unique but
|
||||
deterministic ids. As you can see in the above example, that single generator
|
||||
created the same id in the label's `htmlFor` as well as the input's `id`.
|
||||
|
||||
A single generator instance will create the same id when passed the same argument
|
||||
to the function multiple times. But two different generators will produce two different
|
||||
ids for the same argument to the function, as you can see in the following example:
|
||||
|
||||
```js
|
||||
const generatorOne = htmlIdGenerator();
|
||||
const generatorTwo = htmlIdGenerator();
|
||||
|
||||
// Those statements are always true:
|
||||
// Same generator
|
||||
generatorOne('foo') === generatorOne('foo');
|
||||
generatorOne('foo') !== generatorOne('bar');
|
||||
|
||||
// Different generator
|
||||
generatorOne('foo') !== generatorTwo('foo');
|
||||
```
|
||||
|
||||
This allows multiple instances of a single React component to now have different ids.
|
||||
If you include the above React component multiple times in the same page,
|
||||
each component instance will have a unique id, because each render method will use a different
|
||||
id generator.
|
||||
|
||||
You can also use this service outside of React.
|
||||
|
||||
## API endpoints
|
||||
|
||||
The following style guide rules are targeting development of server side API endpoints.
|
||||
|
@ -90,7 +140,8 @@ API routes must start with the `/api/` path segment, and should be followed by t
|
|||
|
||||
Kibana uses `snake_case` for the entire API, just like Elasticsearch. All urls, paths, query string parameters, values, and bodies should be `snake_case` formatted.
|
||||
|
||||
*Right:*
|
||||
_Right:_
|
||||
|
||||
```
|
||||
POST /api/kibana/index_patterns
|
||||
{
|
||||
|
@ -108,19 +159,19 @@ The following style guide rules apply for working with TypeScript/JavaScript fil
|
|||
|
||||
### TypeScript vs. JavaScript
|
||||
|
||||
Whenever possible, write code in TypeScript instead of JavaScript, especially if it's new code.
|
||||
Whenever possible, write code in TypeScript instead of JavaScript, especially if it's new code.
|
||||
Check out [TYPESCRIPT.md](TYPESCRIPT.md) for help with this process.
|
||||
|
||||
### Prefer modern JavaScript/TypeScript syntax
|
||||
|
||||
You should prefer modern language features in a lot of cases, e.g.:
|
||||
|
||||
* Prefer `class` over `prototype` inheritance
|
||||
* Prefer arrow function over function expressions
|
||||
* Prefer arrow function over storing `this` (no `const self = this;`)
|
||||
* Prefer template strings over string concatenation
|
||||
* Prefer the spread operator for copying arrays (`[...arr]`) over `arr.slice()`
|
||||
* Use optional chaining (`?.`) and nullish Coalescing (`??`) over `lodash.get` (and similar utilities)
|
||||
- Prefer `class` over `prototype` inheritance
|
||||
- Prefer arrow function over function expressions
|
||||
- Prefer arrow function over storing `this` (no `const self = this;`)
|
||||
- Prefer template strings over string concatenation
|
||||
- Prefer the spread operator for copying arrays (`[...arr]`) over `arr.slice()`
|
||||
- Use optional chaining (`?.`) and nullish Coalescing (`??`) over `lodash.get` (and similar utilities)
|
||||
|
||||
### Avoid mutability and state
|
||||
|
||||
|
@ -131,7 +182,7 @@ Instead, create new variables, and shallow copies of objects and arrays:
|
|||
```js
|
||||
// good
|
||||
function addBar(foos, foo) {
|
||||
const newFoo = {...foo, name: 'bar'};
|
||||
const newFoo = { ...foo, name: 'bar' };
|
||||
return [...foos, newFoo];
|
||||
}
|
||||
|
||||
|
@ -250,8 +301,8 @@ const second = arr[1];
|
|||
|
||||
### Magic numbers/strings
|
||||
|
||||
These are numbers (or other values) simply used in line in your code. *Do not
|
||||
use these*, give them a variable name so they can be understood and changed
|
||||
These are numbers (or other values) simply used in line in your code. _Do not
|
||||
use these_, give them a variable name so they can be understood and changed
|
||||
easily.
|
||||
|
||||
```js
|
||||
|
@ -325,19 +376,18 @@ import inSibling from '../foo/child';
|
|||
Don't do this. Everything should be wrapped in a module that can be depended on
|
||||
by other modules. Even things as simple as a single value should be a module.
|
||||
|
||||
|
||||
### Only use ternary operators for small, simple code
|
||||
|
||||
And *never* use multiple ternaries together, because they make it more
|
||||
And _never_ use multiple ternaries together, because they make it more
|
||||
difficult to reason about how different values flow through the conditions
|
||||
involved. Instead, structure the logic for maximum readability.
|
||||
|
||||
```js
|
||||
// good, a situation where only 1 ternary is needed
|
||||
const foo = (a === b) ? 1 : 2;
|
||||
const foo = a === b ? 1 : 2;
|
||||
|
||||
// bad
|
||||
const foo = (a === b) ? 1 : (a === c) ? 2 : 3;
|
||||
const foo = a === b ? 1 : a === c ? 2 : 3;
|
||||
```
|
||||
|
||||
### Use descriptive conditions
|
||||
|
@ -475,13 +525,12 @@ setTimeout(() => {
|
|||
|
||||
Use slashes for both single line and multi line comments. Try to write
|
||||
comments that explain higher level mechanisms or clarify difficult
|
||||
segments of your code. *Don't use comments to restate trivial things*.
|
||||
segments of your code. _Don't use comments to restate trivial things_.
|
||||
|
||||
*Exception:* Comment blocks describing a function and its arguments
|
||||
_Exception:_ Comment blocks describing a function and its arguments
|
||||
(docblock) should start with `/**`, contain a single `*` at the beginning of
|
||||
each line, and end with `*/`.
|
||||
|
||||
|
||||
```js
|
||||
// good
|
||||
|
||||
|
@ -546,11 +595,17 @@ You can read more about these two ngReact methods [here](https://github.com/ngRe
|
|||
Using `react-component` means adding a bunch of components into angular, while `reactDirective` keeps them isolated, and is also a more succinct syntax.
|
||||
|
||||
**Good:**
|
||||
|
||||
```html
|
||||
<hello-component fname="person.fname" lname="person.lname" watch-depth="reference"></hello-component>
|
||||
<hello-component
|
||||
fname="person.fname"
|
||||
lname="person.lname"
|
||||
watch-depth="reference"
|
||||
></hello-component>
|
||||
```
|
||||
|
||||
**Bad:**
|
||||
|
||||
```html
|
||||
<react-component name="HelloComponent" props="person" watch-depth="reference" />
|
||||
```
|
||||
|
@ -564,9 +619,9 @@ Name action functions in the form of a strong verb and passed properties in the
|
|||
<pagerButton onPageNext={action.turnToNextPage} />
|
||||
```
|
||||
|
||||
## Attribution
|
||||
## Attribution
|
||||
|
||||
Parts of the JavaScript style guide were initially forked from the
|
||||
[node style guide](https://github.com/felixge/node-style-guide) created by [Felix Geisendörfer](http://felixge.de/) which is
|
||||
licensed under the [CC BY-SA 3.0](http://creativecommons.org/licenses/by-sa/3.0/)
|
||||
Parts of the JavaScript style guide were initially forked from the
|
||||
[node style guide](https://github.com/felixge/node-style-guide) created by [Felix Geisendörfer](http://felixge.de/) which is
|
||||
licensed under the [CC BY-SA 3.0](http://creativecommons.org/licenses/by-sa/3.0/)
|
||||
license.
|
||||
|
|
|
@ -1,286 +0,0 @@
|
|||
# Accessibility (A11Y) Guide
|
||||
|
||||
This document provides some technical guidelines how to prevent several common
|
||||
accessibility issues.
|
||||
|
||||
## Naming elements
|
||||
|
||||
### `aria-label` and `aria-labelledby`
|
||||
|
||||
Every element on a page will have a name, that is read out to an assistive technology
|
||||
like a screen reader. This will for most elements be the content of the element.
|
||||
For form elements it will be the content of the associated `<label>` (see below).
|
||||
|
||||
You can overwrite that name, that is read out, by specifying a new name via the
|
||||
`aria-label` attribute. This must e.g. be done, if the element itself has no
|
||||
visual text representation (e.g. an icon button):
|
||||
|
||||
```html
|
||||
<button aria-label="Add filter"><span class="fa fa-plus"></span></button>
|
||||
```
|
||||
|
||||
If you have to use a form element without a related `<label>` element, you can use `aria-label`
|
||||
directly on the form element to provide labeling information to screen readers.
|
||||
|
||||
If the actual name for that element is already present in another element,
|
||||
you can use `aria-labelledby` to reference the id of that element:
|
||||
|
||||
```html
|
||||
<div id="datepicker">Date Picker</div>
|
||||
<button aria-labelledby="datepicker"><span class="fa fa-calendar"></span></button>
|
||||
```
|
||||
|
||||
### Label every form element
|
||||
|
||||
You should add a label for every form element:
|
||||
|
||||
```html
|
||||
<label for="interval">Interval</label>
|
||||
<select id="interval"><!-- ... --></select>
|
||||
```
|
||||
|
||||
If one label references multiple form elements, you can use the reverse logic
|
||||
and add `aria-labelledby` to all form elements:
|
||||
|
||||
```html
|
||||
<label id="fromLabel">From</label>
|
||||
<input type="number" aria-labelledby="fromLabel">
|
||||
<input type="number" aria-labelledby="fromLabel">
|
||||
<input type="number" aria-labelledby="fromLabel">
|
||||
```
|
||||
|
||||
You should always prefer the `<label for>` solution, since it also adds benefit
|
||||
for every user, by making the label clickable, to directly jump to the form
|
||||
element (or in case of checkboxes and radio buttons directly check them).
|
||||
|
||||
#### How to generate ids?
|
||||
|
||||
When labeling elements (and for some other accessibility tasks) you will often need
|
||||
ids. Ids must be unique within the page i.e. no duplicate ids in the rendered DOM
|
||||
at any time.
|
||||
|
||||
Since we have some components that are used multiple times on the page, you must
|
||||
make sure every instance of that component has a unique `id`. To make the generation
|
||||
of those `id`s easier, you can use the `htmlIdGenerator` service in the `@kbn/ui-framework/services`.
|
||||
|
||||
A react component could use it as follows:
|
||||
|
||||
```jsx
|
||||
import { htmlIdGenerator } from '@kbn/ui-framework/services';
|
||||
|
||||
render() {
|
||||
// Create a new generator that will create ids deterministic
|
||||
const htmlId = htmlIdGenerator();
|
||||
return (<div>
|
||||
<label htmlFor={htmlId('agg')}>Aggregation</label>
|
||||
<input id={htmlId('agg')}/>
|
||||
</div>);
|
||||
}
|
||||
```
|
||||
|
||||
Each id generator you create by calling `htmlIdGenerator()` will generate unique but
|
||||
deterministic ids. As you can see in the above example, that single generator
|
||||
created the same id in the label's `htmlFor` as well as the input's `id`.
|
||||
|
||||
A single generator instance will create the same id when passed the same argument
|
||||
to the function multiple times. But two different generators will produce two different
|
||||
ids for the same argument to the function, as you can see in the following example:
|
||||
|
||||
```js
|
||||
const generatorOne = htmlIdGenerator();
|
||||
const generatorTwo = htmlIdGenerator();
|
||||
|
||||
// Those statements are always true:
|
||||
// Same generator
|
||||
generatorOne('foo') === generatorOne('foo');
|
||||
generatorOne('foo') !== generatorOne('bar');
|
||||
|
||||
// Different generator
|
||||
generatorOne('foo') !== generatorTwo('foo')
|
||||
```
|
||||
|
||||
This allows multiple instances of a single react component to now have different ids.
|
||||
If you include the above react component multiple times in the same page,
|
||||
each component instance will have a unique id, because each render method will use a different
|
||||
id generator.
|
||||
|
||||
You can use this service of course also outside of react.
|
||||
|
||||
### Don't use the `title` attribute
|
||||
|
||||
**TL;DR** *Don't use the `title` attribute, use tooltips, `aria-label`, etc. instead.*
|
||||
|
||||
The `title` has no clear role within the accessibility standards.
|
||||
[See the HTML5 spec](http://w3c.github.io/html/dom.html#the-title-attribute) for more information.
|
||||
|
||||
To provide supplementary, descriptive information about a form control, button, link, or other element,
|
||||
that should also be visible to non vision impaired users, use a tooltip component instead.
|
||||
|
||||
If you need a label only for screen readers use `aria-label`.
|
||||
|
||||
**Additional reading:**
|
||||
|
||||
* https://www.paciellogroup.com/blog/2010/11/using-the-html-title-attribute/
|
||||
* https://www.paciellogroup.com/blog/2012/01/html5-accessibility-chops-title-attribute-use-and-abuse/
|
||||
* https://www.deque.com/blog/text-links-practices-screen-readers/
|
||||
|
||||
## Interactive elements
|
||||
|
||||
### Use `<button>` and `<a href>`
|
||||
|
||||
**TL;DR** *Use `<button>` or `<a>` (with `href`) instead of click listeners on other elements
|
||||
and style it whatever way you need.*
|
||||
|
||||
If you want to make an element clickable, use a `<button>` or `<a href>` element for it.
|
||||
Use a `<button>` whenever it causes an action on the current page, and an `<a href>` if it
|
||||
navigates to a different page. You can use click listeners just fine on these elements.
|
||||
|
||||
An `<a>` element must have an `href` attribute, so that (a) it will be correctly perceived
|
||||
as a link by a screen reader and (b) that registered click listener will correctly
|
||||
trigger on pressing <kbd>Enter</kbd>. If you don't need it, make it `href="#"`
|
||||
and call `preventDefault()` on the click event.
|
||||
|
||||
*Why not use other elements?*
|
||||
|
||||
If you create e.g. a `<div>` with a click listener (like `<div ng-click="ctrl.doSomething()">...</div>`)
|
||||
you will create multiple accessibility issues:
|
||||
|
||||
* The element is not *keyboard accessible*, meaning:
|
||||
* You cannot focus it by pressing <kbd>tab</kbd>. You can add this behavior by
|
||||
adding `tabindex="0"` to the element.
|
||||
* You cannot trigger the click by pressing <kbd>Enter</kbd> or <kbd>Space</kbd>.
|
||||
We have a `kbn-accessible-click` directive for AngularJS and a `KuiKeyboardAccessible`
|
||||
React component to add that behavior.
|
||||
* Even if you make it keyboard accessible, a user using a screen reader won't
|
||||
recognize, that the div is actually an interactive element, the screen reader
|
||||
will just announce something like: "Sort". You would need
|
||||
to add `role="button"` or `role="link"` to it, so that the screen reader would
|
||||
actually announce something like "Sort, button" and give the user the required
|
||||
information, that this element is interactive.
|
||||
|
||||
You will need quite some work just to rebuild native logic of a button (and we haven't
|
||||
even touched disabled states, etc.). It is most of the time easier to just use
|
||||
a `button` or an `a` and style this, whatever way you want it to look (even if
|
||||
you don't want it to look like a button at all).
|
||||
|
||||
### tabindex and id
|
||||
|
||||
**TL;DR** *Only use `tabindex="0"` and `tabindex="-1"` and no values above 0. Always
|
||||
add an `id` to an element with `tabindex`.*
|
||||
|
||||
If you want to make an element focusable, that doesn't offer this feature by default
|
||||
(i.e. isn't an form element or a link), you can add `tabindex` with a value >= 0 to it.
|
||||
|
||||
*Why shouldn't you use values above 0?*
|
||||
|
||||
Setting `tabindex="0"` will add the element to the tabbing order at the position
|
||||
it is in the DOM. Setting it to something above 0 will create an explicit order.
|
||||
Tabbing will always focus all elements with an tabindex > 0, starting from the smallest
|
||||
number. After all those elements has been tabbed, it will continue with all `tabindex="0"`
|
||||
or implicit tabable elements. These values are not scoped to a subtree of the
|
||||
DOM, but are global values. Maintaining a global order is nearly impossible
|
||||
and considered a [serious issue](https://dequeuniversity.com/rules/axe/1.1/tabindex)
|
||||
by automated accessibility testing frameworks.
|
||||
|
||||
`tabindex="-1"` will remove an element from tab order, that would be focusable
|
||||
otherwise. You won't need this often.
|
||||
|
||||
*Why should you add an `id`?*
|
||||
|
||||
Due to some bugs in some common screen readers, you will always need to add an `id`
|
||||
to an element with `tabindex`, since they wouldn't pick up the `tabindex` correctly
|
||||
otherwise.
|
||||
|
||||
### Tooltips
|
||||
|
||||
**TL;DR** *Add `role="tooltip"` and `aria-describedby` to elements for accessible tooltips.*
|
||||
|
||||
Elements which act as tooltips should have the `role="tooltip"` attribute and an ID to which the
|
||||
described element can point to with the `aria-describedby` attribute. For example:
|
||||
|
||||
```html
|
||||
<div
|
||||
class="kuiTooltip"
|
||||
role="tooltip"
|
||||
id="visualizationsTooltip"
|
||||
>
|
||||
Visualizations help you make sense of your data.
|
||||
</div>
|
||||
|
||||
<button aria-describedby="visualizationsTooltip">
|
||||
Visualizations
|
||||
</button>
|
||||
```
|
||||
|
||||
### Don't create keyboard traps
|
||||
|
||||
**TL;DR** *If you can't leave an element with <kbd>Tab</kbd> again, it needs a special interaction model.*
|
||||
|
||||
If an interactive element consumes the <kbd>Tab</kbd> key (e.g. a code editor to
|
||||
create an actual tabular indentation) it will prevent a keyboard user to leave
|
||||
that element again. Also see [WCAG 2.1.2](https://www.w3.org/TR/WCAG20/#keyboard-operation-trapping).
|
||||
|
||||
Those kind of elements, require a special interaction model. A [code editor](https://github.com/elastic/kibana/pull/13339)
|
||||
could require an <kbd>Enter</kbd> keypress before starting editing mode, and
|
||||
could leave that mode on <kbd>Escape</kbd> again.
|
||||
|
||||
Unfortunately there is no universal solution for this problem, so be aware when creating
|
||||
such elements, that would consume tabbing, to think about an accessible interaction
|
||||
model.
|
||||
|
||||
*Hint:* If you create that kind of interactive elements `role="application"` might
|
||||
be a good `role` (also see below) for that element. It is meant for elements providing
|
||||
their own interaction schemes.
|
||||
|
||||
## Roles
|
||||
|
||||
Each DOM element has an implicit role in the accessibility tree (that assistive technologies
|
||||
use). The mapping of elements to default roles can be found in the
|
||||
[Accessibility API Mappings](https://www.w3.org/TR/html-aam-1.0/#html-element-role-mappings).
|
||||
You can overwrite this role via the `role` attribute on an element, and the
|
||||
assistive technology will now behave the same like any other element with that role
|
||||
(e.g. behave like it is a button when it has `role="button"`).
|
||||
|
||||
### Landmark roles
|
||||
|
||||
Some roles can be used to declare so called landmarks. These landmarks tag important
|
||||
parts of a web page. Screen readers offer a quick way to jump to these
|
||||
parts of the page (*landmark navigation*).
|
||||
|
||||
#### role=main
|
||||
|
||||
The `main` role (or equivalent using the `<main>` tag) declares the main part
|
||||
of a page. This can be used in the landmark navigation to quickly jump to the
|
||||
actual main area of the page (and skip all headers, navigations, etc.).
|
||||
|
||||
#### `<section>`
|
||||
|
||||
The `<section>` element, can be used to mark a region on the page, so that it
|
||||
appears in the landmark navigation. The section element therefore needs to have
|
||||
an *accessible name*, i.e. you should add an `aria-label`, that gives a short
|
||||
title to that section of the page.
|
||||
|
||||
### role=search
|
||||
|
||||
**TL;DR** *Place `role="search"` neither on the `<input>` nor the `<form>`, but
|
||||
some `div` in between.*
|
||||
|
||||
Role search can be used to mark a region as used for searching. This can be used
|
||||
by assistive technologies to quickly find and navigate to this section.
|
||||
|
||||
If you place it on the `input` you will overwrite the implicit `textbox` or `searchbox`
|
||||
role, and as such confuse the user, since it loses it meaning as in input element.
|
||||
If you place it on the `form` element you will also overwrite its role and
|
||||
remove it from a quick jump navigation to all forms.
|
||||
|
||||
That's why it should be placed to an `div` (or any other container) between the
|
||||
`form` and the `input`. In most cases we already have a div there that you can
|
||||
easily put this role to.
|
||||
|
||||
**Related Links:**
|
||||
|
||||
* [Where to put your search role?](http://adrianroselli.com/2015/08/where-to-put-your-search-role.html)
|
||||
* Discussions about making `search` role inherit the `form` role:
|
||||
[wcag/113](https://github.com/w3c/wcag/issues/113),
|
||||
[html-aria/118](https://github.com/w3c/html-aria/issues/18),
|
||||
[aria/85](https://github.com/w3c/aria/issues/85)
|
Loading…
Add table
Add a link
Reference in a new issue