hasLayout : une définitionhasLayouthasLayoutfiltercontenteditableBeaucoup d'incompatibilités de rendu dans Internet Explorer peuvent être corrigées en donnant la « mise en page » (layout) à l'élément. John Gallant et Holly Bergevin ont classé ces incompatibilités dans la catégorie des « bogues dimensionnels », signifiant par-là qu'on peut souvent les résoudre en appliquant une largeur ou une hauteur. Cela amène la question de savoir pourquoi la mise en page peut changer le rendu des éléments et leurs relations. Si c'est une bonne question, il est par contre difficile d'y répondre. Dans cet article, les auteurs se concentrent sur quelques aspects de cette matière complexe. Pour des discussions approfondies et des exemples, veuillez consulter les liens fournis.
hasLayout : une définitionLa mise en page est un concept propriétaire d'Internet Explorer pour Windows (IE/Win), qui détermine comment les éléments dessinent leurs contenus et les lient, interagissent avec d'autres éléments et s'y réfèrent, se comportent face aux événements de l'application/l'utilisateur et les transmettent.
Certaines propriétés CSS peuvent immanquablement déclencher cette qualité. Par défaut, certains éléments HTML ont la mise en page.
Les développeurs chez Microsoft ont décidé que des éléments devaient pouvoir acquérir une propriété (au sens de la programmation
orientée objets), qu'ils ont appelée hasLayout (N.d.T., qui a la mise en page) et qui a la valeur true lorsque ce concept de rendu prend effet.
Nous disons d'un élément qu'il gagne la mise en page
ou qu'il a la mise en page lorsque la propriété exclusive de Microsoft
hasLayout
de cet élément a la valeur true. Un élément qui a la mise en page
peut être n'importe quel élément qui l'a par défaut, ou qui l'a gagnée grâce au paramétrage approprié d'une propriété CSS.
La propriété hasLayout n'est pas déclenchée dans les éléments qui n'ont pas la mise en page,
c'est-à-dire qu'un élément div pur, sans dimension, peut être un ancêtre qui n'a pas la mise en page.
Donner ou appliquer la mise en page à un élément qui ne l'a pas par défaut implique de paramétrer une propriété CSS qui déclenche hasLayout=true pour l'élément en question. Cf. les sections « Les éléments qui ont la mise en page par défaut » et « Les propriétés » pour des listes. Il n'y a pas d'autre moyen d'établir hasLayout=false que de supprimer ou réinitialiser la propriété CSS qui a enclenché hasLayout=true au départ.
Le problème hasLayout affecte les concepteurs (et les codeurs) à tous les niveaux d'expérience. La mise en page
a des effets inhabituels et difficiles à prévoir sur l'affichage des boîtes ainsi que des implications pour leurs éléments descendants.
Avoir ou non la mise en page peut entraîner les conséquences suivantes :
La liste précédente est brève et incomplète. Cet article tente de décrire précisément les problèmes rencontrés dans l'application de la mise en page ou faute de l'appliquer.
Contrairement aux propriétés standards, ou même aux propriétés CSS exclusives disponibles dans différents navigateurs, la mise en page n'est pas directement affectée via des déclarations CSS. En d'autres termes, il n'existe pas de « propriété layout ». Certains éléments acquièrent automatiquement la mise en page, qui s'ajoute silencieusement en présence de déclarations CSS variées.
Les éléments suivants ont la mise en page par défaut :
<html>, <body><table>, <tr>, <th>, <td><img><hr><input>, <button>, <select>, <textarea>, <fieldset>, <legend><iframe>, <embed>, <object>, <applet><marquee>Les couples de propriété/valeur CSS suivants, si appliqués, permettent à un élément de gagner la mise en page.
width: toute valeur sauf "auto"hasLayout fait les choses de travers.height: toute valeur sauf "auto"zoom: toute valeur sauf "normal" (MSDN)Depuis Internet Explorer 7 (IE 7), la propriété overflow est devenu un déclencheur pour la mise en page.
overflow-x et
overflow-y n'est pas encore très répandue. Elles n'initiaient pas hasLayout dans les versions précédentes d'IE.De nouveaux acteurs hasLayout ont fait leur apparition dans IE 7. En ce qui concerne hasLayout,
les propriétés des types min/max fonctionnent de manière similaire aux propriétés width et height,
et les effets des positionnements fixes et absolus semblent identiques.
min-width: toute valeurmax-width: toute valeur sauf "none"min-height: toute valeurmax-height: toute valeur sauf "none"Ceci est fondé sur l'interrogation de la barre d'outils des développeurs d'IE (IE Developer Toolbar) et sur des tests préliminaires.
Pour les éléments de type en-ligne (soit de type en-ligne par défaut comme l'élément span, soit ayant
display: inline) :
width et height déclenchent hasLayout dans IE 5.x,
et dans IE 6 et suivants, seulement en « mode des bizarreries » (quirks mode). Depuis IE 6,
lorsque le navigateur est en « mode de conformité aux standards », les éléments de type en-ligne ignorent les propriétés width
et height, et leur paramétrage n'attribuera pas la mise en page à l'élément ;zoom déclenche toujours hasLayout, mais elle n'est pas reconnue dans IE 5.0.Les éléments ayant à la fois la mise en page et display: inline ont un comportement similaire
à ceux avec la déclaration display: inline-block définie dans les standards : ils s'écoulent horizontalement comme des mots
dans un paragraphe, sont sensibles à l'alignement vertical et appliquent une sorte d'enveloppe rétractable
à leurs contenus. Dès que les éléments en-ligne ont la mise en page, ils se comportent comme pour inline-block,
et c'est une explication au fait que les éléments en-ligne, dans IE/Win, peuvent contenir et loger des
éléments de type bloc avec moins de problèmes que dans les autres navigateurs,
où pour display: inline les éléments restent en-ligne.
hasLayoutLa réinitialisation des propriétés suivantes à leurs valeurs par défaut dans un jeu de règles séparé réinitialisera (ou défera)
hasLayout, si aucune autre propriété donnant la mise en page reste en vigueur :
width, height (à "auto")max-width, max-height (à "none" dans IE 7)position (à "static")float (à "none")overflow (à "visible" dans IE 7)zoom (à "normal")writing-mode (de "tb-rl" à "lr-tb")Les auteurs doivent se montrer prudents pour la réinitialisation de ces propriétés. Prenons un système de menu ; changer l'état
de hasLayout sur un a:hover, intentionnellement ou non, peut produire un rendu inattendu (ou une
instabilité du programme avec IE 6 lorsqu'on le défait dynamiquement en combinaison avec position: relative).
La propriété display est différente : tandis que la valeur "inline-block" établit haslayout=true,
le drapeau ne sera pas réinitialisé à "false" si on l'écrase ensuite avec les valeurs
"block"
ou "inline"
dans un autre jeu de règles.
Le paramétrage des propriétés min-width et min-height à leur valeur par défaut "0"
donne toujours la mise en page, mais IE 7 accepte pour elles la valeur invalide "auto",
qui réinitialise hasLayout.
hasLayoutNous avons choisi de considérer hasLayout comme une « propriété de script » afin de la distinguer des propriétés CSS
familières.
Il n'existe aucun moyen d'initialiser ou de réinitialiser directement la propriété de script hasLayout.
On peut utiliser la propriété hasLayout
pour vérifier si un élément a la mise en page : par exemple, si l'attribut id de celui-ci vaut "eid",
alors il suffit simplement de taper javascript: alert(eid.currentStyle.hasLayout) dans la barre d'adresse des navigateurs IE 5.5+
pour tester son état.
La barre d'outils des développeurs d'IE
permet d'inspecter en direct le style courant d'un élément ; lorsque la propriété hasLayout est vérifiée (true),
sa valeur est signalée par "-1". En éditant en direct les attributs d'un nœud, vous pouvez donner à zoom (CSS) la valeur "1"
afin de déclencher hasLayout pour les besoins du débogage.
Une autre chose à examiner est la façon dont la mise en page affecte les scripts. Les propriétés
clientWidth ou clientHeight retournent toujours zéro pour les éléments sans mise en page.
Ce comportement peut être déroutant pour les créateurs de scripts novices, car il diffère de celui des navigateurs de type Mozilla.
Nous pouvons utiliser ce fait pour déterminer la mise en page avec IE 5.0 :
si la propriété clientWidth vaut zéro, alors l'élément n'a pas la mise en page.
Les bidouilles (hacks) suivantes pour déclencher hasLayout ont été testées dans
IE 7 et précédents.
John Gallant et Holly Bergevin ont livré la « bidouille de Holly » en 2003 :
Cette bidouille :
height explicite) ;* html ne sélectionne rien du tout.Pour donner la mise en page dans IE 6 et précédents, nous pouvons aussi utiliser la bidouille du souligné :
Et pour donner la mise en page dans IE 7, nous pouvons utiliser la propriété min-height :
Sinon, et probablement à l'épreuve du temps, il y a les commentaires conditionnels :
L'utilisation d'une feuille de style externe pour toutes corrections nécessitées par IE/Win, appelée depuis un commentaire conditionnel, est une solution sûre et élégante :
Pour IE 6 et précédents, il faudrait « toujours » utiliser la propriété height
(si nous voulons inclure IE 5.0, il n'y a pas tellement de choix), à moins que celle-ci n'entre en conflit avec autre chose
(overflow: hidden). En ce qui concerne sa valeur, les valeurs "1%", "1px" et "0" sont plus ou moins équivalentes, mais
la valeur "1%" peut (quoique très rarement) poser des problèmes.
La propriété height ne peut pas être utilisée pour les éléments en-ligne en mode standard et on devrait l'éviter dans
IE 7 (ou l'utiliser prudemment : seulement avec des valeurs en pourcentage et uniquement si l'élément parent n'a pas de
propriété height explicite). Dans ces cas, nous préférons display: inline-block ou zoom: 1.
Nous avons vu des tentatives de bidouillage désespérées, en application sur des éléments flottants, ou sur des éléments ayant déjà
une propriété width. Retenez que le but de cette bidouille n'est pas d'attribuer une hauteur mais de déclencher
hasLayout=true.
Ne donnez pas la mise en page à tout : * {_height: 1px;}. C'est du poison à cette dose, avoir la mise en page n'est pas le remède, cela change fondamentalement le rendu.
Comme le montre l'apparition d'IE 7, il est impossible de prévoir si les versions futures d'IE nécessiteront encore hasLayout
pour corriger quelques bogues et comment elles réagiront aux filtres utilisés aujourd'hui. Dans cette perspective,
on peut conseiller d'utiliser les techniques propriétaires de Microsoft, à savoir la propriété zoom
et/ou les commentaires conditionnels.
inline" se comportent comme ceux avec "inline-block") ;zoom dans un commentaire conditionnel.Bien que nous pensons que l'expression « à l'épreuve du temps » soit une contradiction dans les termes, nous suggérons vigoureusement aux concepteurs Web de « jouer sûrement », de revoir leurs pages à la recherche de bidouilles explicites et implicites, et d'utiliser des commentaires conditionnels pour servir ces bidouilles aux versions appropriées des navigateurs.
Pour une vue détaillée des déclencheurs hasLayout et une comparaison des bidouilles hasLayout dans
les diverses versions d'IE, cf. l'article « Réflexions sur la gestion des bidouilles pour IE ».
IE Mac et IE pour Windows sont deux animaux différents, vivant dans des parties séparées du zoo. Chacun a son propre moteur de rendu,
et IE Mac ne connaît en aucune façon le comportement hasLayout (ou contenteditable).
Le moteur de rendu d'IE Mac tend à être plutôt conforme aux standards, en traitant la propriété height comme il se doit.
Les bidouilles et contournements de problèmes de hasLayout (spécialement dans l'utilisation des propriétés height
ou width) auront souvent des effets désastreux dans IE Mac, et il faudrait les cacher à ce navigateur.
Plus sur les problèmes d'IE Mac dans « Les curiosités d'Internet Explorer 5 pour Mac ».
Dans le site communautaire MSDN (Microsoft Developer Network), il y a peu de pages consacrées
à la propriété hasLayout, et encore moins d'explications concernant l'influence de la mise en page
sur le modèle de formatage visuel d'IE.
Dans IE 4 déjà, presque tous les éléments avaient une sorte de mise en page,
sauf les éléments en-ligne simples en position non absolue et sans dimension (le document MSDN a été modifié [1]).
Et dans ce concept précurseur de la mise en page, il y avait des « propriétés de mise en pages » (layout properties)
telles border, margin, padding, qui ne pouvaient pas s'appliquer à ces éléments en-ligne simples.
En d'autres termes, « avoir la mise en page » était à peu près synonyme de « peut avoir ces propriétés ».
MSDN parle toujours de « propriétés de mise en pages »,
mais la signification a changé, elles ne sont plus associées aux éléments ayant la mise en page.
La propriété Microsoft hasLayout
a été introduite dans IE 5.5, plus ou moins comme un drapeau interne.
Dans IE 5.5, la documentation de la plateforme d'édition MSHTML (qui permet d'éditer, dimensionner et faire glisser dynamiquement les éléments qui ont la mise en page via <body contenteditable=true>) révèle trois aspects importants sur le fait d'avoir la mise en page :
« Si un élément qui a la mise en page a un contenu, alors son rectangle englobant détermine la mise en page du contenu. »
« Avoir la mise en page signifie essentiellement qu'un élément est rectangulaire. »
« En interne, avoir la mise en page signifie qu'un élément est responsable du dessin de son propre contenu. »
(Plateforme d'édition : pièce retirée de la documentation MSDN [2])
Jusqu'en août 2005, les fonctionnements internes liés à la mise en page en question n'étaient pas documentés, lorsque Markus Mielke (Microsoft), à la suite de « The Web Standards Project » et du groupe d'étude de Microsoft, ouvrit les portes pour une discussion approfondie :
« En général, les éléments dans le moteur HTML dynamique d'Internet Explorer ne sont pas responsables de leur propre arrangement. Des éléments
divouppeuvent avoir une certaine position dans l'ordre de la source et dans le flux du document, mais leurs contenus sont arrangés par leur ancêtre qui a la mise en page le plus proche (fréquemmentbody). Ces éléments s'appuient sur la mise en page de l'ancêtre pour faire tous les gros travaux de détermination des informations de dimension et de mesure à leur place. »
Notre interprétation est une tentative d'explication de ce qui se passe dans des cas connus, et elle devrait servir de guide
pour les cas qui ne sont pas entièrement démêlés. Une tentative qui consiste seulement à démystifier une boîte noire en y insérant
quelques jeux d'essais et en écoutant si la sonnette retentit est vouée à l'échec. La question du pourquoi ne peut pas être résolue.
Il nous faut comprendre la plateforme dans laquelle fonctionne le modèle hasLayout en entier. De cela, on peut tirer des
indications (et ce ne sont que des indications pas des solutions absolues).
Nous pensons qu'elles concernent une fenêtre étroite. Le contenu d'un élément qui a la mise en page serait complètement indépendant de tout se qui se trouve hors des limites de l'élément, et le contenu ne pourrait rien affecter en dehors non plus.
La propriété Microsoft hasLayout est une sorte de drapeau : lorsqu'il est mis, l'élément a cette « qualité »
mise en page, qui inclut des capacités spéciales, par exemple sur le flottement
et l'empilement, pour l'élément même ou pour ses sous-éléments sans mise en page.
Cette plus grande indépendance des éléments qui ont la mise en page est probablement la raison pour laquelle ils sont généralement plus stables, et font donc disparaître quelques bogues. Le prix à payer pour ça est à la fois un écart par rapport aux standards et d'autres bogues/problèmes à leurs frontières.
On peut assimiler le modèle de la « page » de Microsoft, dans une pensée sémiotique, comme constitué de petits blocs d'histoires sans liens de parenté, tandis que le modèle de la « page » HTML du W3C est une histoire narrative complète, où les blocs d'information sont liés.
Les flottants sont auto-contenus par les éléments qui ont la mise en page. C'est une raison pour laquelle la plupart des débutants se débattent avec leurs pages construites pour IE dans les navigateurs conformes, où les flottants dépassent du conteneur s'ils ne sont pas dégagés (cleared).
Le comportement opposé : et si un flottant doit dépasser de son conteneur, par exemple, que l'auto-contenance n'est pas l'effet désiré ? Pour une démonstration des problèmes frustrants que l'on peut rencontrer, jetez un coup d'œil à notre discussion approfondie :
Dans IE, un flottant « appartiendra » toujours à son conteneur qui a la mise en page. Les éléments suivants peuvent respecter le conteneur qui a la mise en page mais pas le flottant lui-même.
Ce comportement et celui de prolongement d'un conteneur pour loger un contenu plus large d'IE 6 (le « prolonger pour loger ») peuvent être vus comme un aspect de la règle du « rectangle englobant déterminant la mise en page ».
Pire encore : la propriété clear ne peut pas affecter un flottant hors du conteneur qui a la mise en page de l'élément dégageur.
Les mises en pages de flottants comptant sur ce bug dans IE ne sont pas transférables et elles ne pourront fonctionner dans un navigateur conforme
sans une refonte générale.
L'auto-contenance du flottant d'IE, qui est parfois inévitable, ne peut pas être obtenue dans d'autres navigateurs : cf. notre section « Les similarités avec les spécifications CSS » pour des concepts de confinement des flottants.
Lorsqu'un élément de type bloc suit un élément flottant, il devrait (en tant que bloc) ignorer le flottant, toutefois son contenu devrait être déplacé par le flottant : le texte dans un élément de type bloc à côté d'un élément flottant à gauche devrait s'écouler à la droite du flottant puis (s'il est plus long que le flottant) continuer sous lui. Mais si le bloc a la mise en page, par exemple du fait de l'affectation d'une largeur, alors l'élément entier est déplacé par le flottant, comme s'il était lui-même un flottant, et son contenu textuel n'épouse donc plus le contour du flottant (il reste à sa droite dans sa forme rectangulaire).
Dans IE 5, une largeur en pourcentage se calcule d'après l'espace disponible à côté du flottant, et dans IE 6, d'après la largeur disponible entière du bloc parent. Donc, dans IE 6, une déclaration width: 100% se traduit par quelque chose qui ne tient pas à côté du flottant, avec tous les problèmes de mise en pages causés par les blocs qui ne se logent pas.
Voici les jeux d'essais pour des blocs hasLayout adjacents de blocs flottants :
De la même façon en réalité, les éléments en position relative à côté de flottants devraient se décaler
par rapport au bord d'espacement du parent (c'est-à-dire que la déclaration left: 0;
sur une élément en position relative devrait le placer au sommet d'une boîte flottant à gauche précédente). Dans IE 6,
un décalage left: valeur commence au bord de la marge droite du flottant, provoquant un
désalignement horizontal de la totalité de la largeur (total outer width)
du flottant (un palliatif serait d'utiliser margin-left à la place, mais attention aux anomalies bizarres des pourcentages).
Selon les spécifications, les flottants s'entrelacent avec les boîtes suivantes. Cela ne peut pas être réalisé avec des rectangles en deux dimensions qui ne s'entrecroisent pas.
Si l'auteur abdique devant les insuffisances d'IE, la question se pose alors de savoir comment rendre les boîtes dans les navigateurs conformes aux standards similaires à ces boîtes avec mise en page qui « se rétractent » pour laisser de la place à un flottant précédent. Nous donnons des pistes afin d'établir un nouveau contexte de formatage de bloc à côté du flottant dans notre section « Les similarités avec les spécifications CSS ».
En (re)visitant cette page-ci de bogues dans IE 6 :
Nous constatons que la boîte avec la mise en page suivant le flottant ne montre pas l'écart de 3 pixels du texte, parce que l'entourage codé de 3 pixels du flottant ne peut plus affecter le contenu dans l'élément qui a la mise en page, mais pousse l'élément qui a la mise en page entier de 3 pixels. Tel un bouclier, la mise en page empêche d'affecter le contenu mais l'énergie de poussée du flottant déplace la boîte protégée en question.
Les listes sont affectées par la mise en page, qu'elle s'applique à la liste (ol, ul),
ou bien aux éléments de la liste (li). Les diverses versions d'IE réagissent différemment. Les effets les plus visibles touchent
aux marqueurs de listes (les listes entièrement personnalisées, où les marqueurs sont supprimés,
n'ont pas ces problèmes). Les marqueurs sont probablement créés par l'addition interne, plutôt instable, d'éléments en quelque sorte
« accrochés » aux éléments de listes (habituellement accolés à eux). Malheureusement, comme ce sont seulement des objets « internes »,
on ne peut pas y accéder pour tenter d'en corriger les inconduites.
Les effets les plus visibles sont les suivants :
On peut parfois les rétablir en changeant les marges des éléments de listes (li). Cela semble provenir du fait qu'un
élément qui a la mise en page tend à rogner les éléments internes qui s'y accrochent.
Un autre problème (dans les listes ordonnées) est que tout élément de liste qui a la mise en page semble avoir son propre compteur. Supposons que nous ayons une liste ordonnée de cinq éléments où seul le troisième a la mise en page. Nous verrons ceci :
1... 2... 1... 4... 5...
En outre, lorsqu'un élément de liste qui a la mise en page s'affiche sur plusieurs lignes, le marqueur s'aligne en bas (et non en haut comme on s'y attendrait).
Tous ces problèmes ne peuvent pas être résolus, et si on souhaite des marqueurs, il vaut donc mieux éviter la mise en page sur les listes et éléments de listes. Si on a besoin d'appliquer des dimensions, il vaut mieux le faire sur les autres éléments : par exemple, on peut appliquer une largeur à une enveloppe extérieure et une hauteur au contenu de chaque élément de liste.
Un autre problème commun avec les listes dans IE survient lorsque le contenu d'un élement li est une ancre avec
la déclaration display: block. Dans ces conditions, les caractères blancs (whitespace)
entre les éléments de liste ne sont pas ignorés et s'affichent habituellement comme une ligne supplémentaire pour chaque li.
Une méthode pour supprimer cet espace vertical en trop est de donner la mise en page à ces ancres de type bloc.
Cela présente aussi l'avantage de rendre cliquable la totalité de la zone rectangulaire de l'ancre.
Un élément table a toujours la mise en page et se comporte toujours comme un objet à largeur définie.
Dans IE 6, la déclaration table-layout: fixed
se traduit normalement par une table large de 100%, avec tous les problèmes que ça comporte (erreurs d'arrondis).
En note marginale, quelques petites choses
sur la situation dans IE 5.5 et dans IE 6 en « mode des bizarreries ».
Notez que position: relative ne déclenche pas hasLayout, ce qui conduit à quelques erreurs de rendu,
principalement du contenu disparu ou mal placé. On peut rencontrer des incompatibilités lors du rechargement de la page,
du redimensionnement ou du défilement de la fenêtre, de la sélection. Avec cette propriété, IE décale l'élément en semblant oublier
d'envoyer un signal de « rafraîchissement » à ses sous-éléments qui ont la mise en page (comme un
élément qui a la mise en page l'aurait correctement fait en l'envoyant dans la chaîne de commande
des événéments de rafraîchissement).
Les pages précédentes en offrent des descriptions proches. En règle générale, ne jamais positionner un élément relativement sans établir la mise en page. De plus, on peut vérifier si le parent d'une telle construction a aussi besoin de la mise en page et/ou de position: relative, cela devient crucial lorsque des flottants sont affectés.
Il est essentiel de comprendre le concept CSS du bloc conteneur, qui répond à la question de savoir à quoi rapporter un élément en position absolue pour définir l'origine des décalages et calculer les pourcentages des longueurs.
Pour les éléments en position absolue, le bloc conteneur est établi par son ancêtre positionné le plus proche. S'il n'y en a pas,
le bloc conteneur initial html est utilisé.
Normalement, un tel bloc conteneur serait établi via position: relative. Cela signifie que nous pouvons laisser les éléments en position absolue se rapporter aux longueurs et aux origines indépendamment du flux des éléments, c'est-à-dire de satisfaire aux besoins du concept d'accessibilité du « contenu d'abord » ou de faciliter les choses dans les mises en pages complexes avec des flottants.
Cette conception est remise en cause par IE : les décalages d'un éléments en position absolue sont correctement calculés seulement si le bloc conteneur a la mise en page, et la largeur en pourcentage d'un élément en position absolue peut se rapporter au mauvais ancêtre. Sur ce point, IE 5 et IE 6 se comportent différemment, mais tous deux ont des problèmes. IE 7b2 a un comportement plus cohérent, pourtant erroné dans certains cas. Si possible, essayez de vous tenir aux cas dans lesquels le bloc conteneur a la mise en page et est le parent de l'élément en position absolue (c'est-à-dire, qu'il ne doit pas y avoir d'autres ancêtres entre l'élément en position absolue et le bloc conteneur).
Supposons un parent sans mise en page en position relative, il nous faut impérativement lui donner la mise en page pour que le décalage fonctionne :
Supposons qu'un parent non positionné doive avoir une dimension, et que le plan repose sur le calcul d'une largeur en pourcentage, nous pouvons abandonner cette idée en absence de mise en œuvre dans les navigateurs :
filterLa propriété exclusive de Microsoft filter
ne s'applique qu'aux éléments qui ont la mise en page. Elle présente des
défauts spécifiques.
Une fois tous les éléments rendus, IE repositionne le bloc conteneur qui a la mise en page
lorsqu'une transition :hover (c'est-à-dire un changement de la propriété background du lien) se produit.
Les éléments se trouvent parfois à une nouvelle position car toutes les largeurs et tous les décalages des éléments concernés ne sont connus
d'IE qu'au moment de la transition hover. Il est peu probable que ce soit le cas lors du premier chargement,
où la largeur n'est pas encore déterminée, à cause de la caractéristique de « prolongement-pour-loger» (expand-to-fit).
Il peut y avoir un à-coup lors du hover.
Ces bogues relationnels, liés au problème du repositionnement, créent des problèmes dans les mises en pages liquides dans lesquelles l'utilisation de pourcentages pour les marges et espacements est la plus courante.
La propriété hasLayout de Microsoft affecte l'extension et le positionnement de l'arrière-plan. Par exemple,
conformément à spécification CSS,
la déclaration background-position: 0 0 devrait se rapporter au « bord de l'espacement » (padding edge)
de l'élément. Dans IE/Win, elle se rapporte au « bord de la bordure » (border edge) si hasLayout=false,
et au « bord de l'espacement » si hasLayout=true :
La propriété hasLayout de Microsoft affecte la fusion des marges (collapsing of margins)
entre une boîte et ses descendants. Selon la spécification, la marge du haut d'une boîte sans espacement haut ni espacement bas
et la marge du haut de son premier sous-élément de type bloc dans le flux devraient fusionner :
Dans IE/Win, ce n'est jamais le cas si la boîte a la mise en page : il semble que la mise en page empêche les marges du sous-élément de dépasser de la boîte englobante. En plus, si hasLayout=true, que ce soit sur le conteneur ou sur le sous-élément, d'autres erreurs de calcul des marges apparaissent :
La propriété hasLayout affecte la zone cliquable/sensible au survol des ancres de type bloc. Normalement,
avec hasLayout=false, seule la partie couverte par le texte est sensible. Avec hasLayout=true, la totalité
de l'aire du bloc est sensible. C'est la même chose pour tout élément de type bloc auquel est associé
un gestionnaire d'événement onclick/onmouseover.
Lorsqu'on « tabule » à travers une page et qu'on arrive sur un lien interne à la page, la pression suivante de la touche « tabulation » ne reprend pas sur l'ancre suivante :
La touche « tabulation » mènera l'utilisateur, souvent en le trompant, à la première cible de l'ancêtre qui a la mise en page
le plus proche (si cet ancêtre est représenté par un élément table, div, span, et d'autres éléments).
Certaines propriétés appliquées aux éléments avec width: auto les poussent à calculer leur largeur selon un algorithme de rétractation. Comme exemples de ces propriétés : float: left|right, position: absolute|fixed, display: table|table-cell|inline-block|inline-table.
Cela fonctionne dans IE/Win et se limite bien sûr aux propriétés gérées. Mais lorsque l'élément qui devrait se rétracter contient un élément de type bloc affecté d'une mise en page, alors dans la plupart des cas, ce sous-élément s'étend sur toute la largeur disponible, indépendamment de son contenu, et empêche l'effet de rétractation du parent.
ul de navigation verticale flottant ne se rétracte pas, car il fallait une déclaration a {display: block; zoom: 1;}
sur les liens pour corriger le bogue de la ligne blanche des listes et pour étendre la zone cliquable.La rétractation reste en vigueur seulement si le sous-élément avec la mise en page est affecté d'une largeur,
ou s'il a lui-même une propriété à rétractation telle que float.
En général, lorsqu'une boîte contient des structures plus complexes, comme un contenu qui dépasse, la propriété hasLayout
est souvent nécessaire sur ce conteneur pour éviter des problèmes de rendu. Cette quasi obligation entraîne un dilemme aux frontières,
puiqu'un élément de type bloc gagnant la mise en page devient une sorte de
boîte auto-contenue.
Les boîtes de contenu imbriquées poussées hors de cet élément (par exemple, en utilisant des marges négatives) sont rognées.
Les parties rognées peuvent être rétablies en déclenchant hasLayout sur cette boîte de contenu, et dans IE 6,
il faudra aussi utiliser position: relative. Le comportement d'IE 7 montre un léger mieux
puisque la déclaration position: relative n'est plus nécessaire.
Il semble y avoir deux ordres des couches et de l'empilement au sein d'IE/Win :
hasLayout et son acolyte le comportement contenteditable.
Comme illustré dans l'exemple du positionnement relatif, le fait de ne pas avoir la mise en page peut affecter
l'empilement d'une façon qui enchanterait Harry Houdini.Les deux modèles d'empilement, incompatibles, sont des résidents du moteur de rendu d'IE. En règle générale, pendant le débogage, ne pas oublier de surveiller les deux suspects. Nous voyons régulièrement des problèmes liés dans les menus déroulants ou de complexité similaire, où l'empilement, le positionnement et le flottement peuvent concourir à des désastres variés, et les corrections de bogues peuvent consister en mises en pages positionnées en couches, mais c'est variable, vous êtes prévenus.
contenteditableL'attribut contenteditable=true, affecté à une balise HTML tel que <body contenteditable=true>,
permet l'édition, le glissement et le redimensionnement en direct de l'élément qui a la mise en page et ses sous-éléments.
Essayez donc ça avec des éléments flottants ou des éléments li qui ont la mise en page
dans une liste ordonnée.
Afin de manipuler les éléments (les éditer), contenteditable et hasLayout introduisent un
ordre d'empilement séparé pour les éléments avec hasLayout=true.
La plateforme d'édition (un document retiré du réseau MSDN [2])
hérite du concept de mise en page, preuve que contenteditable est la raison
de la conception erronée de la mise en page (avec l'implication que les applications intégrant
quelque peu le moteur d'édition d'IE forcent une rétrocompatibilité vers ce concept de mise en page).
Vos pages conçues pour IE sont-elles défaillantes dans les autres navigateurs ? Ce n'est pas une fatalité, sachez-le ! N'importe quel bon navigateur peut tout aussi bien manipuler les conceptions d'IE si vous lui demandez gentiment (et lui servez du CSS valide).
L'utilisation des « quelques » similarités trouvées entre hasLayout et l'établissement d'un
« nouveau contexte de formatage de bloc »,
nous donne le moyen de reproduire l'effet de hasLayout pour le
« confinement des flottants »
et le comportement des « éléments à côté d'un élément flottant »
dans les navigateurs conformes aux standards.
Veuillez consulter « Le mode des bizarreries dans IE 6 et IE 7 » (quirks mode) pour des renseignements à propos de ce mode de rendu.
Le concept de la mise en page dans son ensemble n'est pas compatible avec plusieurs concepts CSS de base du modèle de formatage visuel, comprenant notamment ceux de flux, de flottement et des couches.
Cela entraîne des violations propres à IE/Win de la spécification CSS dues à la présence ou l'absence de mise en page sur les éléments de la page.
Le modèle d'objets dans Explorer paraît être l'hybride d'un modèle de document et de leur modèle d'application traditionnel. J'en fait mention car c'est important pour comprendre comment Explorer rend les pages. La bascule pour sauter d'un modèle de document à un modèle d'application est le fait de donner la mise en page à un élément.
Parfois, il est impossible de donner une interprétation d'un certain comportement : c'est simplement comme si, en fonction de l'état
de hasLayout, l'un des deux moteurs de rendus différents était utilisé, chacun avec ses propres bizarreries et bogues.
Les bogues des logiciels sont les conséquences d'erreurs humaines et d'une absence de prise en compte du global et de logique pendant le processus de création. C'est un défaut humain fondamental pour lequel il reste à découvrir un remède durable.
Toutes les tentatives de corriger un programme bogué sans le recréer à zéro aboutira inévitablement à encore plus de bogues plus complexes trouvant leur chemin dans le logiciel à cause de ces mêmes défauts humains.
Tout programme qui repose sur d'autres, y compris (bien sûr) les systèmes d'exploitation, héritera aussi de leurs bogues. Nous obtenons ainsi une cascade de bogues de tous les bouts de code impliqués, qui rend l'idée même de trouver un programme sans bogues complètement absurde.
Cet article est d'abord paru le 30 juin 2005 et a été révisé pour la dernière fois le 23 octobre 2007.
Adresse permanente : http://www.satzansatz.de/cssd/onhavinglayout.html