Pourquoi mes calques sont-ils plus grands que ce que je demande lorsqu'on visite mon site avec NN6 ou Opera ? Peut-on arranger ça ?

Cela n'arrive pas qu'aux calques. En effet, chaque fois qu'on définit un bloc avec des dimensions en pixels, que ce soit dans un éditeur wysiwyg comme DW2 ou qu'on code les width et height à la main, et puis qu'on y ajoute un padding (marge interne) et/ou une bordure, une simple copie d'écran montre aisément que ce bloc ne fait les dimensions prescrites que sous Explorer (ou NN4, peut-être...). Sur les navigateurs alternatifs plus récents comme Opera, NN6 ou Mozilla, il est plus grand et cela peut entraîner divers désagréments : apparition d'ascenseurs indésirables, chevauchements inattendus ; si le calque a une image de fond, début de duplication de cette image.

En fait, si on se réfère à la norme du consortium W3C, c'est Explorer qui a tort. Les paramètres de largeur et de hauteur (width et height) ne concernent pas les dimensions totales occupées sur la page, mais seulement le contenu interne du calque ou du bloc. Si on définit une marge interne et une bordure, on doit ajouter les épaisseurs de marge et de bordure aux width et height pour obtenir les dimensions totales occupées sur la page.

Autrement dit, quand on a choisi width et height, Explorer place les bordures et marges internes à l'intérieur, réduisant d'autant l'espace utile, tandis que les navigateurs conformes (Opera, NN6, Mozilla...) les placent à l'extérieur, prenant donc plus de place dans la page. Le style suivant :
div.bloc1 {background:red;
              width:200px; height:100px;
              padding-left:20px; padding-right:10px;
              border:6px solid black; ...} 
se traduira par un pavé rouge 200x100 sur Explorer et 242x100 sur NN6 (242 = 200 + 20 + 10 + 2x6).

Il est inutile de s'insurger contre cet état de fait ou de déplorer que le W3C ait fait un choix contre-intuitif. Il vaut mieux chercher à coder de manière plus habile pour contourner ce piège. On a le choix entre plusieurs attitudes.

  1. Eviter les mises en pages trop rigides au pixel près. Bien entendu, c'est la sagesse même... mais ce n'est pas toujours possible.
  2. Contre-attaque frontale : puisque Explorer dévie de la norme, chercher d'autres failles d'Explorer qui permettront d'ajouter d'autres instructions qui ne seront comprises que par les navigateurs conformes. Attention, ce genre de rustine ne reste pas éternellement valide. Par exemple, la méthode [1] souvent proposée fonctionne bien avec IE5/6-windows, mais pas avec IE5-mac. Une méthode plus universelle en cette mi-2002 serait d'ajouter la déclaration

            div.bloc1[class] {width:158px}

    juste après les lignes ci-dessus. Il s'agit d'une déclaration avec un sélecteur d'attribut qu'aucun des Explorer actuels ne sait lire et par le biais duquel on peut donc transmettre une largeur «corrigée» aux navigateurs conformes. Mais on retrouvera le même problème si jamais Microsoft sort un IE7 avec toujours avec la même conception des dimensions des blocs, mais capable de lire les sélecteurs d'attribut.
  3. Esquiver en souplesse : puisque les difficultés naissent des paddings et border, enlever ceux-ci et les reporter un bloc DIV interne sans dimensions déclarées.
Per exemple, on peut remplacer <div class="bloc1">, avec la classe bloc1 définie plus haut, par les lignes suivantes :
   <div class="bloc1a">
       <div class="bloc1b">
             bla bla bla...
       </div>
   </div>
avec des classes de style bloc1a et bloc1b définies par
.bloc1a {background:red; width:200px;} 
.bloc1b {padding-left:20px; padding-right:10px;
             border:6px solid black; ...} 
Le premier DIV donne les dimensions extérieures sur la page. Le deuxième DIV sans dimensions spécifiées occupe la place maximum dans le premier bloc, mais reste à l'intérieur ; la bordure et la marge viennent donc à l'intérieur des 200 pixels.

On notera qu'on a supprimé le height des styles. En effet, le mécanisme d'occupation de l'espace «disponible» ne fonctionne qu'en largeur, pas en hauteur. Si on fixe un height:100px pour le premier DIV et rien pour le second, la bordure du second bloc se refermera sur son contenu sans tenir compte des 100px demandés, et si on fixe height:inherit ou height:100% pour le second bloc, les navigateurs conformes ajouteront l'épaisseur de la bordure et celle-ci sortira du pavé rouge. Il vaut donc mieux se passer totalement de height explicite et laisser faire les navigateurs... quitte à revenir au vieux truc du gif transparent si on veut absolument imposer une hauteur.

bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla...

Ci-contre un exemple de rendu, sans aucun height, et avec une marge interne en haut, à gauche et à droite

Le codage est donc très légèrement plus compliqué. En revanche, il conduit aux mêmes résultats sur les Explorer et sur les navigateurs conformes.

Charles
(merci à François Battail
pour les échanges sur ce sujet)