Skip to content

Commit cd5bde3

Browse files
Text spacing rewrite (act-rules#1923)
* Add new letter-spacing rule and deprecate old one * Add new word-spacing rule and deprecate old one * Clean up assumptions * Clean up * Clean up * Add new line-height rule and deprecate old one * Replace old letter spacing version rather than deprecating it * Replace old line height version rather than deprecating it * Replace old word spacing version rather than deprecating it * Target text nodes * Improve background note * Apply suggestion from review * Clean up * Target text nodes rather than their parents * Target text nodes rather than their parents * Add missing reference * Update example * Apply to parent of text nodes, not text nodes * Apply suggestions from code review Co-authored-by: Carlos Duarte <caduarte@campus.ul.pt> * Typos Co-authored-by: Carlos Duarte <caduarte@campus.ul.pt> * Typos --------- Co-authored-by: Carlos Duarte <caduarte@campus.ul.pt>
1 parent db69b36 commit cd5bde3

6 files changed

Lines changed: 791 additions & 66 deletions

__tests__/spelling-ignore.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,8 @@
260260
- 2px
261261
- 3px
262262
- 4px
263+
- 10px
264+
- 15px
263265
- 16px
264266
- 20px
265267
- 24px

_rules/letter-spacing-not-important-24afc2.md renamed to _rules/important-letter-spacing-wide-enough-24afc2.md

Lines changed: 104 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
id: 24afc2
3-
name: Letter spacing in style attributes is not !important
3+
name: Important letter spacing in style attributes is wide enough
44
rule_type: atomic
55
description: |
66
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.
@@ -16,74 +16,72 @@ input_aspects:
1616
acknowledgments:
1717
authors:
1818
- Jean-Yves Moyen
19+
previous_authors:
1920
- Jey Nandakumar
2021
funding:
2122
- WAI-Tools
2223
---
2324

2425
## Applicability
2526

26-
This rule applies to any [HTML element][] that is [visible][] and for which the `style` attribute [declares][declared] the [letter-spacing][] CSS property.
27+
This rule applies to any [HTML element][] with one or more [visible][] [text node][] children, when all the following are true for the `letter-spacing` property of the element:
2728

28-
## Expectation
29+
- the [specified][] value is [declared][] in a `style` attribute; and
30+
- the [computed][] value is [important][].
2931

30-
For each test target, at least one of the following is true:
32+
## Expectation
3133

32-
- **not important**: the [computed][] value of its [letter-spacing][] property is not [important][]; or
33-
- **wide enough**: the [computed][] value of its [letter-spacing][] property is at least 0.12 times the [computed][] value of its [font-size][] property; or
34-
- **cascade**: the [cascaded][] value of its [letter-spacing][] property is not a value [declared][] in its `style` attribute.
34+
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.
3535

3636
## Assumptions
3737

38-
- 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.
38+
- 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.
39+
40+
- 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.
3941

4042
- 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).
4143

4244
- 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].
4345

46+
- The target text node expresses something in a human language written in a script that uses the `letter-spacing` property.
47+
4448
## Accessibility Support
4549

4650
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.
4751

4852
## Background
4953

50-
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][].
54+
Styles [declared][] in a `style` attribute have higher [cascade specificity][] than any selector; therefore, they "win" 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] can win the [cascade sort][] over styles with the [author origin][].
5155

52-
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.
56+
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 some properties, and that `!important` is wider known than this distinction, this rule rather uses "[important][]"/"not [important][]" to avoid confusion.
5357

5458
### Bibliography
5559

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

64+
### About test cases
65+
66+
Test cases descriptions abusively refer to the CSS properties of text nodes, meaning the one of their parent.
67+
6068
## Test Cases
6169

6270
### Passed
6371

6472
#### Passed Example 1
6573

66-
This `p` element has a **not [important][]** [computed][] `letter-spacing`.
67-
68-
```html
69-
<p style="letter-spacing: 0.1em">
70-
The toy brought back fond memories of being lost in the rain forest.
71-
</p>
72-
```
73-
74-
#### Passed Example 2
75-
76-
This `p` element has a [computed][] `letter-spacing` of 0.15 time the font size, which is **wide enough**.
74+
This `p` element has a [computed][] `letter-spacing` of 0.15 time the `font-size`.
7775

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

