You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: _src/posts/cache-cache-css/index.md
+20-5Lines changed: 20 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,7 +2,7 @@
2
2
layout: "template/post.njk"
3
3
title: "Cache-cache CSS"
4
4
date: "2016-10-13T13:11:13"
5
-
modified: "2021-03-05T17:07:37"
5
+
modified: "2025-03-11"
6
6
permalink: "cache-cache-css/index.html"
7
7
excerpt: "Il existe une myriade de façon de masquer visuellement du texte en CSS tout en le maintenant accessible aux technologies d'assistance telles que les lecteurs d'écran. J'en agrège ici quelques-unes pour proposer une version que j'espère plus robuste."
8
8
tags: ["posts"]
@@ -14,6 +14,14 @@ Il existe de nombreuses façons de faire, que je ne détaillerai pas ici. Depuis
14
14
15
15
Mais elle n’est pas exempte de problème, désormais.
16
16
17
+
---
18
+
19
+
## Mise à jour
20
+
21
+
Depuis la dernière mise à jour en 2019, d’autres changements ont été apportés. Je les ai récapitulés dans [<cite>Masquage accessible de point</cite>](/masquage-accessible-de-pointe/).
22
+
23
+
---
24
+
17
25
## Propriété dépréciée
18
26
19
27
La « magie » de cette solution repose sur la propriété `clip`. Elle est simple à comprendre et très efficace. Seul bémol : `clip` est **déprécié par le module _[CSS masking](https://drafts.fxtf.org/css-masking-1/#clip-property)_** de niveau 1.
@@ -47,7 +55,6 @@ Et voilà, second problème résolu.
47
55
Voilà la version finale que je propose actuellement :
48
56
49
57
```css
50
-
51
58
.sr-only {
52
59
border: 0!important;
53
60
clip: rect(1px, 1px, 1px, 1px) !important;
@@ -105,7 +112,7 @@ Qu’en dites-vous ?
105
112
106
113
### Les lecteurs d’écran sur mobile
107
114
108
-
19 octobre 2016
115
+
<timedatetime="2016-10-19">19 octobre 2016</time>
109
116
110
117
Ayant besoin de tests sur cette version pour vérifier qu’elle n’introduit pas de régressions, [Johan Ramon m’a remonté un bug étrange sur VoiceOver](https://twitter.com/johan_ramon/status/788372720224526336). En creusant un peu avec [Sylvain Pigeard](https://github.com/PigeardSylvain), il nous est apparu que `position: static` posait problème lors de la prise de focus d’un lien ayant la classe `.sr-only-focusable`.
111
118
@@ -121,14 +128,22 @@ L’état des lieux est assez sombre : **les liens d’évitement ne marche
121
128
122
129
### Le référencement naturel
123
130
124
-
19 octobre 2016
131
+
<timedatetime="2016-10-19">19 octobre 2016</time>
125
132
126
133
[Steve Faulkner](https://twitter.com/stevefaulkner) — du [Paciello Group](https://www.paciellogroup.com/blog/) — a posé la question au forum de support pour _webmasters_ de Google : [les contextes supplémentaires pour utilisateurs malvoyants ont-ils un effet négatif sur le positionnement dans les résultats de recherche ?](https://productforums.google.com/forum/#!msg/webmasters/YJcZUhtMIE4/XkOEzVakBAAJ)
127
134
128
135
Réponse courte : **non** Cependant étant donné que ce texte n’apparaît pas de prime abord il est considéré comme du contenu secondaire et a donc un très faible impact sur le positionnement, et c’est une excellente chose puisque cela dissuade d’en abuser.
129
136
130
137
### Les débordements inopinés
131
138
132
-
18 janvier 2019
139
+
<timedatetime="2019-01-18">18 janvier 2019</time>
133
140
134
141
De multiples problèmes de débordements ont été observés, notamment sur Chrome, lorsque les éléments masqués sont contenus dans un élément avec `overflow: auto;`. [Le problème est résolu dans Boosted](https://github.com/Orange-OpenSource/Orange-Boosted-Bootstrap/issues/84) en ajoutant `margin: -1px;`.
142
+
143
+
---
144
+
145
+
## Mise à jour
146
+
147
+
Depuis la dernière mise à jour en 2019, d’autres changements ont été apportés. Je les ai récapitulés dans [<cite>Masquage accessible de point</cite>](/masquage-accessible-de-pointe/).
excerpt: "Depuis ma dernière partie de [cache-cache CSS](https://wwww.ffoodd.fr/cache-cache-css/), les choses ont changé — quelques cas tordus sont apparus."
7
+
description: "Depuis ma dernière partie de <a href='/cache-cache-css/'>cache-cache CSS</a>, les choses ont changé — quelques cas tordus sont apparus."
8
+
metadescription: "Depuis ma dernière partie de cache-cache CSS, les choses ont changé — quelques cas tordus sont apparus."
9
+
tags: ["posts"]
10
+
commentsOpen: "true"
11
+
---
12
+
13
+
La classe de masquage accessible `.visually-hidden` — anciennement `.sr-only` dans Bootstrap — a beaucoup évolué au fil du temps. C’est pour ça que j’ai publié [<cite>cache-cache CSS</cite>](/cache-cache-css/) il y a quelques années, qui récapitulait l’état de l’art à ce moment.
14
+
15
+
Mais il n’y a pas que les techniques CSS qui évoluent… Les navigateurs, aussi. Et parfois, ça requièrs de l’adaptation !
16
+
17
+
## Un cas légendaire
18
+
19
+
Louis-Maxime Piton — un des mainteneurs de [Boosted (en anglais)](https://boosted.orange.com/) et inévitablement contributeur à [Bootstrap (en anglais)](https://getbootstrap.com) — a [proposé un correctif (sur GitHub, en anglais)](https://github.com/twbs/bootstrap/pull/37533) il y a plus de deux ans pour contourner [un problème provoqué par le masquage accessible appliqué à une légende de tableau (sur StackOverflow, en anglais)](https://stackoverflow.com/questions/31057955/why-are-table-borders-not-collapsing-when-caption-is-positioned/32063028#32063028).
20
+
21
+
Les `caption`, lorsqu’ils sont en position absolue, sont considérés comme des cellules de tableaux anonymes — et ça met la grouille dans la fusion des bordures, l’indispensable `border-collapse: collapse`.
22
+
23
+
Le correctif proposé est simplissime, bien qu’il puisse théoriquement poser des problèmes : n’appliquer la position absolue que si l’élément n’est pas un `caption`. C’est l’état actuel [du <emlang="en">mixin</em> dans Bootstrap (sur GitHub, en anglais)](https://github.com/twbs/bootstrap/blob/53171ad564b2d01bff7613d7210e93a5197a367b/scss/mixins/_visually-hidden.scss).
24
+
25
+
En résumé, voici la modification :
26
+
27
+
```css
28
+
.visually-hidden:not(caption) {
29
+
position: absolute!important;
30
+
}
31
+
```
32
+
33
+
## En cas de débordement
34
+
35
+
La semaine dernière, l’ami [Django Janny](https://www.djangojanny.net/) a relancé [le sujet sur Gist (en anglais) avec un cas marginal](https://gist.github.com/ffoodd/000b59f431e3e64e4ce1a24d5bb36034?permalink_comment_id=5468620#gistcomment-5468620) : un élément qui déborde, à l’intérieur d’un élément masqué visuellement.
36
+
37
+
En général, on ne masque qu’une portion de texte de cette façon : aucun élément bloc ne devrait s’y trouver — ni, en réalité, aucun enfant. La majorité du temps, le masquage accessible respecte implicitement les mêmes règles qu’un attribut `aria-label` par exemple : un texte simple et concis.
38
+
39
+
Mais c’est une règle implicite, et à ma connaissance aucune contre-indication n’a jamais été mentionnée quant à l’utilisation du masquage accessible sur une portion de DOM plus riche. Je l’ai par exemple fait lorsque j’ai amélioré les liens d’évitements sur [la documentation de Bootstrap (en anglais)](https://getbootstrap.com/docs/5.3/getting-started/introduction/), dont le conteneur est masqué visuellement — mais il apparaît à la prise de focus, nous faisant passer à côté du problème…
40
+
41
+
Depuis (au moins) 2019, les éléments en débordement deviennent focusables dans la plupart des navigateurs, pour palier un défaut d’accessibilité : ne pas pouvoir interagir avec un élément masqué par un débordement. [Cassey Lottman a retracé ce changement dans son article <citelang="en">Elements with overflow: scroll become focusable</cite> (en anglais)](https://cassey.dev/til/2019-11-19-overflow-scroll-gets-focus/).
42
+
43
+
Ce qui, dans un élément masqué visuellement, devient un piège : on ne voit (évidemment) pas le focus.
44
+
45
+
La solution proposée par Django — et après quelques tests, la seule qui paraisse fonctionner — est d’[empêcher le débordement sur les enfants d’un élément masqué visuellement (sur CodePen, en anglais)](https://codepen.io/djangounet/pen/WbNpmMP?editors=1111) :
46
+
47
+
```css
48
+
.visually-hidden* {
49
+
overflow: hidden!important;
50
+
}
51
+
```
52
+
53
+
## La totale
54
+
55
+
Voici donc la version mise à jour de la technique de masquage accessible :
56
+
57
+
```css
58
+
.visually-hidden {
59
+
border: 0!important;
60
+
clip-path: inset(50%) !important;
61
+
height: 1px!important;
62
+
margin: -1px!important;
63
+
overflow: hidden!important;
64
+
padding: 0!important;
65
+
width: 1px!important;
66
+
white-space: nowrap!important;
67
+
}
68
+
69
+
.visually-hidden:not(caption) {
70
+
position: absolute!important;
71
+
}
72
+
73
+
.visually-hidden* {
74
+
overflow: hidden!important;
75
+
}
76
+
```
77
+
78
+
J’en ai profité pour [proposer ce changement dans Bootstrap (sur GitHub, en anglais)](https://github.com/twbs/bootstrap/pull/41286) — en citant Django bien entendu — et pour mettre à jour [le Gist servant souvent de référence (en anglais)](https://gist.github.com/ffoodd/000b59f431e3e64e4ce1a24d5bb36034).
79
+
80
+
Notez par ailleurs quelques autres changements succincts :
81
+
82
+
1. J’ai renommé `.sr-only` en `.visually-hidden` pour me conformer aux usages des <emlang="en">frameworks</em> populaires,
83
+
2. Et nettoyé un peu le support de navigateurs anciens : plus de `clip` désormais, car [`clip-path` est très largement supporté](https://developer.mozilla.org/fr/docs/Web/CSS/clip-path).
84
+
3. La variante pour démasquer le contenu lors de la prise de focus n’est plus une remise à zéro, mais une autre classe conditionnée à l’état : `.visually-hidden-focusable:not(:focus):not(:focus-within)`, à l’instar de ce qui est fait [dans Bootstrap depuis cinq ans déjà (sur GitHub, en anglais)](https://github.com/twbs/bootstrap/pull/32440).
Copy file name to clipboardExpand all lines: docs/cache-cache-css/index.html
+14-7Lines changed: 14 additions & 7 deletions
Original file line number
Diff line number
Diff line change
@@ -62,6 +62,10 @@ <h2 class="h3-like description" itemprop="description">Il m'arrive souvent
62
62
<p>Et j’ai beau trouver ça idiot — masquer du texte pour certains utilisateurs et pas pour d’autres, ça me paraît incohérent avec l’accessibilité — c’est un besoin récurrent.</p>
63
63
<p>Il existe de nombreuses façons de faire, que je ne détaillerai pas ici. Depuis quelques années, lorsque je le peux, j’utilise celle de <ahref="https://twitter.com/thierrykoblentz">Thierry Koblentz</a> pour Yahoo! qui est décrite <ahref="https://developer.yahoo.com/blogs/ydn/clip-hidden-content-better-accessibility-53456.html">sur le blog technique de Yahoo!</a><ahref="https://cssmojo.com/hide-content-from-sighted-users/">sur le blog de Thierry</a>. C’est de loin la plus complète, et la seule à ma connaissance à supporter la direction de texte de droite à gauche.</p>
64
64
<p>Mais elle n’est pas exempte de problème, désormais.</p>
65
+
<hr>
66
+
<h2id="mise-a-jour" tabindex="-1">Mise à jour</h2>
67
+
<p>Depuis la dernière mise à jour en 2019, d’autres changements ont été apportés. Je les ai récapitulés dans <ahref="/masquage-accessible-de-pointe/"><cite>Masquage accessible de point</cite></a>.</p>
<p>La « magie » de cette solution repose sur la propriété <code>clip</code>. Elle est simple à comprendre et très efficace. Seul bémol : <code>clip</code> est <strong>déprécié par le module <em><ahref="https://drafts.fxtf.org/css-masking-1/#clip-property">CSS masking</a></em></strong> de niveau 1.</p>
67
71
<p>Pas de souci. La technique basée sur <code>clip</code> date un peu, il est normal qu’elle tombe en désuétude. La nouvelle spécification recommande l’utilisation de <code>clip-path</code> pour remplacer <code>clip</code>. Ce qui nous laisse pantois, puisque <ahref="https://caniuse.com/#feat=css-clip-path">le support de <code>clip-path</code> est encore tout à fait relatif</a>. <strong>Nous devons conserver <code>clip</code> et ajouter <code>clip-path</code> en guise d’amélioration progressive</strong>.</p>
<p><ahref="https://twitter.com/KittyGiraudel">Kitty Giraudel</a> m’a fait l’honneur de <ahref="https://kittygiraudel.com/2016/10/13/css-hide-and-seek/">traduire cet article en anglais et le publier sur son blog</a>. Merci !</p>
<h3id="les-lecteurs-d-ecran-sur-mobile" tabindex="-1">Les lecteurs d’écran sur mobile</h3>
121
-
<p>19 octobre 2016</p>
124
+
<p><timedatetime="2016-10-19">19 octobre 2016</time></p>
122
125
<p>Ayant besoin de tests sur cette version pour vérifier qu’elle n’introduit pas de régressions, <ahref="https://twitter.com/johan_ramon/status/788372720224526336">Johan Ramon m’a remonté un bug étrange sur VoiceOver</a>. En creusant un peu avec <ahref="https://github.com/PigeardSylvain">Sylvain Pigeard</a>, il nous est apparu que <code>position: static</code> posait problème lors de la prise de focus d’un lien ayant la classe <code>.sr-only-focusable</code>.</p>
123
126
<p>Nous étions contents, lorsqu’en cherchant à avertir l’équipe de Bootstrap nous sommes tombés sur <ahref="https://github.com/twbs/bootstrap/issues/20732">un ticket ouvert récemment qui implique également TalkBack</a>. <ahref="https://twitter.com/patrick_h_lauke">Patrick H. Lauke</a>, en investiguant, a décelé de nombreuses incohérences dans la gestion du focus entre les diverses technologies d’assistance sur mobile. Il a ainsi ouvert des tickets un peu partout :</p>
124
127
<ul>
@@ -130,19 +133,23 @@ <h3 id="les-lecteurs-d-ecran-sur-mobile" tabindex="-1">Les lecteurs d’écran s
130
133
</ul>
131
134
<p>L’état des lieux est assez sombre : <strong>les liens d’évitement ne marchent globalement pas sur les interfaces tactiles lorsqu’on utilise un lecteur d’écran</strong>. Ô joie.</p>
<p><timedatetime="2016-10-19">19 octobre 2016</time></p>
134
137
<p><ahref="https://twitter.com/stevefaulkner">Steve Faulkner</a> — du <ahref="https://www.paciellogroup.com/blog/">Paciello Group</a> — a posé la question au forum de support pour <em>webmasters</em> de Google : <ahref="https://productforums.google.com/forum/#!msg/webmasters/YJcZUhtMIE4/XkOEzVakBAAJ">les contextes supplémentaires pour utilisateurs malvoyants ont-ils un effet négatif sur le positionnement dans les résultats de recherche ?</a></p>
135
138
<p>Réponse courte : <strong>non</strong> Cependant étant donné que ce texte n’apparaît pas de prime abord il est considéré comme du contenu secondaire et a donc un très faible impact sur le positionnement, et c’est une excellente chose puisque cela dissuade d’en abuser.</p>
<p><timedatetime="2019-01-18">18 janvier 2019</time></p>
138
141
<p>De multiples problèmes de débordements ont été observés, notamment sur Chrome, lorsque les éléments masqués sont contenus dans un élément avec <code>overflow: auto;</code>. <ahref="https://github.com/Orange-OpenSource/Orange-Boosted-Bootstrap/issues/84">Le problème est résolu dans Boosted</a> en ajoutant <code>margin: -1px;</code>.</p>
142
+
<hr>
143
+
<h2id="mise-a-jour-1" tabindex="-1">Mise à jour</h2>
144
+
<p>Depuis la dernière mise à jour en 2019, d’autres changements ont été apportés. Je les ai récapitulés dans <ahref="/masquage-accessible-de-pointe/"><cite>Masquage accessible de point</cite></a>.</p>
145
+
<hr>
139
146
140
147
</div>
141
148
<footerclass="small mt2">
142
149
<pclass="pl2 mt0 pt1">
143
150
Article rédigé par <strongitemprop="author"><spanclass="fn">Gaël Poupard</span></strong>.
144
151
Publié le <timeclass="updated" datetime="2016-10-13T13:11:13" itemprop="datePublished">13 octobre 2016</time>
145
-
et modifié le <timeclass="updated" datetime="2021-03-05T17:07:37" itemprop="dateModified">5 mars 2021</time>.
152
+
et modifié le <timeclass="updated" datetime="2025-03-11" itemprop="dateModified">11 mars 2025</time>.
<ol><li><ahref="#propriete-depreciee">Propriété dépréciée</a></li><li><ahref="#le-texte-ratatine">Le texte ratatiné</a></li><li><ahref="#la-totale">La totale</a></li><li><ahref="#code-et-traduction">Code et traduction</a></li><li><ahref="#modifications">Modifications</a></li><li><ahref="#comments">Commentaires</a></li></ol>
339
+
<ol><li><ahref="#mise-a-jour">Mise à jour</a></li><li><ahref="#propriete-depreciee">Propriété dépréciée</a></li><li><ahref="#le-texte-ratatine">Le texte ratatiné</a></li><li><ahref="#la-totale">La totale</a></li><li><ahref="#code-et-traduction">Code et traduction</a></li><li><ahref="#modifications">Modifications</a></li><li><ahref="#mise-a-jour-1">Mise à jour</a></li><li><ahref="#comments">Commentaires</a></li></ol>
0 commit comments