28173 sujets

CSS et mise en forme, CSS3

Bonjour. Mon problème avec IE : Avec des div imbriquées (ici 3 en tout), la couleur de fond de la troisième reste celle de la deuxième. n redimensionnant la fenêtre, la bonne couleur apparaît malgré tout "à certains endroits".

<html>
<head>
<style>
#page {	
position:relative; top:0px; width:780px;
background:red; 
}
.principal {
background-color:blue; 
padding: 20px 20px 20px 20px;
}
.article { 
background-color:green; 
padding: 20px 20px 20px 20px;
}
</style>
</head>
<body>
<div id="page">
<p>début</p>
<div class="principal">
<p>premier article, mais pourquoi avec IE le fond reste-t-il bleu(class principal) et n'est-il pas vert (class article) ?<br>Il devient vert quand on change les dimensions de la fenêtre.</p>
<div class="article">
<p>Les sanglots longs des sanglots de l'automne blessent mon coeur d'une langueur monotone. Les sanglots longs des sanglots de l'automne blessent mon coeur d'une langueur monotone. Les sanglots longs des sanglots de l'automne blessent mon coeur d'une langueur monotone. Les sanglots longs des sanglots de l'automne blessent mon coeur d'une langueur monotone. Les sanglots longs des sanglots de l'automne blessent mon coeur d'une langueur monotone.</p>
</div>
</div>
</div>
</body>
</html>


Vous voyez pourquoi ?
Modifié par guenael (24 Aug 2006 - 05:58)
Salut

Sans vérification, ça ressemble au "peek-a-boo bug", mais celui-ci est censé être associé aux flottants :s

Essaie de donner la propriété "position: relative;" au div #principal, pour voir.
Oui, merci Sopo, avec position:relative sur le div .principal, ça marche, mais un autre problème apparaît ensuite, lié au float d'un encart que j'insère dans mon article.

Je rajoute un encart
.encart { 
float:right;
width:100px;
background-color:yellow; 
}

dans mon article
<div class="principal">
<p>Premier article</p>
<div class="article">
<div class="encart"><p>. Petit encart dans mon long texte. Petit encart dans mon long texte.</p></div>
<p>Les sanglots longs des sanglots de l'automne blessent mon coeur d'une langueur monotone. Les sanglots longs des sanglots de l'automne blessent mon coeur d'une langueur monotone. Les sanglots longs des sanglots de l'automne blessent mon coeur d'une langueur monotone. </p>
</div>
</div>

Avec .principal { position:relative; }, le fond de l'article s'affiche bien, mais pas l'encart float que j'y ai mis :
upload/8187-exemple1.GIF

Et si j'enlève .principal { position:relative; }, alors j'ai l'encart, mais plus la bonne couleur de fond d'article :
upload/8187-exemple2.GIF

Evidemment, si j'imbrique une nouvelle div à chaque fois qu'on me donne une solution, ça va vous lasser...
Modifié par guenael (24 Aug 2006 - 06:17)
Bonjour guenael, et bienvenue sur ces forums. Smiley smile

Il s'agit d'un bug de Haslayout.
Cf. http://www.test.blog-and-blues.org/haslayout/
Et l'explication générale : http://www.test.blog-and-blues.org/haslayout/trad_temp.html

Bon, c'est un peu abrupt. Alors on va essayer d'expliquer brièvement.
Le HasLayout, c'est une propriété interne au moteur de rendu d'Internet Explorer windows. Chaque élément de type bloc (paragraphes, titres, divisions, etc.) soit a le layout, soit ne l'a pas (c'est du zéro ou un, quoi).
Le fait d'avoir le layout ou pas peut hélas modifier fortement le comportement ou le rendu du bloc. C'est (en partie) la source d'un certain nombre des bugs de rendu d'Internet Explorer. À l'opposé, on peut parfois donner le layout a un élément pour corriger un bug, ça marche un peu dans les deux sens...

Il y a plusieurs propriétés CSS qui confèrent le layout à un élément. En particulier, tous les éléments de type bloc qui ont une dimmension fixée (width ou height, en pixels ou en pourcentages) ont le layout.

Si on reprend l'exemple que tu donnes, en corrigeant un peu le code HTML pour avoir quelque chose de valide (regarde les différences pour voir ce que tu as oublié) :
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
	<title>Test</title>
	<style type="text/css">
	#page {
	position:relative; top:4px;
	background:red;	
	}
	.principal {
	background-color:blue;
	padding: 20px;	
	}
	.article {
	background-color:green;
	padding: 20px;
	}
	</style>
</head>
<body>
<div id="page">
	<p>début</p>
	<div class="principal">
		<p>premier article, mais pourquoi avec IE le fond reste-t-il bleu(class principal) et n'est-il pas vert (class article) ?<br />Il devient vert quand on change les dimensions de la fenêtre.</p>
		<div class="article">
			<p>Les sanglots longs des sanglots de l'automne blessent mon coeur d'une langueur monotone. Les sanglots longs des sanglots de l'automne blessent mon coeur d'une langueur monotone. Les sanglots longs des sanglots de l'automne blessent mon coeur d'une langueur monotone. Les sanglots longs des sanglots de l'automne blessent mon coeur d'une langueur monotone. Les sanglots longs des sanglots de l'automne blessent mon coeur d'une langueur monotone.</p>
		</div>
	</div>
</div>
</body>
</html>

Note : les deux éléments oubliés qui étaient indispensables sont la déclaration de type de document (Doctype), et l'attribut type="text/css" pour la balise <style>.