84-
#### Passed Example 3
82+
#### Passed Example 2
8583

86-
This `p` element has a [computed][] [letter-spacing][] of `3px`, which is **wide enough** (the threshold is `3px`).
84+
This `p` element has a [computed][] `letter-spacing` of `3px`, which is exactly 0.12 the `font-size` of `25px`.
8785

8886
```html
8987
<style>
@@ -97,64 +95,48 @@ This `p` element has a [computed][] [letter-spacing][] of `3px`, which is **wide
9795
</p>
9896
```
9997

100-
#### Passed Example 4
98+
#### Passed Example 3
10199

102-
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`, and is **wide enough**.
100+
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.
103101

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

110-
#### Passed Example 5
108+
#### Passed Example 4
111109

112-
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`, and is **wide enough**.
110+
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.
113111

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

120-
#### Passed Example 6
121-
122-
The [cascaded][] 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][]). Thus, the `p` element matches the **cascade** condition.
123-
124-
```html
125-
<style>
126-
p {
127-
letter-spacing: 0.1em !important;
128-
}
129-
</style>
130-
131-
<p style="letter-spacing: 0.15em">
132-
The toy brought back fond memories of being lost in the rain forest.
133-
</p>
134-
```
135-
136-
#### Passed Example 7
118+
#### Passed Example 5
137119

138-
The [computed][] value of the `letter-spacing` property of this `p` element is **not [important][]**. The [computed][] value of the `letter-spacing` property of this `span` element is the [inherited][] value, that is the [computed][] value of its parent and therefore also **not [important][]**.
120+
This `p` element has a [computed][] `letter-spacing` of `2px`, 0.2 times its [computed][] `font-size` of `10px`; the `div` element has no [visible][] text node children.
139121

140122
```html
141-
<p style="letter-spacing: 0.1em">
142-
<span style="letter-spacing: inherit !important;">
123+
<div style="font-size: 16px; letter-spacing: 2px !important">
124+
<p style="font-size: 10px;">
143125
The toy brought back fond memories of being lost in the rain forest.
144-
</span>
145-
</p>
126+
</p>
127+
</div>
146128
```
147129

148-
#### Passed Example 8
130+
#### Passed Example 6
149131

150-
The [computed][] value of the `letter-spacing` property of this `p` element is **not [important][]**. The [computed][] value of the `letter-spacing` property of this `span` element is the [inherited][] value, that is the [computed][] value of its parent and therefore also **not [important][]**.
132+
This `p` element has a [computed][] `letter-spacing` of 0.2 times its `font-size`; the `div` element has no [visible][] text node children.
151133

152134
```html
153-
<p style="letter-spacing: 0.1em">
154-
<span style="letter-spacing: unset !important;">
135+
<div style="letter-spacing: 0.1em !important">
136+
<p style="letter-spacing: 0.2em !important;">
155137
The toy brought back fond memories of being lost in the rain forest.
156-
</span>
157-
</p>
138+
</p>
139+
</div>
158140
```
159141

160142
### Failed
@@ -219,48 +201,106 @@ There is no HTML element.
219201

220202
#### Inapplicable Example 2
221203

222-
This `p` element is not [visible][] because of `display: none`.
204+
There is no text node.
205+
206+
```html
207+
<div style="letter-spacing: 0.1em !important;"></div>
208+
```
209+
210+
#### Inapplicable Example 3
211+
212+
There is no [visible][] text node because of `display: none`.
223213

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

230-
#### Inapplicable Example 3
220+
#### Inapplicable Example 4
231221

232-
This `p` element is not [visible][] because it is positioned off-screen.
222+
There is no [visible][] text node because it is positioned off-screen.
233223

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

240-
#### Inapplicable Example 4
230+
#### Inapplicable Example 5
241231

242-
The `style` attribute of this `p` element does not [declare][declared] the `letter-spacing` property.
232+
This `p` element's `letter-spacing` property is not [declared][] in a `style` attribute.
243233

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

