Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Text spacing rewrite #1923

Merged
merged 33 commits into from
Oct 13, 2023
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
6ac7c5c
Add new letter-spacing rule and deprecate old one
Jym77 Sep 15, 2022
453902b
Add new word-spacing rule and deprecate old one
Jym77 Sep 15, 2022
e8f7c9e
Clean up assumptions
Jym77 Sep 15, 2022
77be6e9
Clean up
Jym77 Sep 15, 2022
b9a6561
Clean up
Jym77 Sep 15, 2022
dc1d399
Add new line-height rule and deprecate old one
Jym77 Sep 15, 2022
8a0e96c
Merge branch 'develop' into text-spacing-rewrite
Jym77 Sep 15, 2022
27a16ab
Merge branch 'develop' into text-spacing-rewrite
Jym77 Oct 7, 2022
152e445
Replace old letter spacing version rather than deprecating it
Jym77 Oct 7, 2022
cb09dc9
Replace old line height version rather than deprecating it
Jym77 Oct 7, 2022
27ce954
Replace old word spacing version rather than deprecating it
Jym77 Oct 7, 2022
840a39c
Target text nodes
Jym77 Oct 7, 2022
f30eb45
Improve background note
Jym77 Oct 7, 2022
8afae38
Merge branch 'develop' into text-spacing-rewrite
Jym77 Oct 11, 2022
090aa68
Merge branch 'develop' into text-spacing-rewrite
Jym77 Oct 27, 2022
48b48eb
Apply suggestion from review
Jym77 Oct 27, 2022
be908ce
Clean up
Jym77 Oct 27, 2022
f3f052e
Target text nodes rather than their parents
Jym77 Oct 27, 2022
2e983f5
Target text nodes rather than their parents
Jym77 Oct 27, 2022
d7da031
Add missing reference
Jym77 Oct 27, 2022
b9f5c61
Merge branch 'develop' into text-spacing-rewrite
Jym77 Nov 1, 2022
d1d1c07
Update example
Jym77 Nov 22, 2022
08b8fde
Merge branch 'develop' into text-spacing-rewrite
Jym77 Nov 25, 2022
7410673
Apply to parent of text nodes, not text nodes
Jym77 Nov 25, 2022
32eb79c
Merge branch 'develop' into text-spacing-rewrite
Jym77 Nov 25, 2022
8dd55d8
Merge branch 'develop' into text-spacing-rewrite
Jym77 Jan 10, 2023
b2af34e
Apply suggestions from code review
Jym77 Jan 12, 2023
7815582
Merge branch 'develop' into text-spacing-rewrite
Jym77 Jan 19, 2023
a4456f3
Typos
Jym77 Jan 19, 2023
c087368
Merge branch 'develop' into text-spacing-rewrite
Jym77 May 23, 2023
5ced4b4
Merge branch 'develop' into text-spacing-rewrite
Jym77 Aug 31, 2023
f82a0c4
Merge branch 'develop' into text-spacing-rewrite
Jym77 Sep 28, 2023
8d6fcd7
Typos
Jym77 Sep 28, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions __tests__/spelling-ignore.yml
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,8 @@
- 2px
- 3px
- 4px
- 10px
- 15px
- 16px
- 20px
- 24px
Expand Down
301 changes: 301 additions & 0 deletions _rules/important-letter-spacing-wide-enough-fsy8c7.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,301 @@
---
id: fsy8c7
Jym77 marked this conversation as resolved.
Show resolved Hide resolved
name: Important letter spacing in style attributes is wide enough
rule_type: atomic
description: |
This rule checks that the `style` attribute is not used to prevent adjusting `letter-spacing` by using `!important`, except if it's at least 0.12 times the font size.
accessibility_requirements:
wcag21:1.4.12: # Text Spacing (AA)
forConformance: true
failed: not satisfied
passed: further testing needed
inapplicable: further testing needed
input_aspects:
- DOM Tree
- CSS Styling
acknowledgments:
authors:
- Jean-Yves Moyen
Jym77 marked this conversation as resolved.
Show resolved Hide resolved
---

## Applicability
Jym77 marked this conversation as resolved.
Show resolved Hide resolved

This rule applies to any [HTML element][] for which all the following are true:

- the element is has at least one [visible][] text node children; and
Jym77 marked this conversation as resolved.
Show resolved Hide resolved
- the [specified][] `letter-spacing` property of the element is [declared][] in a `style` attribute; and
- the [computed][] `letter-spacing` property is [important][].

The [specified][] `letter-spacing` of the element may be inherited from an ancestor, therefore the test targets do not necessarily have a `style` attribute.

## Expectation

For each test target, the [computed][] value of its `letter-spacing` property is at least 0.12 times the [computed][] value of its `font-size` property.

## Assumptions

- There is no mechanism available on the page to adjust `letter-spacing`. If there is such a mechanism, it is possible to fail this rule while [Success Criterion 1.4.12 Text Spacing][sc1412] is still satisfied.

- The font size is constant for all text in the element. If `font-size` changes (e.g., through use of the `::first-line` pseudo-element) then the required letter spacing would also change throughout the element. This is untested by the current rule.

