28172 sujets

CSS et mise en forme, CSS3

Tout d'abord bonjour à tous, et meilleurs voeux pour 2011.

Je suis en train d'apprendre les feuilles de style et un petit problème se pose à moi dans la notion parent-enfant.

Petit exemple :
<div id="container">
      <h1>Conteneur</h1>
      <p>Conteneur principal</p>
        <div class="box">
          <h1>Box 1</h1>
          <p>Je suis une boîte !</p>
        </div>
        <div class="box">
          <h1>Box 2</h1>
          <p>Je suis aussi une boîte !</p>
        </div>
    </div>


Je souhaite que le paragraphe du conteneur soit en rouge et celui des boîtes en vert.

J'essaye d'appliquer cette feuille de style :

/* Définition du container */
#container {
  padding: 20px;
  border: 1px solid #000;
  background: #CCC;
}

/* Définition des boîtes */
.box {
	margin: 10px;
	padding: 20px;
	border: 1px solid #000;
}

/* Mets le paragraphes des boîtes en rouge */
.box p {
	color: #F00;
}

/* Mets uniquement le paragraphes du container en vert */
#container p {
	color: #0F0;
}


Mais quand je teste ce code dans mon navigateur, l'ensemble des textes des paragraphes se retrouvent en vert. Qu'ai-je mal compris ?

Merci d'avance pour vos réponses.
Modifié par Morifen (17 Jan 2011 - 13:14)
Il faut savoir qu'un ID l'emporte sur une classe.

Donc il exécutera toujours #container p après .box p.

Et #container p s'applique à tous les paragraphes contenus dans #container, y compris ceux des .box contenues dans #container.

Ensuite, pour deux classes, il exécutera toujours la dernière dans la feuille de style.

Il faut donc changer ton ID en classe, et inverser les deux valeurs CSS comme suit :

/* Définition du container */ 
#container { 
  padding: 20px; 
  border: 1px solid #000; 
  background: #CCC; 
} 
 
/* Définition des boîtes */ 
.box { 
    margin: 10px; 
    padding: 20px; 
    border: 1px solid #000; 
} 
 
/* Mets uniquement le paragraphes du container en vert */ 
.container p { 
    color: #0F0; 
}

/* Mets le paragraphes des boîtes en rouge */ 
.box p { 
    color: #F00; 
} 


<div class="container"> 
      <h1>Conteneur</h1> 
      <p>Conteneur principal</p> 
        <div class="box"> 
          <h1>Box 1</h1> 
          <p>Je suis une boîte !</p> 
        </div> 
        <div class="box"> 
          <h1>Box 2</h1> 
          <p>Je suis aussi une boîte !</p> 
        </div> 
    </div>
Merci Confridin pour ta réponse rapide.

A bientôt pour la suite de mes questions de béotien.
Merci Confridin pour cette presque limpide réponse, mais une doute persiste chez moi, et j'aime bien maîtriser une problématique dans son ensemble (quand c'est possible Smiley smile )

Quand tu dis :

a écrit :
Donc il exécutera toujours #container p après .box p.


Que veux tu dire exactement ? Le navigateur interprète d'abord toutes les classe puis ensuite les id ? Je ne suis pas sûr ce comprendre le raisonnement qui mène à ce résultat.

Tu pourrais nous en dire plus ?
Salut,
XIV-V a écrit :
Que veux tu dire exactement ? Le navigateur interprète d'abord toutes les classe puis ensuite les id ? Je ne suis pas sûr ce comprendre le raisonnement qui mène à ce résultat.

Tu pourrais nous en dire plus ?

C'est une question de poids du sélecteur : selon le type de sélecteur (sélecteur d'identifiant, sélecteur de classe, pseudo-classe, etc.), ce dernier sera plus ou moins prioritaire dans l'assignation des règles CSS. Le calcul du poids du sélecteur s'effectue comme suit :
1. on vérifie s'il s'agit d'un style en ligne (attribut style) ou pas : si oui, on compte 1, sinon 0 ;
2. on compte le nombre d'attributs id (les #) ;
3. on compte le nombre de sélecteurs d'autres attributs (dont les classes) et de pseudo-classes (comme :hover ou :focus) ;
4. on compte le nombre de noms d'élément et de pseudo-éléments (comme :first-letter, :first-line, :before ou :after).
On concatène les quatre nombres obtenus pour obtenir le poids du sélecteur (selector's specificity dans le jargon du W3C), sachant que le sélecteur universel (*) ne compte pas et que l'on se base sur la forme du sélecteur (ainsi, [id="mon-id"] sera traité comme un sélecteur d'attribut, et non comme si c'était #mon-id).

Avec les sélecteurs mentionnés dans ce sujet, on obtient les spécificités suivantes :
#container {
  /* 0, 1, 0, 0 (1 seul attribut id) */
}
.box {
  /* 0, 0, 1, 0 (1 seule classe) */
}
.box p {
  /* 0, 0, 1, 1 (1 classe et 1 nom d'élément) */
}
.container p {
  /* 0, 0, 1, 1 (1 classe et 1 nom d'élément) */
}
#container p {
  /* 0, 1, 0, 1 (1 attribut id et 1 nom d'élément) */
}

Ainsi, on constate que le sélecteur #container p a plus de poids que le sélecteur .container p ou le sélecteur .box p et que, par conséquent, les déclarations CSS déclarées dans #container p seront prioritaires par rapport à celles déclarées dans .container p ou dans .box p.
#container p {
  color: green; /* Les paragraphes descendant de l'élément d'id #container sont en vert */
}
.box p, .container p {
  color: red;
  /* Si les éléments de classe box ou container ont un ancêtre dont l'id est #container, le rouge ne passera pas et les paragraphes demeureront en vert */
}

Il y a la possibilité de refuser la priorité à un sélecteur qui pèse davantage en employant le mot clé !important à la fin d'une valeur CSS.
#container p {
  color: green; /* Les paragraphes descendant de l'élément d'id #container sont en vert */
}
.box p, .container p {
  color: red !important;
  /* Dans ce cas, même si les éléments de classe box ou container ont un ancêtre dont l'id est #container, le rouge sera bien appliqué aux paragraphes, puisqu'on court-circuite le sélecteur #container p */
}

Pour les amateurs de RTFM, la source de ces explications se trouve dans la spécification CSS 2.1, à la section traitant du calcul de la spécificité d'un sélecteur. Smiley cligne