Ces petites corrections ne corrigent pas notre problème pour autant (même si elles nous évitent d'en avoir d'autres par la suite).

Tu as trois divisions (div) qui contiennent chacune un paragraphe, soit en tout six éléments de type bloc. Le seul qui soit doté de layout est la première division, qui porte l'identifiant "page".
#page {
	position: relative;
	width: 780px;
}

C'est la largeur fixe qui confère le layout à cet élément.

Le HasLayout tout seul ne poserait pas (dans la situation présente) de problème. Le bug se produit à cause du positionnement relatif. En effet, HasLayout et positionnement relatif ne font pas toujours bon ménage.

La page que je donne en premier lien recense un certain nombre de bugs de HasLayout, dont quelques uns avec le positionnement relatif, mais je n'ai pas trouvé trace de celui-ci (pourtant assez simple...). Qu'à cela ne tienne, on peut toujours essayer de combattre le feu par le feu ! Si on applique un width: 100%; div.principal ou à div.article, le bug semble être corrigé.

On a donc plusieurs solutions :
- se passer du positionnement relatif dans ce cas précis, s'il n'est pas nécessaire ;
- ne pas donner de dimmension fixe au bloc parent (div#page), si possible ;
- conférer le layout au bloc enfant (div.principal), voire au petit-enfant (div.article).

L'article traduit par Laurent Denis (deuxième lien) précise d'autre propriétés qui confèrent le layout, si un width: 100%; pose problème.

Voilà, j'espère que ça t'aidera.


Une remarque en passant : avec une largeur de 780px, tu as deux chances sur trois que cela crée une barre de défilement horizontale chez l'utilisateur d'un écran en 800x600. La largeur canonique serait plutôt 760px, plus ou moins 10px (dont à moins de faire plus étroit, on choisira dans la plage 750-770px).
Ne pas oublier qu'en plus de la barre de défilement (dont la largeur peut varier selon les réglages de l'utilisateur), on peut avoir des bordures de fenêtre, voire une fenêtre qui ne prend pas toute la largeur de l'écran.
J'ai peut-être parfois dans mes pages utilisé trop de div, créé des imbrications artificielles ou inutiles, utilisé ma logique de structuration de pages quand il en existe de plus simples. Mais quelle que soit l'organisation que j'aie choisie, si elle est correcte et fonctionne par exemple avec FireFox, je ne souhaite la modifier pour m'adapter à Internet Explorer.
Les réponses que j'ai vues dans les forums : repérer la div en cause (celle où ça se passe mal, ou une de niveau supérieur), préciser la largeur, mettre ou enlever une position relative, indiquer une hauteur fictive... ne sont pas satisfaisantes. Et ces opérations imposent de nouvelles contraintes à gérer pour un affichage correct dans les autres navigateurs.

J'ai pris quelques heures pour étudier le problème à partir des indications de Gourou dickien, et il apparaît assez clairement qu'il existe une solution efficace et qui corrige le bug d'IE par une extension Microsoft. Ca tue le mal par le mal, et c'est transparent pour les autres navigateurs.
Le problème se pose pour les div sans "layout" incluses dans les div avec "layout". Et "zoom:1" est une fausse propriété css de Microsoft (une extension propriétaire) qui, en plus de faire son travail, donne un "layout" à la div. Alors sans même chercher à savoir ce qu'est un "layout", ni ce qu'est un "zoom", mettons-en partout. Il n'y aura plus ainsi de div sans "layout" incluses dans des div avec "layout", et le monde sera plus heureux.
Bref, il suffit de rajouter dans le css, systématiquement :
div { zoom:1; }

Grâce au super "zoom" de Microsoft, plus de problèmes de disparition d'arrière-plan ou de bordure, et les div flottantes sont bien visibles, sans frotter.
Mais bon, si ça semble un peu violent, et dans l'attente d'avoir testé les éventuels effets indésirables (qui ne se produiront que pour IE), on peut déjà appliquer cette propriété à la div concernée par le problème...
Merci pour votre réactivité.
Modifié par guenael (24 Aug 2006 - 06:15)
Bonjour,

guenael a écrit :

Bref, il suffit de rajouter dans le css, systématiquement :
div { zoom:1; }


A l'usage, et avec un certain recul lié à l'expérience, je dirais clairement: c'est une très mauvaise idée, comme le sont le plus souvent les tentatives de "panacées universelles" Smiley cligne

Les difficultés liées au haslayout peuvent tenir en effet aussi bien à la présence de layout qu'à son absence. D'autre part, elles sont loin de concerner uniquement des éléments div: doter tous les éléments conteneurs éventuels de haslayout par défaut serait encore pire en générant encore plus d'effets indésirables. En outre, les besoins de doter tel ou tel élément de haslayout varient sur le même code XHTML CSS en fonction de la version d'IE. Enfin, la propriété zoom ne permet pas de corrections pour IE5.0, qui doit encore être pris en compte dans de très nombreux projets.

Bref, il faut prendre le temps (qui n'a rien d'excessif) d'apporter au cas par cas les correctifs nécessaires, en ajustant les propriétés utilisées selon les besoins (IE5.0, 5.5, 6.0, 7.0) et selon les possibilités (une propriété "naturelle" qui pourra être lue par tous les navigateurs peut souvent éviter de recourir à un height:1% ou à un zoom et à une feuille de style supplémentaire en commentaires conditionnels)
Modifié par Laurent Denis (24 Aug 2006 - 08:23)