Creuser dans la propriété d'affichage : génération de boîtes

Publié: 2022-03-10
Résumé rapide ↬ Poursuivant une série sur la propriété d' display en CSS, cette fois Rachel Andrew se penche sur les valeurs qui contrôlent la génération de boîte, pour les moments où vous ne voulez pas du tout générer de boîte.

Ceci est le deuxième d'une courte série d'articles sur la propriété display en CSS. Vous pouvez lire l'article initial de la série sur "Les deux valeurs de l'affichage". La spécification display est une spécification très utile à comprendre car elle sous-tend toutes les différentes méthodes de mise en page que nous avons.

Bien que de nombreuses valeurs d' display aient leurs propres spécifications, de nombreux termes et idées sont détaillés dans display . Cela signifie que la compréhension de cette spécification vous aide à comprendre les spécifications qui détaillent essentiellement les valeurs d' display . Dans cet article, je vais jeter un œil aux valeurs de génération de boîte de displaynone et contents .

Tout est une boîte

En CSS, tout génère des boîtes. Une page Web est essentiellement un ensemble de blocs et de boîtes en ligne, ce que vous comprenez très bien si vous ouvrez DevTools dans votre navigateur préféré et commencez à sélectionner des éléments sur la page. Vous pouvez voir les cases qui composent la mise en page et comment leurs marges, remplissages et bordures sont appliqués.

Une image d'une mise en page simple avec une liste non ordonnée mise en évidence dans le navigateur DevTools
J'ai mis en surbrillance l'élément ul à l'aide de Firefox DevTools afin de pouvoir inspecter les différentes parties de la boîte. ( Grand aperçu )

Contrôler la génération de boîtes

Les valeurs none et contents de display déterminent si les boîtes doivent apparaître ou non. Si vous avez des éléments dans votre balisage et que vous ne voulez pas qu'ils génèrent une boîte en CSS, vous devez en quelque sorte supprimer la génération de la boîte. Il y a deux choses que vous pourriez vouloir faire. Qui sont:

  • Empêcher la génération d'une boîte et de tous ses enfants.
  • Empêche la génération d'une boîte mais affiche toujours les enfants.

Nous pouvons examiner tour à tour chacun de ces scénarios.

Plus après saut! Continuez à lire ci-dessous ↓

affichage : aucun

La valeur none de display est la façon dont nous empêchons la génération d'une boîte et de tous les enfants de cette boîte. Il agit comme si l'élément n'était pas là du tout. Par conséquent, il est utile dans les situations où vous avez l'intention de masquer complètement ce contenu, peut-être parce qu'il sera révélé plus tard après l'activation d'un lien.

Si j'ai un exemple avec un paragraphe, une liste non ordonnée et un autre paragraphe, vous pouvez voir que les éléments s'affichent dans un flux normal. L' ul a un arrière-plan et une bordure appliqués, ainsi qu'un rembourrage.

Voir l'exemple Pen Box Generation de Rachel Andrew.

Voir l'exemple Pen Box Generation de Rachel Andrew.

Si j'ajoute display: none à ul , il disparaît de l'affichage visuel, emportant avec lui les enfants de ul plus l'arrière-plan et la bordure.

Voir l'exemple d'affichage Pen Box Generation : none par Rachel Andrew.

Voir l'exemple d'affichage Pen Box Generation : none par Rachel Andrew.

Si vous utilisez display: none , cela masque le contenu à tous les utilisateurs du site Web. Cela inclut les utilisateurs de lecteurs d'écran. Par conséquent, vous ne devez l'utiliser que si votre intention est que la boîte et tout ce qu'elle contient soient complètement cachés à tout le monde.

Dans certaines situations, vous souhaiterez peut-être ajouter des informations supplémentaires pour les utilisateurs de technologies d'assistance telles que les lecteurs d'écran, mais les masquer pour les autres utilisateurs ; dans de tels cas, vous devez utiliser une technique différente. D'excellentes suggestions sont faites par Scott O'Hara dans son article « Inclusively Hidden ».

Utiliser display: none est donc assez simple. Utilisez-le dans une situation où vous souhaitez qu'une boîte et son contenu disparaissent de l'affichage, de l'arborescence de la boîte et de l'arborescence d'accessibilité (comme s'ils n'avaient jamais été là en premier lieu).

affichage : contenu

Pour le deuxième scénario, nous devons examiner une valeur d'affichage beaucoup plus récente. La valeur display: contents supprimera la boîte à laquelle elle est appliquée de l'arborescence de la même manière que display: none le fait, mais laisse les enfants en place. Cela provoque un comportement utile en termes de choses que nous pouvons ensuite faire dans nos mises en page. Regardons un exemple simple, puis explorons plus avant.

J'utilise le même exemple qu'avant, mais cette fois j'ai utilisé display: contents sur le ul . Les éléments de la liste sont maintenant visibles, cependant, ils n'ont ni arrière-plan ni bordures et agissent comme si vous aviez ajouté des éléments li à la page sans aucun ul englobant.