- This rule assumes that WCAG's meaning for the "Letter spacing style property" is the value of the CSS `letter-spacing` property rather than the actual space between letters. The value of the CSS property is _added_ to whichever spacing already exist (for example, due to kerning). Thus, the actual space between letters can be larger than the value of the `letter-spacing` property. If [Success Criterion 1.4.12 Text Spacing][sc1412] is concerned by the actual space between letters, then this rule may fail (with the `letter-spacing` property being too small) while the Success Criterion is still satisfied (with the actual space being enough).

- This rule assumes that when inter-letters space is changed because of justification, the `letter-spacing` property is not changed. Therefore, whether a text is justified or not doesn't change the result of this rule. Note that justifying text is a failure of [Success Criterion 1.4.8 Visual Presentation][sc148].

- At least one text node child of the element express something in a human language written in a script that that uses the `letter-spacing` property.

## Accessibility Support

While some assistive technologies are able to set [user origin][] or [user agent origin][] styles, others, such as browser extensions, are only able to set styles with the [author origin][]. Such assistive technologies cannot create styles "winning" the [cascade sort][] over a `style` attribute with an [important][] declaration.

## Background

When a style is [declared][] in the `style` attribute with an [important][] declaration, it "wins" the [cascade sort] over any other style from [author origin][], i.e. it cannot be overridden by any of these. On the other hand, if such a style is [declared][] in a style sheet, it can still "lose" the [cascade sort][] to declarations with higher [specificity][] or simply coming from a later style sheet (such as ones injected by assistive technologies). This rule ensures that the element is not in the first case and that the style can be overridden by users, unless it is already at least the minimum required threshold. [Important][] styles that are declared with the [user][user origin] or [user agent][user agent origin] origin can win the [cascade sort][] over styles with the [author origin][].

CSS specifications define each declaration as being either [important][] (if it has the `!important` annotation) or [normal][]. Given that `normal` is also a keyword for this property, and that `!important` is wider known that this distinction, this rule rather uses "[important][]"/"not [important][]" to avoid confusion.

### Bibliography

