@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.
Files changed (103) hide show
  1. package/LICENSE +23 -0
  2. package/NOTICE +24 -0
  3. package/README.md +162 -2
  4. package/codelaw-pack.toml +6 -0
  5. package/data/html/elements.json +4892 -0
  6. package/data/html/entities.json +1 -0
  7. package/data/html/input-attributes.json +227 -0
  8. package/package.json +14 -4
  9. package/presets/html/a11y.toml +29 -0
  10. package/presets/html/conventions.toml +6 -0
  11. package/presets/html/document.toml +8 -0
  12. package/presets/html/recommended.toml +67 -0
  13. package/rules/html/area-alt.md +48 -0
  14. package/rules/html/aria-hidden-body.md +39 -0
  15. package/rules/html/aria-label-misuse.md +42 -0
  16. package/rules/html/attribute-allowed-values.cases.md +31 -0
  17. package/rules/html/attribute-allowed-values.md +41 -0
  18. package/rules/html/attribute-misuse.md +39 -0
  19. package/rules/html/autocomplete-password.md +41 -0
  20. package/rules/html/button-type.cases.md +28 -0
  21. package/rules/html/button-type.md +35 -0
  22. package/rules/html/close-attr.md +33 -0
  23. package/rules/html/close-order.cases.md +38 -0
  24. package/rules/html/close-order.md +47 -0
  25. package/rules/html/deprecated.md +39 -0
  26. package/rules/html/doctype-html.md +36 -0
  27. package/rules/html/element-name.cases.md +21 -0
  28. package/rules/html/element-name.md +42 -0
  29. package/rules/html/element-permitted-content.cases.md +54 -0
  30. package/rules/html/element-permitted-content.md +45 -0
  31. package/rules/html/element-permitted-occurrences.md +45 -0
  32. package/rules/html/element-permitted-order.md +44 -0
  33. package/rules/html/element-permitted-parent.cases.md +11 -0
  34. package/rules/html/element-permitted-parent.md +43 -0
  35. package/rules/html/element-required-ancestor.md +45 -0
  36. package/rules/html/element-required-attributes.md +44 -0
  37. package/rules/html/element-required-content.cases.md +23 -0
  38. package/rules/html/element-required-content.md +43 -0
  39. package/rules/html/empty-heading.md +40 -0
  40. package/rules/html/empty-title.md +39 -0
  41. package/rules/html/fieldset-legend.md +44 -0
  42. package/rules/html/form-dup-name.cases.md +38 -0
  43. package/rules/html/form-dup-name.md +48 -0
  44. package/rules/html/form-submit.md +44 -0
  45. package/rules/html/heading-level.cases.md +26 -0
  46. package/rules/html/heading-level.md +44 -0
  47. package/rules/html/hidden-focusable.cases.md +23 -0
  48. package/rules/html/hidden-focusable.md +40 -0
  49. package/rules/html/img-alt.cases.md +22 -0
  50. package/rules/html/img-alt.md +44 -0
  51. package/rules/html/img-title.md +40 -0
  52. package/rules/html/input-attributes.md +34 -0
  53. package/rules/html/input-image-alt.md +39 -0
  54. package/rules/html/input-missing-label.md +40 -0
  55. package/rules/html/link-text.md +39 -0
  56. package/rules/html/long-title.md +40 -0
  57. package/rules/html/map-dup-name.md +40 -0
  58. package/rules/html/map-id-name.md +38 -0
  59. package/rules/html/meta-refresh.md +42 -0
  60. package/rules/html/missing-doctype.cases.md +24 -0
  61. package/rules/html/missing-doctype.md +43 -0
  62. package/rules/html/multiple-labeled-controls.md +40 -0
  63. package/rules/html/no-abstract-role.md +39 -0
  64. package/rules/html/no-autoplay.md +37 -0
  65. package/rules/html/no-conditional-comment.md +39 -0
  66. package/rules/html/no-deprecated-attr.md +39 -0
  67. package/rules/html/no-dup-attr.md +37 -0
  68. package/rules/html/no-dup-class.md +33 -0
  69. package/rules/html/no-duplicate-id.cases.md +23 -0
  70. package/rules/html/no-duplicate-id.md +42 -0
  71. package/rules/html/no-implicit-close.cases.md +38 -0
  72. package/rules/html/no-implicit-close.md +40 -0
  73. package/rules/html/no-implicit-input-type.md +34 -0
  74. package/rules/html/no-inline-script.md +42 -0
  75. package/rules/html/no-inline-style.cases.md +12 -0
  76. package/rules/html/no-inline-style.md +42 -0
  77. package/rules/html/no-missing-references.md +39 -0
  78. package/rules/html/no-multiple-main.md +40 -0
  79. package/rules/html/no-raw-characters.cases.md +84 -0
  80. package/rules/html/no-raw-characters.md +35 -0
  81. package/rules/html/no-redundant-aria-label.md +36 -0
  82. package/rules/html/no-redundant-for.md +34 -0
  83. package/rules/html/no-redundant-role.md +42 -0
  84. package/rules/html/no-utf8-bom.md +45 -0
  85. package/rules/html/prefer-button.md +39 -0
  86. package/rules/html/prefer-native-element.md +40 -0
  87. package/rules/html/prefer-tbody.md +41 -0
  88. package/rules/html/require-sri.md +41 -0
  89. package/rules/html/script-element.md +36 -0
  90. package/rules/html/script-type.md +33 -0
  91. package/rules/html/target-blank-rel.cases.md +35 -0
  92. package/rules/html/target-blank-rel.md +32 -0
  93. package/rules/html/tel-non-breaking.md +37 -0
  94. package/rules/html/text-content.md +39 -0
  95. package/rules/html/th-scope.md +47 -0
  96. package/rules/html/unique-landmark.md +41 -0
  97. package/rules/html/unrecognized-char-ref.cases.md +41 -0
  98. package/rules/html/unrecognized-char-ref.md +42 -0
  99. package/rules/html/valid-autocomplete.cases.md +42 -0
  100. package/rules/html/valid-autocomplete.md +42 -0
  101. package/rules/html/valid-for.md +40 -0
  102. package/rules/html/valid-id.md +40 -0
  103. 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,11 @@
1
+ # html/element-permitted-parent — cases
2
+
3
+ ### case: li in a template
4
+
5
+ ```html
6
+ <template><li>a</li></template>
7
+ ```
8
+
9
+ ```expect
10
+ (none)
11
+ ```
@@ -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
+ ```