Voir l'exemple d'affichage Pen Box Generation : contenu par Rachel Andrew.

Voir l'exemple d'affichage Pen Box Generation : contenu par Rachel Andrew.

La raison pour laquelle supprimer une boîte et conserver les enfants est utile est due à la façon dont les autres valeurs d' display se comportent. Lorsque nous modifions la valeur de display , nous le faisons sur une boîte et les enfants directs de cette boîte, comme je l'ai décrit dans le dernier article. Si j'ajoute display: flex aux règles CSS d'un élément, cet élément devient une boîte de niveau bloc et les enfants directs deviennent des éléments flexibles. Les enfants de ces éléments flexibles reviennent au flux normal (ils ne font pas partie de la disposition flexible).

Vous pouvez voir ce comportement dans l'exemple suivant. Ici, j'ai un élément conteneur défini pour afficher flex, il a quatre enfants directs, trois éléments div et un ul . L' ul a deux éléments de liste. Les enfants directs participent tous à la mise en page flexible et se présentent comme des éléments flexibles. Les éléments de liste ne sont pas des enfants directs et s'affichent donc en tant qu'éléments de liste à l'intérieur de la boîte de ul .

Voir la boîte flexible Pen Box Generation et l'affichage : contenu 1 par Rachel Andrew.

Voir la boîte flexible Pen Box Generation et l'affichage : contenu 1 par Rachel Andrew.

Si nous prenons cet exemple et ajoutons display: contents à ul , la boîte est supprimée de l'affichage visuel et maintenant les enfants participent à la mise en page flexible. Vous pouvez voir qu'ils ne deviennent pas des enfants directs. Ils ne sont pas sélectionnés par le sélecteur universel enfant direct ( .wrapper > * ) comme le sont les éléments div et ul , et ils conservent l'arrière-plan qui leur est donné. Tout ce qui s'est passé, c'est que la boîte de l' ul contenant a été supprimée, tout le reste continue normalement.

Voir la boîte flexible Pen Box Generation et l'affichage : contenu 2 par Rachel Andrew.

Voir la boîte flexible Pen Box Generation et l'affichage : contenu 2 par Rachel Andrew.

Cela a des implications potentiellement très utiles si l'on considère des éléments en HTML qui sont importants pour l'accessibilité et les données sémantiques, mais qui génèrent une boîte supplémentaire qui peut nous empêcher de disposer le contenu avec une disposition flexible ou en grille.

Ceci n'est pas une "réinitialisation" CSS

Vous avez peut-être remarqué que l'un des effets secondaires de l'utilisation de display: contents est que la marge et le remplissage de l'élément sont supprimés. C'est parce qu'ils sont liés à la boîte, qui fait partie du modèle de boîte CSS. Cela pourrait vous amener à penser que display: contents est un bon moyen de vous débarrasser rapidement du rembourrage et de la marge sur un élément.

C'est une utilisation qu'Adrian Roselli a repérée dans la nature ; il était suffisamment inquiet pour écrire un article détaillé expliquant les problèmes de le faire - " display: contents n'est pas une réinitialisation CSS." Certains des problèmes qu'il soulève sont dus à un malheureux problème d'accessibilité dans les navigateurs actuellement avec display: contents dont nous parlerons ci-dessous. Cependant, même une fois ces problèmes résolus, supprimer un élément du buis simplement pour se débarrasser de la marge et du rembourrage est quelque peu extrême.

Si rien d'autre, cela poserait problème pour la future maintenance du site, un futur développeur pourrait se demander pourquoi ils ne semblaient pas pouvoir appliquer quoi que ce soit à cette mystérieuse boîte — manquant le fait qu'elle avait été supprimée ! Si vous avez besoin que margin et padding soient 0 , rendez-vous service à vous-même et réglez-les sur 0 de manière traditionnelle. Réservez l'utilisation de display: contents pour les cas particuliers où vous souhaitez vraiment supprimer la boîte.

Il convient également de noter la différence entre l' display: contents et la sous-grille CSS Grid Layout. Où display: contents supprime complètement la boîte, l'arrière-plan et la bordure de l'affichage, faire d'un élément de la grille une sous-grille conserverait n'importe quel style de boîte sur cet élément, et passerait simplement par le dimensionnement de la piste afin que les éléments imbriqués puissent utiliser la même grille. Pour en savoir plus, consultez mon article « CSS Grid Level 2: Here Comes Subgrid ».

Problèmes d'accessibilité et affichage : contenu

Un problème sérieux rend actuellement display: contents n'est pas utile pour la chose même pour laquelle il serait le plus utile. Les cas évidents pour display: contents sont les cas où des zones supplémentaires sont nécessaires pour ajouter un balisage qui rend votre contenu plus facilement compréhensible par ceux qui utilisent des lecteurs d'écran ou d'autres dispositifs d'assistance.