240+
#### Inapplicable Example 6
241+
242+
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][]).
243+
244+
```html
245+
<style>
246+
p {
247+
letter-spacing: 0.1em !important;
248+
}
249+
</style>
250+
251+
<p style="letter-spacing: 0.15em">
252+
The toy brought back fond memories of being lost in the rain forest.
253+
</p>
254+
```
255+
256+
#### Inapplicable Example 7
257+
258+
This `p` element does not have an [important][] [computed][] `letter-spacing`.
259+
260+
```html
261+
<p style="letter-spacing: 0.1em">
262+
The toy brought back fond memories of being lost in the rain forest.
263+
</p>
264+
```
265+
266+
#### Inapplicable Example 8
267+
268+
The [computed][] value of the `letter-spacing` property of this `span` element is the [inherited][] value, that is the [computed][] value of the `p` element and therefore not [important][]; the `p` element has no [visible][] text node children.
269+
270+
```html
271+
<p style="letter-spacing: 0.1em">
272+
<span style="letter-spacing: inherit !important;">
273+
The toy brought back fond memories of being lost in the rain forest.
274+
</span>
275+
</p>
276+
```
277+
278+
#### Inapplicable Example 9
279+
280+
The [computed][] value of the `letter-spacing` property of this `span` element is the [inherited][] value, that is the [computed][] value of the `p` element and therefore not [important][]; the `p` element has no [visible][] text node children.
281+
282+
```html
283+
<p style="letter-spacing: 0.1em">
284+
<span style="letter-spacing: unset !important;">
285+
The toy brought back fond memories of being lost in the rain forest.
286+
</span>
287+
</p>
288+
```
289+
250290
[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'
251291
[cascade sort]: https://www.w3.org/TR/css-cascade-4/#cascade-sort 'CSS Cascading and Inheritance Level 4 (Working draft) - Cascade Sort'
252-
[cascaded]: https://www.w3.org/TR/css-cascade-4/#cascaded 'CSS Cascading and Inheritance Level 4 (Working draft) - Cascaded Values'
292+
[cascade specificity]: https://www.w3.org/TR/css-cascade-3/#cascade-specificity 'CSS Cascading and Inheritance Level 4 (Candidate Recommendation) - Cascade specificity'
253293
[computed]: https://www.w3.org/TR/css-cascade-4/#computed 'CSS Cascading and Inheritance Level 4 (Working draft) - Computed Values'
254294
[declared]: https://www.w3.org/TR/css-cascade-4/#declared 'CSS Cascading and Inheritance Level 4 (Working draft) - Declared Values'
255-
[font-size]: https://www.w3.org/TR/css-fonts-4/#propdef-font-size 'CSS Fonts Module Level 4 (Working draft) - Font size: the font-size property'
295+
[html element]: #namespaced-element
256296
[important]: https://www.w3.org/TR/css-cascade-4/#importance 'CSS Cascading and Inheritance Level 4 (Working draft) - Importance'
257297
[inherited]: https://www.w3.org/TR/css-cascade-4/#inheriting 'CSS Cascading and Inheritance Level 4 (Working draft) - Inherited Values'
258-
[letter-spacing]: https://www.w3.org/TR/css-text-3/#propdef-letter-spacing 'CSS Text Module Level 3 - Tracking: the letter-spacing property'
259298
[normal]: https://www.w3.org/TR/css-cascade-4/#normal 'CSS Cascading and Inheritance Level 4 (Working draft) - Normal declarations'
260299
[sc1412]: https://www.w3.org/TR/WCAG21/#text-spacing 'Success Criterion 1.4.12 Text Spacing'
261300
[sc148]: https://www.w3.org/TR/WCAG21/#visual-presentation 'Success Criterion 1.4.8 Visual Presentation'
301+
[specified]: https://www.w3.org/TR/css-cascade-4/#specified 'CSS Cascading and Inheritance Level 4 (Working draft) - Specified Values'
262302
[specificity]: https://www.w3.org/TR/selectors/#specificity 'CSS Selectors Level 4 (Working draft) - Specificity'
303+
[text node]: https://dom.spec.whatwg.org/#text
263304
[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'
264305
[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'
265306
[visible]: #visible 'Definition of visible'
266-
[html element]: #namespaced-element

0 commit comments

Comments
 (0)