- [Understanding Success Criterion 1.4.12: Text Spacing](https://www.w3.org/WAI/WCAG21/Understanding/text-spacing.html)
- [CSS Text Module Level 3 - Spacing](https://www.w3.org/TR/css-text-3/#spacing)
- [CSS Visual formatting model details](https://drafts.csswg.org/css2/visudet.html)

## Test Cases

### Passed

#### Passed Example 1

This `p` element has a [computed][] `letter-spacing` of 0.15 time the `font-size`.

```html
<p style="letter-spacing: 0.15em !important">
The toy brought back fond memories of being lost in the rain forest.
</p>
```

#### Passed Example 2

This `p` element has a [computed][] `letter-spacing` of `3px`, which is exactly 0.12 the `font-size` of `25px`.

```html
<style>
p {
font-size: 25px;
}
</style>

<p style="letter-spacing: 3px !important">
The toy brought back fond memories of being lost in the rain forest.
</p>
```

#### Passed Example 3

This `p` element has two [declared][] values for its `letter-spacing` property. The latest wins the [cascade sort][]. It has a value of `0.15em`, which is wide enough.

```html
<p style="letter-spacing: 0.1em !important; letter-spacing: 0.15em !important">
The toy brought back fond memories of being lost in the rain forest.
</p>
```

#### Passed Example 4

This `p` element has two [declared][] values for its `letter-spacing` property. The one which is [important][] wins the [cascade sort][]. It has a value of `0.15em`, which is wide enough.

```html
<p style="letter-spacing: 0.15em !important; letter-spacing: 0.1em">
The toy brought back fond memories of being lost in the rain forest.
</p>
```

#### Passed Example 5

The `div` element has no text node child. The [computed][] `letter-spacing` of the `p` element is `2px`, 0.2 times its [computed][] `font-size` of `10px`

```html
<div style="font-size: 16px; letter-spacing: 2px !important">
<p style="font-size: 10px;">
The toy brought back fond memories of being lost in the rain forest.
</p>
</div>
```

#### Passed Example 6

The `div` element has no text node child. The [computed][] `letter-spacing` of the `p` element is 0.2 times its `font-size`.

```html
<div style="letter-spacing: 0.1em !important">
<p style="letter-spacing: 0.2em !important;">
The toy brought back fond memories of being lost in the rain forest.
</p>
</div>
```

### Failed

#### Failed Example 1

This `p` element has a [computed][] `letter-spacing` of only 0.1 times the font size, which is below the required minimum.

```html
<p style="letter-spacing: 0.1em !important">
The toy brought back fond memories of being lost in the rain forest.
</p>
```

#### Failed Example 2

This `p` element has a [computed][] `letter-spacing` of `2px` which is only 0.1 times the font size (`20px`), thus below the required minimum.

```html
<style>
p {
font-size: 20px;
}
</style>

<p style="letter-spacing: 2px !important">
The toy brought back fond memories of being lost in the rain forest.
</p>
```

#### Failed Example 3

This `p` element has a [computed][] `letter-spacing` of 0.

```html
<p style="letter-spacing: normal !important">
The toy brought back fond memories of being lost in the rain forest.
</p>
```

#### Failed Example 4

This `p` element has a [computed][] `letter-spacing` of 0.

```html
<p style="letter-spacing: initial !important">
The toy brought back fond memories of being lost in the rain forest.
</p>
```

### Inapplicable

#### Inapplicable Example 1

There is no HTML element.

```svg
<svg xmlns="http://www.w3.org/2000/svg">
<text y="20" style="letter-spacing: 0.1em">ACT rules</text>
</svg>
```

#### Inapplicable Example 2

This `div` element has no text node child.

```html
<div style="letter-spacing: 0.1em !important; border-top: 1px solid black;">
<!-- empty div, border to make it "visible" -->
</div>
```

#### Inapplicable Example 3

This `p` element has no [visible][] text node child because of `display: none`.

```html
<p style="display: none; letter-spacing: 0.1em !important;">
The toy brought back fond memories of being lost in the rain forest.
</p>
```

#### Inapplicable Example 4

This `p` element has no [visible][] text node child because it is positioned off-screen.

```html
<p style="position: absolute; top: -999em; letter-spacing: 0.1em !important;">
The toy brought back fond memories of being lost in the rain forest.
</p>
```

#### Inapplicable Example 5

This `p` element's `letter-spacing` property is not [declared][] in a `style` attribute.

```html
<p style="width: 60%">
The toy brought back fond memories of being lost in the rain forest.
</p>
```

#### Inapplicable Example 6

The [specified][] value of the `letter-spacing` property of this `p` element is [declared][] in the style sheet, not in the `style` attribute (it wins the [cascade sort][] because it is [important][]).

```html
<style>
p {
letter-spacing: 0.1em !important;
}
</style>

<p style="letter-spacing: 0.15em">
The toy brought back fond memories of being lost in the rain forest.
</p>
```

#### Inapplicable Example 7

This `p` element does not have an [important][] [computed][] `letter-spacing`.

```html
<p style="letter-spacing: 0.1em">
The toy brought back fond memories of being lost in the rain forest.
</p>
```

#### Inapplicable Example 8

The `p` element has no text node child. The [computed][] value of the `letter-spacing` property of the `span` element is the [inherited][] value, that is the [computed][] value of its parent and therefore not [important][].

```html
<p style="letter-spacing: 0.1em">
<span style="letter-spacing: inherit !important;">
The toy brought back fond memories of being lost in the rain forest.
</span>
</p>
```

#### Inapplicable Example 9

The `p` element has no text node child. The [computed][] value of the `letter-spacing` property of the `span` element is the [inherited][] value, that is the [computed][] value of its parent and therefore not [important][].

```html
<p style="letter-spacing: 0.1em">
<span style="letter-spacing: unset !important;">
The toy brought back fond memories of being lost in the rain forest.
</span>
</p>
```

[author origin]: https://www.w3.org/TR/css-cascade-4/#cascade-origin-author 'CSS Cascading and Inheritance Level 4 (Working draft) - Cascading Origins - Author Origin'
[cascade sort]: https://www.w3.org/TR/css-cascade-4/#cascade-sort 'CSS Cascading and Inheritance Level 4 (Working draft) - Cascade Sort'
[computed]: https://www.w3.org/TR/css-cascade-4/#computed 'CSS Cascading and Inheritance Level 4 (Working draft) - Computed Values'
[declared]: https://www.w3.org/TR/css-cascade-4/#declared 'CSS Cascading and Inheritance Level 4 (Working draft) - Declared Values'
[html element]: #namespaced-element
[important]: https://www.w3.org/TR/css-cascade-4/#importance 'CSS Cascading and Inheritance Level 4 (Working draft) - Importance'
[inherited]: https://www.w3.org/TR/css-cascade-4/#inheriting 'CSS Cascading and Inheritance Level 4 (Working draft) - Inherited Values'
[normal]: https://www.w3.org/TR/css-cascade-4/#normal 'CSS Cascading and Inheritance Level 4 (Working draft) - Normal declarations'
[sc1412]: https://www.w3.org/TR/WCAG21/#text-spacing 'Success Criterion 1.4.12 Text Spacing'
[sc148]: https://www.w3.org/TR/WCAG21/#visual-presentation 'Success Criterion 1.4.8 Visual Presentation'
[specified]: https://www.w3.org/TR/css-cascade-4/#specified 'CSS Cascading and Inheritance Level 4 (Working draft) - Specified Values'
[specificity]: https://www.w3.org/TR/selectors/#specificity 'CSS Selectors Level 4 (Working draft) - Specificity'
[user origin]: https://www.w3.org/TR/css-cascade-4/#cascade-origin-user 'CSS Cascading and Inheritance Level 4 (Working draft) - Cascading Origins - User Origin'
[user agent origin]: https://www.w3.org/TR/css-cascade-4/#cascade-origin-ua 'CSS Cascading and Inheritance Level 4 (Working draft) - Cascading Origins - User Agent Origin'
[visible]: #visible 'Definition of visible'
Loading