L'élément ul de notre liste dans le premier display: contents CodePen en est un parfait exemple. Vous pourriez obtenir le même résultat visuel en aplatissant le balisage et en n'utilisant pas du tout de liste. Cependant, si le contenu était sémantiquement une liste, serait mieux compris et lu par un lecteur d'écran sous forme de liste, il devrait être balisé comme tel.

Si vous voulez ensuite que les éléments enfants fassent partie d'une mise en page flexible ou en grille, tout comme si la boîte de l' ul n'était pas là, vous devriez pouvoir utiliser display: contents pour supprimer magiquement la boîte et la rendre ainsi - tout en laissant la sémantique en place. La spécification dit que cela devrait être le cas,

« La propriété display n'a aucun effet sur la sémantique d'un élément : celle-ci est définie par le langage du document et n'est pas affectée par CSS. Mis à part la valeur none, qui affecte également la sortie auditive/vocale et l'interactivité d'un élément et de ses descendants, la propriété display n'affecte que la mise en page visuelle : son but est de permettre aux concepteurs de modifier librement le comportement de mise en page d'un élément sans affecter le sous-jacent. sémantique du document.

Comme nous en avons déjà discuté, la valeur none masque l'élément aux lecteurs d'écran, cependant, d'autres valeurs d' display sont purement là pour nous permettre de changer la façon dont les choses s'affichent visuellement . Ils ne doivent pas toucher à la sémantique du document.

Pour cette raison, plusieurs d'entre nous ont été surpris de constater que display: contents retirait en fait l'élément de l'arbre d'accessibilité dans les deux navigateurs (Chrome et Firefox) qui l'avaient implémenté. Par conséquent, changer la sémantique du document, en faisant en sorte qu'un lecteur d'écran ne sache pas qu'une liste était une liste une fois que l' ul avait été supprimé à l'aide de display: contents . Il s'agit d'un bogue de navigateur - et sérieux en plus.

L'année dernière, Hidde de Vries a écrit ce problème dans son article "Marquage plus accessible avec display:contents " et a utilement soulevé des problèmes contre les différents navigateurs afin de les sensibiliser et de les amener à travailler sur un correctif. Firefox a partiellement résolu le problème, bien que des problèmes existent toujours avec certains éléments tels que le bouton. Le problème est activement travaillé dans Chrome. Il y a aussi un problème pour WebKit. Je vous encourage à mettre ces bogues en évidence si vous avez des cas d'utilisation pour l'affichage : le contenu qui serait impacté par les problèmes.

Jusqu'à ce que ces problèmes soient résolus et que les versions de navigateur qui présentaient le problème ne soient plus utilisées, vous devez être très prudent lorsque vous utilisez l'affichage : contenu sur tout ce qui transmet des informations sémantiques et doit être exposé à une technologie d'assistance. Comme le dit Adrian Roselli,

"Pour l'instant, veuillez n'utiliser display: contents que si vous allez tester avec une technologie d'assistance et que vous pouvez confirmer que les résultats fonctionnent pour les utilisateurs."

Il existe des endroits où vous pouvez utiliser display: contents en toute sécurité sans ce souci. L'une serait si vous deviez ajouter un balisage supplémentaire pour créer des solutions de repli pour votre grille de mises en page flexibles dans les anciens navigateurs. Les navigateurs qui prennent en charge l' display: contents prennent également en charge la grille et la boîte flexible, vous pouvez donc display: contents en éliminant les éléments div redondants ajoutés. Dans l'exemple ci-dessous, j'ai créé une grille basée sur des flotteurs, complète avec des wrappers de lignes.

J'utilise ensuite display: contents pour supprimer les wrappers de ligne afin de permettre à tous les éléments de devenir des éléments de grille et donc de faire partie de la disposition de la grille. Cela pourrait vous donner un outil supplémentaire lors de la création de solutions de secours pour les mises en page avancées dans la mesure où si vous avez besoin d'ajouter un balisage supplémentaire, vous pouvez le supprimer avec display: contents lors de la création de votre grille ou de votre mise en page flexible. Je ne pense pas que cette utilisation devrait causer des problèmes - bien que si quelqu'un a de meilleures informations sur l'accessibilité que moi et peut signaler un problème, veuillez le faire dans les commentaires.

Voir le Pen Removing row wrappers with display: contents par Rachel Andrew.

Voir le Pen Removing row wrappers with display: contents par Rachel Andrew.

Emballer

Cet article a examiné les valeurs de génération de boîte de la propriété display . J'espère que vous comprenez maintenant le comportement différent de display: none - qui supprime complètement une boîte et tous les enfants, et display: contents qui supprime uniquement la boîte elle-même. Vous devez également comprendre les problèmes potentiels liés à l'utilisation de ces méthodes en matière d'accessibilité.