@codelaw/rules-html 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +23 -0
- package/NOTICE +24 -0
- package/README.md +162 -2
- package/codelaw-pack.toml +6 -0
- package/data/html/elements.json +4892 -0
- package/data/html/entities.json +1 -0
- package/data/html/input-attributes.json +227 -0
- package/package.json +14 -4
- package/presets/html/a11y.toml +29 -0
- package/presets/html/conventions.toml +6 -0
- package/presets/html/document.toml +8 -0
- package/presets/html/recommended.toml +67 -0
- package/rules/html/area-alt.md +48 -0
- package/rules/html/aria-hidden-body.md +39 -0
- package/rules/html/aria-label-misuse.md +42 -0
- package/rules/html/attribute-allowed-values.cases.md +31 -0
- package/rules/html/attribute-allowed-values.md +41 -0
- package/rules/html/attribute-misuse.md +39 -0
- package/rules/html/autocomplete-password.md +41 -0
- package/rules/html/button-type.cases.md +28 -0
- package/rules/html/button-type.md +35 -0
- package/rules/html/close-attr.md +33 -0
- package/rules/html/close-order.cases.md +38 -0
- package/rules/html/close-order.md +47 -0
- package/rules/html/deprecated.md +39 -0
- package/rules/html/doctype-html.md +36 -0
- package/rules/html/element-name.cases.md +21 -0
- package/rules/html/element-name.md +42 -0
- package/rules/html/element-permitted-content.cases.md +54 -0
- package/rules/html/element-permitted-content.md +45 -0
- package/rules/html/element-permitted-occurrences.md +45 -0
- package/rules/html/element-permitted-order.md +44 -0
- package/rules/html/element-permitted-parent.cases.md +11 -0
- package/rules/html/element-permitted-parent.md +43 -0
- package/rules/html/element-required-ancestor.md +45 -0
- package/rules/html/element-required-attributes.md +44 -0
- package/rules/html/element-required-content.cases.md +23 -0
- package/rules/html/element-required-content.md +43 -0
- package/rules/html/empty-heading.md +40 -0
- package/rules/html/empty-title.md +39 -0
- package/rules/html/fieldset-legend.md +44 -0
- package/rules/html/form-dup-name.cases.md +38 -0
- package/rules/html/form-dup-name.md +48 -0
- package/rules/html/form-submit.md +44 -0
- package/rules/html/heading-level.cases.md +26 -0
- package/rules/html/heading-level.md +44 -0
- package/rules/html/hidden-focusable.cases.md +23 -0
- package/rules/html/hidden-focusable.md +40 -0
- package/rules/html/img-alt.cases.md +22 -0
- package/rules/html/img-alt.md +44 -0
- package/rules/html/img-title.md +40 -0
- package/rules/html/input-attributes.md +34 -0
- package/rules/html/input-image-alt.md +39 -0
- package/rules/html/input-missing-label.md +40 -0
- package/rules/html/link-text.md +39 -0
- package/rules/html/long-title.md +40 -0
- package/rules/html/map-dup-name.md +40 -0
- package/rules/html/map-id-name.md +38 -0
- package/rules/html/meta-refresh.md +42 -0
- package/rules/html/missing-doctype.cases.md +24 -0
- package/rules/html/missing-doctype.md +43 -0
- package/rules/html/multiple-labeled-controls.md +40 -0
- package/rules/html/no-abstract-role.md +39 -0
- package/rules/html/no-autoplay.md +37 -0
- package/rules/html/no-conditional-comment.md +39 -0
- package/rules/html/no-deprecated-attr.md +39 -0
- package/rules/html/no-dup-attr.md +37 -0
- package/rules/html/no-dup-class.md +33 -0
- package/rules/html/no-duplicate-id.cases.md +23 -0
- package/rules/html/no-duplicate-id.md +42 -0
- package/rules/html/no-implicit-close.cases.md +38 -0
- package/rules/html/no-implicit-close.md +40 -0
- package/rules/html/no-implicit-input-type.md +34 -0
- package/rules/html/no-inline-script.md +42 -0
- package/rules/html/no-inline-style.cases.md +12 -0
- package/rules/html/no-inline-style.md +42 -0
- package/rules/html/no-missing-references.md +39 -0
- package/rules/html/no-multiple-main.md +40 -0
- package/rules/html/no-raw-characters.cases.md +84 -0
- package/rules/html/no-raw-characters.md +35 -0
- package/rules/html/no-redundant-aria-label.md +36 -0
- package/rules/html/no-redundant-for.md +34 -0
- package/rules/html/no-redundant-role.md +42 -0
- package/rules/html/no-utf8-bom.md +45 -0
- package/rules/html/prefer-button.md +39 -0
- package/rules/html/prefer-native-element.md +40 -0
- package/rules/html/prefer-tbody.md +41 -0
- package/rules/html/require-sri.md +41 -0
- package/rules/html/script-element.md +36 -0
- package/rules/html/script-type.md +33 -0
- package/rules/html/target-blank-rel.cases.md +35 -0
- package/rules/html/target-blank-rel.md +32 -0
- package/rules/html/tel-non-breaking.md +37 -0
- package/rules/html/text-content.md +39 -0
- package/rules/html/th-scope.md +47 -0
- package/rules/html/unique-landmark.md +41 -0
- package/rules/html/unrecognized-char-ref.cases.md +41 -0
- package/rules/html/unrecognized-char-ref.md +42 -0
- package/rules/html/valid-autocomplete.cases.md +42 -0
- package/rules/html/valid-autocomplete.md +42 -0
- package/rules/html/valid-for.md +40 -0
- package/rules/html/valid-id.md +40 -0
- package/rules/html/void-content.md +34 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: html/attribute-allowed-values
|
|
3
|
+
title: "Attributes have values HTML allows"
|
|
4
|
+
languages: [html]
|
|
5
|
+
fix: manual
|
|
6
|
+
fix_reason: "the intended value can only be guessed"
|
|
7
|
+
stability: preview
|
|
8
|
+
ported_from: [html-validate/attribute-allowed-values, htmlhint/src-not-empty]
|
|
9
|
+
since: 0.1.0
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
An attribute with a fixed set of values (`type`, `dir`, `loading`, …) uses one of them; a boolean attribute (`disabled`, `checked`) is written bare or with its own name; a numeric attribute holds a number.
|
|
13
|
+
|
|
14
|
+
**Why:** Browsers fall back to a default for a value they don't know, so a typo silently changes behaviour.
|
|
15
|
+
|
|
16
|
+
```codelaw
|
|
17
|
+
native: html/attribute-allowed-values
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## How to fix
|
|
21
|
+
|
|
22
|
+
1. Check the attribute's allowed values (the message lists the one written).
|
|
23
|
+
2. Correct the value, or remove the attribute to get the default.
|
|
24
|
+
|
|
25
|
+
## Examples
|
|
26
|
+
|
|
27
|
+
### HTML
|
|
28
|
+
|
|
29
|
+
#### Don't
|
|
30
|
+
|
|
31
|
+
```html
|
|
32
|
+
<input type="emial" name="email">
|
|
33
|
+
<img src="a.png" alt="A" loading="later">
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
#### Do
|
|
37
|
+
|
|
38
|
+
```html
|
|
39
|
+
<input type="email" name="email">
|
|
40
|
+
<img src="a.png" alt="A" loading="lazy">
|
|
41
|
+
```
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: html/attribute-misuse
|
|
3
|
+
title: "Attributes are used only where they take effect"
|
|
4
|
+
languages: [html]
|
|
5
|
+
fix: manual
|
|
6
|
+
fix_reason: "either the attribute or its context is wrong, and only the author knows which"
|
|
7
|
+
stability: preview
|
|
8
|
+
ported_from: [html-validate/attribute-misuse]
|
|
9
|
+
since: 0.1.0
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
An attribute that only works in a given context is used there: `formaction` on a submit button, `target` on a link with `href`, `coords` with a `shape` that needs them, and similar.
|
|
13
|
+
|
|
14
|
+
**Why:** Outside that context the browser ignores the attribute, so the author's intent is lost.
|
|
15
|
+
|
|
16
|
+
```codelaw
|
|
17
|
+
native: html/attribute-misuse
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## How to fix
|
|
21
|
+
|
|
22
|
+
1. Read the message: it names the attribute and what it needs.
|
|
23
|
+
2. Add the missing context (for example `href` or `type="submit"`), or remove the attribute.
|
|
24
|
+
|
|
25
|
+
## Examples
|
|
26
|
+
|
|
27
|
+
### HTML
|
|
28
|
+
|
|
29
|
+
#### Don't
|
|
30
|
+
|
|
31
|
+
```html
|
|
32
|
+
<button type="button" formaction="/save">Save</button>
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
#### Do
|
|
36
|
+
|
|
37
|
+
```html
|
|
38
|
+
<button type="submit" formaction="/save">Save</button>
|
|
39
|
+
```
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: html/autocomplete-password
|
|
3
|
+
title: "Password fields say which password they want"
|
|
4
|
+
languages: [html]
|
|
5
|
+
fix: manual
|
|
6
|
+
fix_reason: "whether the field asks for a new or the current password depends on the form"
|
|
7
|
+
stability: preview
|
|
8
|
+
options:
|
|
9
|
+
preferred: { type: "string", default: "", description: "one value every password field must use, such as `current-password`" }
|
|
10
|
+
ported_from: [html-validate/autocomplete-password]
|
|
11
|
+
since: 0.1.0
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
An `<input type="password">` has `autocomplete`, set to `new-password` or `current-password`, not `off`.
|
|
15
|
+
|
|
16
|
+
**Why:** Password managers autofill password fields anyway; saying which kind stops them filling a saved password into a "new password" field.
|
|
17
|
+
|
|
18
|
+
```codelaw
|
|
19
|
+
native: html/autocomplete-password
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## How to fix
|
|
23
|
+
|
|
24
|
+
1. Use `autocomplete="current-password"` on a sign-in form.
|
|
25
|
+
2. Use `autocomplete="new-password"` on a sign-up or change-password form.
|
|
26
|
+
|
|
27
|
+
## Examples
|
|
28
|
+
|
|
29
|
+
### HTML
|
|
30
|
+
|
|
31
|
+
#### Don't
|
|
32
|
+
|
|
33
|
+
```html
|
|
34
|
+
<input type="password" name="pw">
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
#### Do
|
|
38
|
+
|
|
39
|
+
```html
|
|
40
|
+
<input type="password" name="pw" autocomplete="current-password">
|
|
41
|
+
```
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# html/button-type — cases
|
|
2
|
+
|
|
3
|
+
### case: a button inside a select is the picker button
|
|
4
|
+
|
|
5
|
+
```html
|
|
6
|
+
<select>
|
|
7
|
+
<button>Pick</button>
|
|
8
|
+
<option>a</option>
|
|
9
|
+
</select>
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
```expect
|
|
13
|
+
(none)
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
### case: attributes stay after the inserted type
|
|
17
|
+
|
|
18
|
+
```html
|
|
19
|
+
<button class="x">Go</button>
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
```expect
|
|
23
|
+
1:1 html/button-type
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
```fixed
|
|
27
|
+
<button type="button" class="x">Go</button>
|
|
28
|
+
```
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: html/button-type
|
|
3
|
+
title: "<button> says what type it is"
|
|
4
|
+
languages: [html]
|
|
5
|
+
fix: suggest
|
|
6
|
+
fix_reason: "`type=\"button\"` stops the button submitting its form; a button meant to submit needs `type=\"submit\"` instead"
|
|
7
|
+
stability: preview
|
|
8
|
+
ported_from: [html-validate/no-implicit-button-type, htmlhint/button-type-require]
|
|
9
|
+
tags: [a11y]
|
|
10
|
+
since: 0.1.0
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
A `<button>` has a `type` attribute (`button`, `submit` or `reset`).
|
|
14
|
+
|
|
15
|
+
**Why:** Without one a button submits its form, so a button meant to open a menu also sends the form, also when the user presses Enter.
|
|
16
|
+
|
|
17
|
+
```codelaw
|
|
18
|
+
native: html/button-type
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Examples
|
|
22
|
+
|
|
23
|
+
### HTML
|
|
24
|
+
|
|
25
|
+
#### Don't
|
|
26
|
+
|
|
27
|
+
```html
|
|
28
|
+
<button>Open menu</button>
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
#### Do
|
|
32
|
+
|
|
33
|
+
```html
|
|
34
|
+
<button type="button">Open menu</button>
|
|
35
|
+
```
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: html/close-attr
|
|
3
|
+
title: "End tags have no attributes"
|
|
4
|
+
languages: [html]
|
|
5
|
+
fix: auto
|
|
6
|
+
stability: preview
|
|
7
|
+
ported_from: [html-validate/close-attr]
|
|
8
|
+
since: 0.1.0
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
An end tag is just `</name>`, with no attributes.
|
|
12
|
+
|
|
13
|
+
**Why:** HTML ignores attributes on an end tag, so they are dead text that looks meaningful.
|
|
14
|
+
|
|
15
|
+
```codelaw
|
|
16
|
+
native: html/close-attr
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Examples
|
|
20
|
+
|
|
21
|
+
### HTML
|
|
22
|
+
|
|
23
|
+
#### Don't
|
|
24
|
+
|
|
25
|
+
```html
|
|
26
|
+
<p>Text</p class="intro">
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
#### Do
|
|
30
|
+
|
|
31
|
+
```html
|
|
32
|
+
<p>Text</p>
|
|
33
|
+
```
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# html/close-order — cases
|
|
2
|
+
|
|
3
|
+
### case: a pre closes an open paragraph, so its end tag is stray
|
|
4
|
+
|
|
5
|
+
```html
|
|
6
|
+
<p>
|
|
7
|
+
Text
|
|
8
|
+
<pre>code</pre>
|
|
9
|
+
more
|
|
10
|
+
</p>
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
```expect
|
|
14
|
+
5:1 html/close-order
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
### case: optional end tags are not unclosed
|
|
18
|
+
|
|
19
|
+
```html
|
|
20
|
+
<table>
|
|
21
|
+
<tr><td>1<td>2
|
|
22
|
+
</table>
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
```expect
|
|
26
|
+
(none)
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### case: a missing start tag
|
|
30
|
+
|
|
31
|
+
```html
|
|
32
|
+
<head><title>t</title></head>
|
|
33
|
+
</html>
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
```expect
|
|
37
|
+
2:1 html/close-order
|
|
38
|
+
```
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: html/close-order
|
|
3
|
+
title: "Elements are closed, and in the order they were opened"
|
|
4
|
+
languages: [html]
|
|
5
|
+
fix: manual
|
|
6
|
+
fix_reason: "where the missing end tag belongs depends on the intended structure"
|
|
7
|
+
stability: preview
|
|
8
|
+
ported_from: [html-validate/close-order, htmlhint/tag-pair]
|
|
9
|
+
since: 0.1.0
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
Every element whose end tag is required is closed, and no end tag closes an element that isn't open.
|
|
13
|
+
|
|
14
|
+
**Why:** Browsers repair mismatched tags by guessing, and the guess often nests content differently from what the author meant.
|
|
15
|
+
|
|
16
|
+
```codelaw
|
|
17
|
+
native: html/close-order
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## How to fix
|
|
21
|
+
|
|
22
|
+
1. Find where the element named in the message should end.
|
|
23
|
+
2. Add its end tag there, or remove an end tag that closes nothing.
|
|
24
|
+
|
|
25
|
+
## Examples
|
|
26
|
+
|
|
27
|
+
### HTML
|
|
28
|
+
|
|
29
|
+
#### Don't
|
|
30
|
+
|
|
31
|
+
```html
|
|
32
|
+
<div>
|
|
33
|
+
<span>Text
|
|
34
|
+
</div>
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
#### Do
|
|
38
|
+
|
|
39
|
+
```html
|
|
40
|
+
<div>
|
|
41
|
+
<span>Text</span>
|
|
42
|
+
</div>
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Differences from the source
|
|
46
|
+
|
|
47
|
+
Elements whose end tag HTML lets you leave out (`<li>`, `<p>`, `<td>`, …) are not reported here; `html/no-implicit-close` reports them.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: html/deprecated
|
|
3
|
+
title: "No obsolete elements"
|
|
4
|
+
languages: [html]
|
|
5
|
+
fix: manual
|
|
6
|
+
fix_reason: "the replacement — CSS, a semantic element, or nothing — depends on the intent"
|
|
7
|
+
stability: preview
|
|
8
|
+
ported_from: [html-validate/deprecated, htmlhint/tag-no-obsolete]
|
|
9
|
+
since: 0.1.0
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
The document uses no element HTML has made obsolete: `<center>`, `<font>`, `<marquee>`, `<frame>`, `<tt>` and the rest.
|
|
13
|
+
|
|
14
|
+
**Why:** Obsolete elements have no defined meaning, and some are rendered differently, or not at all, by current browsers.
|
|
15
|
+
|
|
16
|
+
```codelaw
|
|
17
|
+
native: html/deprecated
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## How to fix
|
|
21
|
+
|
|
22
|
+
1. Read the message for the usual replacement.
|
|
23
|
+
2. Use that element, or a class and CSS, instead.
|
|
24
|
+
|
|
25
|
+
## Examples
|
|
26
|
+
|
|
27
|
+
### HTML
|
|
28
|
+
|
|
29
|
+
#### Don't
|
|
30
|
+
|
|
31
|
+
```html
|
|
32
|
+
<center>Welcome</center>
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
#### Do
|
|
36
|
+
|
|
37
|
+
```html
|
|
38
|
+
<div class="centered">Welcome</div>
|
|
39
|
+
```
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: html/doctype-html
|
|
3
|
+
title: "The doctype is the HTML5 one"
|
|
4
|
+
languages: [html]
|
|
5
|
+
fix: suggest
|
|
6
|
+
fix_reason: "switching to standards mode can change the page's layout"
|
|
7
|
+
stability: preview
|
|
8
|
+
ported_from: [html-validate/doctype-html, htmlhint/doctype-html5]
|
|
9
|
+
since: 0.1.0
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
The doctype is `<!DOCTYPE html>`, not an HTML 4 or XHTML one.
|
|
13
|
+
|
|
14
|
+
**Why:** Legacy doctypes can put the browser in a quirks or "almost standards" mode, which lays pages out differently.
|
|
15
|
+
|
|
16
|
+
```codelaw
|
|
17
|
+
native: html/doctype-html
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Examples
|
|
21
|
+
|
|
22
|
+
### HTML
|
|
23
|
+
|
|
24
|
+
#### Don't
|
|
25
|
+
|
|
26
|
+
```html
|
|
27
|
+
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
|
28
|
+
<p>Hello</p>
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
#### Do
|
|
32
|
+
|
|
33
|
+
```html
|
|
34
|
+
<!DOCTYPE html>
|
|
35
|
+
<p>Hello</p>
|
|
36
|
+
```
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# html/element-name — cases
|
|
2
|
+
|
|
3
|
+
### case: svg children have their own names
|
|
4
|
+
|
|
5
|
+
```html
|
|
6
|
+
<svg><foreignObject></foreignObject><linearGradient></linearGradient></svg>
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
```expect
|
|
10
|
+
(none)
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### case: namespaced names are left alone
|
|
14
|
+
|
|
15
|
+
```html
|
|
16
|
+
<o:p></o:p>
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
```expect
|
|
20
|
+
(none)
|
|
21
|
+
```
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: html/element-name
|
|
3
|
+
title: "Element names are HTML elements or valid custom elements"
|
|
4
|
+
languages: [html]
|
|
5
|
+
fix: manual
|
|
6
|
+
fix_reason: "renaming an element changes its CSS and script hooks"
|
|
7
|
+
stability: preview
|
|
8
|
+
options:
|
|
9
|
+
allow: { type: "string[]", default: [], description: "more element names to accept" }
|
|
10
|
+
ported_from: [html-validate/element-name]
|
|
11
|
+
since: 0.1.0
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
Every element is either an HTML element or a custom element whose name starts with a lowercase letter and contains a hyphen.
|
|
15
|
+
|
|
16
|
+
**Why:** An unknown element without a hyphen is a typo or an invalid custom element, and the browser treats it as an inline element with no meaning.
|
|
17
|
+
|
|
18
|
+
```codelaw
|
|
19
|
+
native: html/element-name
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## How to fix
|
|
23
|
+
|
|
24
|
+
1. If the name is a typo of an HTML element, correct it.
|
|
25
|
+
2. If it is a custom element, give it a hyphenated name and rename its definition.
|
|
26
|
+
3. If a framework needs the name, add it to the `allow` option.
|
|
27
|
+
|
|
28
|
+
## Examples
|
|
29
|
+
|
|
30
|
+
### HTML
|
|
31
|
+
|
|
32
|
+
#### Don't
|
|
33
|
+
|
|
34
|
+
```html
|
|
35
|
+
<widget>Hi</widget>
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
#### Do
|
|
39
|
+
|
|
40
|
+
```html
|
|
41
|
+
<x-widget>Hi</x-widget>
|
|
42
|
+
```
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# html/element-permitted-content — cases
|
|
2
|
+
|
|
3
|
+
### case: obsolete elements are left to html/deprecated
|
|
4
|
+
|
|
5
|
+
```html
|
|
6
|
+
<p>Use <tt>make</tt> here.</p>
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
```expect
|
|
10
|
+
(none)
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### case: a transparent link passes its content through
|
|
14
|
+
|
|
15
|
+
```html
|
|
16
|
+
<p><a href="/a"><div>Block</div></a></p>
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
```expect
|
|
20
|
+
1:17 html/element-permitted-content
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### case: the svg content model is not HTML
|
|
24
|
+
|
|
25
|
+
```html
|
|
26
|
+
<p><svg><g><rect width="1" height="1"></rect></g></svg></p>
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
```expect
|
|
30
|
+
(none)
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### case: a list nested directly in a list
|
|
34
|
+
|
|
35
|
+
```html
|
|
36
|
+
<ul>
|
|
37
|
+
<li>One</li>
|
|
38
|
+
<ul><li>Two</li></ul>
|
|
39
|
+
</ul>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
```expect
|
|
43
|
+
3:3 html/element-permitted-content
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### case: content of a template is checked against its own parent
|
|
47
|
+
|
|
48
|
+
```html
|
|
49
|
+
<template><td>1</td></template>
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
```expect
|
|
53
|
+
(none)
|
|
54
|
+
```
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: html/element-permitted-content
|
|
3
|
+
title: "Elements contain only content HTML allows there"
|
|
4
|
+
languages: [html]
|
|
5
|
+
fix: manual
|
|
6
|
+
fix_reason: "the right structure depends on what the markup is for"
|
|
7
|
+
stability: preview
|
|
8
|
+
ported_from: [html-validate/element-permitted-content]
|
|
9
|
+
since: 0.1.0
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
Each element contains only the elements its content model allows: no `<div>` inside a `<span>` or `<p>`, nothing interactive inside a link or button, no `<li>` directly inside a `<div>`.
|
|
13
|
+
|
|
14
|
+
**Why:** Browsers repair forbidden nesting by moving elements, so the DOM differs from the markup and styles and scripts miss.
|
|
15
|
+
|
|
16
|
+
```codelaw
|
|
17
|
+
native: html/element-permitted-content
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## How to fix
|
|
21
|
+
|
|
22
|
+
1. Move the element named in the message out of the parent it can't be in.
|
|
23
|
+
2. Or change the parent to one that allows it (for example `<div>` instead of `<span>`).
|
|
24
|
+
|
|
25
|
+
## Examples
|
|
26
|
+
|
|
27
|
+
### HTML
|
|
28
|
+
|
|
29
|
+
#### Don't
|
|
30
|
+
|
|
31
|
+
```html
|
|
32
|
+
<p><div>Block</div></p>
|
|
33
|
+
<a href="/a"><button type="button">Go</button></a>
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
#### Do
|
|
37
|
+
|
|
38
|
+
```html
|
|
39
|
+
<div><p>Block</p></div>
|
|
40
|
+
<a href="/a">Go</a>
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Differences from the source
|
|
44
|
+
|
|
45
|
+
Obsolete elements (`<tt>`, `<font>`, `<acronym>`, …) have no content model in the element table, so html-validate reports them wherever they are; here they are left to `html/deprecated`, which reports each once.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: html/element-permitted-occurrences
|
|
3
|
+
title: "Elements that may appear once do"
|
|
4
|
+
languages: [html]
|
|
5
|
+
fix: manual
|
|
6
|
+
fix_reason: "which of the duplicates to keep is the author's call"
|
|
7
|
+
stability: preview
|
|
8
|
+
ported_from: [html-validate/element-permitted-occurrences]
|
|
9
|
+
since: 0.1.0
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
Children that may appear only once in their parent do: one `<caption>`, `<thead>` and `<tfoot>` per table, one `<title>` and `<base>` per head, one `<legend>` per fieldset.
|
|
13
|
+
|
|
14
|
+
**Why:** The browser uses the first one and ignores the rest.
|
|
15
|
+
|
|
16
|
+
```codelaw
|
|
17
|
+
native: html/element-permitted-occurrences
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## How to fix
|
|
21
|
+
|
|
22
|
+
1. Merge the duplicates into one, or remove the extra one.
|
|
23
|
+
|
|
24
|
+
## Examples
|
|
25
|
+
|
|
26
|
+
### HTML
|
|
27
|
+
|
|
28
|
+
#### Don't
|
|
29
|
+
|
|
30
|
+
```html
|
|
31
|
+
<table>
|
|
32
|
+
<caption>Prices</caption>
|
|
33
|
+
<caption>2024</caption>
|
|
34
|
+
<tr><td>1</td></tr>
|
|
35
|
+
</table>
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
#### Do
|
|
39
|
+
|
|
40
|
+
```html
|
|
41
|
+
<table>
|
|
42
|
+
<caption>Prices, 2024</caption>
|
|
43
|
+
<tr><td>1</td></tr>
|
|
44
|
+
</table>
|
|
45
|
+
```
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: html/element-permitted-order
|
|
3
|
+
title: "Children come in the order HTML requires"
|
|
4
|
+
languages: [html]
|
|
5
|
+
fix: manual
|
|
6
|
+
fix_reason: "moving markup may change how it is styled"
|
|
7
|
+
stability: preview
|
|
8
|
+
ported_from: [html-validate/element-permitted-order]
|
|
9
|
+
since: 0.1.0
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
Children with a required order are in it: in a table, `<caption>` then `<colgroup>`, `<thead>`, `<tbody>`/`<tr>`, `<tfoot>`; `<summary>` first in `<details>`; `<legend>` first in `<fieldset>`; `<source>` before `<img>` in `<picture>`.
|
|
13
|
+
|
|
14
|
+
**Why:** Out of order, browsers ignore or move the element, so it doesn't do its job.
|
|
15
|
+
|
|
16
|
+
```codelaw
|
|
17
|
+
native: html/element-permitted-order
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## How to fix
|
|
21
|
+
|
|
22
|
+
1. Move the element named in the message before the one it must precede.
|
|
23
|
+
|
|
24
|
+
## Examples
|
|
25
|
+
|
|
26
|
+
### HTML
|
|
27
|
+
|
|
28
|
+
#### Don't
|
|
29
|
+
|
|
30
|
+
```html
|
|
31
|
+
<details>
|
|
32
|
+
<p>More text</p>
|
|
33
|
+
<summary>Read more</summary>
|
|
34
|
+
</details>
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
#### Do
|
|
38
|
+
|
|
39
|
+
```html
|
|
40
|
+
<details>
|
|
41
|
+
<summary>Read more</summary>
|
|
42
|
+
<p>More text</p>
|
|
43
|
+
</details>
|
|
44
|
+
```
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: html/element-permitted-parent
|
|
3
|
+
title: "Elements have a parent HTML allows"
|
|
4
|
+
languages: [html]
|
|
5
|
+
fix: manual
|
|
6
|
+
fix_reason: "whether to wrap the element or change it depends on the intended structure"
|
|
7
|
+
stability: preview
|
|
8
|
+
ported_from: [html-validate/element-permitted-parent]
|
|
9
|
+
since: 0.1.0
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
Elements that need a particular parent have it: `<li>` in `<ul>`, `<ol>` or `<menu>`; `<title>` and `<base>` in `<head>`; `<head>` and `<body>` in `<html>`.
|
|
13
|
+
|
|
14
|
+
**Why:** Elsewhere they lose their meaning: an `<li>` outside a list is not a list item to assistive technology.
|
|
15
|
+
|
|
16
|
+
```codelaw
|
|
17
|
+
native: html/element-permitted-parent
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## How to fix
|
|
21
|
+
|
|
22
|
+
1. Wrap the element in the parent it needs.
|
|
23
|
+
2. Or replace it with an element that fits where it is.
|
|
24
|
+
|
|
25
|
+
## Examples
|
|
26
|
+
|
|
27
|
+
### HTML
|
|
28
|
+
|
|
29
|
+
#### Don't
|
|
30
|
+
|
|
31
|
+
```html
|
|
32
|
+
<div>
|
|
33
|
+
<li>Apples</li>
|
|
34
|
+
</div>
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
#### Do
|
|
38
|
+
|
|
39
|
+
```html
|
|
40
|
+
<ul>
|
|
41
|
+
<li>Apples</li>
|
|
42
|
+
</ul>
|
|
43
|
+
```
|