85 votes

Comment fonctionne le contexte de mise en forme des blocs CSS ?

Comment le Contexte du formatage des blocs CSS travail ?

Les spécifications CSS2.1 stipulent que dans un contexte de formatage par blocs, les boîtes sont disposées verticalement, en commençant par le haut. Cela se produit même si des éléments flottants se trouvent sur le chemin, sauf si le bloc encadré a établi un nouveau contexte de formatage de bloc. Comme nous le savons, lorsque les navigateurs rendent des blocs dans un contexte de mise en forme de bloc, l'élément flottant est omis. Pourquoi l'établissement d'un nouveau contexte de mise en forme de bloc fonctionne-t-il ?

Comment les boîtes (boîtes de blocs et boîtes en ligne) sont-elles disposées dans le flux normal ?

J'ai lu quelque part que les éléments de bloc génèrent des boîtes de bloc, mais que les éléments flottants sont ignorés lorsqu'un agent utilisateur dessine des boîtes et les prend en compte lorsqu'il remplit le contenu. Alors que les éléments flottants chevaucheront les limites des boîtes d'autres éléments, la solution consiste à établir un nouveau contexte de formatage de bloc pour les éléments chevauchés à l'aide de la fonction overflow:hidden .

"Le nouveau contexte de formatage de bloc est toujours un formatage de bloc", donc lorsque vous dessinez une boîte, il traitera également l'élément flottant comme s'il ne sortait pas. Est-ce exact ou ai-je mal compris "nouveau contexte de formatage de bloc" ?

Mise à jour : plus de questions

En disant "C'est ce comportement qui est utile pour les mises en page de type colonne. Cependant, sa principale utilité est d'empêcher les éléments flottants, par exemple dans une division "contenu principal", d'effacer les colonnes latérales flottantes, c'est-à-dire les éléments flottants qui apparaissent plus tôt dans le code source."

Je ne comprends pas le sens, je vais donner un exemple, peut-être me comprendrez-vous.

.content {
  background: #eee;
  color #000;
  border: 3px solid #444;
  width: 500px;
  height: 200px;
}
.float {
  background: rgba(0, 0, 255, 0.5);
  border: 1px solid #00f;
  width: 150px;
  height: 150px;
  float: right;
}
p {
  background: #444;
  color: #fff;
}

<div class="content">
  <h3>This is a content box</h3>
  <p>It contains a left floated box, you can see the actual content div does go under the float, but that it is the &lt;h3&gt; and &lt;p&gt; <b>line boxes</b> that are shortened to make room for the float. This is normal behaviour.</p>
  <div class="float">floated box</div>
</div>

Je pensais que la boîte flottante devait flotter au sommet du bloc de containg - le div avec la classe content . En outre, si la boîte flottante apparaît plus tôt dans le balisage, elle affichera ce que je pense qu'elle devrait être.

.content {
  background: #eee;
  color #000;
  border: 3px solid #444;
  width: 500px;
  height: 200px;
}
.float {
  background: rgba(0, 0, 255, 0.5);
  border: 1px solid #00f;
  width: 150px;
  height: 150px;
  float: right;
}
p {
  background: #444;
  color: #fff;
}

<div class="content">
  <div class="float">floated box</div>
  <h3>This is a content box</h3>
  <p>it contains a left floated box, you can see the actual content div does go under the float, but that it is the &lt;h3&gt; and &lt;p&gt; <b>line boxes</b> that are shortened to make room for the float, this is normal behaviour</p>
</div>

Comment pouvons-nous expliquer cela ? Pouvons-nous utiliser "le contexte de formatage en bloc et le contexte de formatage en ligne" pour l'expliquer ?

131voto

clairesuzy Points 14882

Contextes de mise en forme des blocs

Flottants, positionnés de manière absolue les conteneurs de blocs (tels que inline-blocks, cellules de tableau et table-captions) qui ne sont pas des blocs blocs, et les blocs avec un "débordement" autre que autre que "visible" (sauf lorsque ce paramètre a été propagée à la fenêtre d'affichage fenêtre d'affichage) établir de nouveaux contextes de formatage des blocs pour leur contenu.

Avec mon gras, c'est le établir ce qui est important

Ce que cela signifie, c'est que l'élément que vous utilisez overflow (tout ce qui n'est pas visible) ou float ou inline-block etc. devient responsable de la mise en page de ses éléments enfants. Ce sont les éléments enfants qui sont alors "contenus", qu'il s'agisse de flotteurs ou de marges rétractables, ils doivent être entièrement contenus par leur parent limitrophe.

Dans un contexte de formatage de blocs, chaque de chaque boîte touche le bord gauche du bloc du bloc qui le contient (pour les formatage de droite à gauche, les bords droits se touchent)

Ce que signifie la ligne ci-dessus :

Étant donné qu'une boîte ne peut être que rectangulaire et non de forme irrégulière, cela signifie qu'un nouveau contexte de mise en forme de bloc entre deux flotteurs (ou même à côté d'un flotteur) ne s'enroulera pas autour des flotteurs latéraux voisins. Les boîtes internes, enfants, ne peuvent s'étendre que jusqu'à toucher le bord gauche (ou droit en RTL) de leurs parents. C'est ce comportement qui est utile pour les mises en page de type colonne. Cependant, sa principale utilité est d'empêcher les éléments flottants, par exemple dans une div de "contenu principal", d'effacer les colonnes latérales flottantes, c'est-à-dire les éléments flottants qui apparaissent plus tôt dans le code source.


Dégagement du flotteur

Dans des circonstances normales, les flottants sont censés effacer tous les éléments flottants précédents, c'est-à-dire les éléments flottants précédents dans l'ensemble du code source, et pas seulement dans la "colonne" affichée. La citation éloquente des "spécifications d'effacement des flottants" est la suivante :

Cette propriété indique les côtés de la ou des boîte(s) d'un élément ne peuvent pas être adjacents à une boîte flottante antérieure. La propriété "clear" ne tient pas compte les flotteurs à l'intérieur de l'élément lui-même ou dans d'autres contextes de formatage de blocs

Supposons que vous ayez une mise en page à trois colonnes où les colonnes de gauche et de droite sont respectivement flottées à gauche et à droite, les colonnes latérales se trouvent maintenant dans de nouveaux Contextes de mise en forme de bloc, car elles sont flottées (rappelez-vous que la flottaison est également l'une des propriétés qui établissent un nouveau BFC), vous pouvez donc y faire flotter des éléments de liste et ils n'effacent que les flottaisons qui se trouvent déjà dans les colonnes latérales ; ils ne se soucient plus des flottaisons qui se trouvaient auparavant dans le code source.


Faire du contenu principal un nouveau bloc Contexte de mise en forme ou non ?

Maintenant, la colonne centrale, vous pouvez simplement la marginaliser des deux côtés de façon à ce qu'elle semble se situer parfaitement entre les deux colonnes flottantes latérales et prendre la largeur restante, une façon courante d'obtenir la largeur désirée si la colonne centrale est "fluide" - ce qui sera parfait jusqu'à ce que vous ayez besoin d'utiliser des flotteurs/de la clarté à l'intérieur de votre div de contenu (une situation courante pour ceux qui utilisent des bidouilles "clearfix" ou des modèles qui les incluent).

Prenez ce code très simple :

#left-col {
  border: 1px solid #000;
  width: 180px;
  float: left;
}
#right-col {
  border: 1px solid #000;
  width: 180px;
  float: right;
  height: 200px;
}
#content {
  background: #eee;
  margin: 0 200px;
}
.floated {
  float: right;
  width: 180px;
  height: 100px;
  background: #dad;
}

<div id="left-col">left column</div>
<div id="right-col">right column</div>

<div id="content">
  <h3>Main Content</h3>
  <p>Lorem ipsum etc..</p>
  <div class="floated">this a floated box</div>
  <div class="floated">this a floated box</div>
</div>

Il produit ce qui suit :

enter image description here

En général, tout va bien, surtout si vous n'avez pas de couleurs d'arrière-plan ou de flotteurs internes (dans le contenu principal). Remarquez que les flotteurs sont en bon état (pas encore effacés) et qu'ils font probablement ce que vous attendez d'eux. mais ils, les H3 et la marge supérieure de la p ne sont pas réellement contenues dans la division de contenu (fond gris clair).

Donc au même scénario simple et marginalisé du code ci-dessus, ajoutez :

.clear-r {clear: right;}

à la CSS, et changez la deuxième boîte flottante HTML en :

<div class="floated clear-r"> this a floated cleared box</div>

#left-col {
  border: 1px solid #000;
  width: 180px;
  float: left;
}
#right-col {
  border: 1px solid #000;
  width: 180px;
  float: right;
  height: 200px;
}
#content {
  background: #eee;
  margin: 0 200px;
}
.floated {
  float: right;
  width: 180px;
  height: 100px;
  background: #dad;
}
.clear-r {
  clear: right;
}

<div id="left-col">left column</div>
<div id="right-col">right column</div>

<div id="content">
  <h3>Main Content</h3>
  <p>Lorem ipsum etc..</p>
  <div class="floated">this a floated box</div>
  <div class="floated clear-r">this a floated cleared box</div>
</div>

Cette fois, vous obtenez ceci :

enter image description here

La deuxième marge dégage le côté droit, mais elle dégage toute la hauteur de la colonne de droite. La colonne de droite est flottante plus tôt dans le code source, donc elle est effacée comme prévu ! Ce n'est probablement pas l'effet désiré, notez également que la balise h3 et p les marges sont toujours effondrées (non contenues).


Faites en sorte qu'il établisse un contexte de formatage de bloc, pour le bien des enfants !

et enfin faire en sorte que la colonne de contenu principal prenne la responsabilité - devenir un contexte de formatage de blocs - pour son contenu : enlever margin: 0 200px; du contenu principal CSS et ADD overflow: hidden; et vous obtenez ceci :

#left-col {
  border: 1px solid #000;
  width: 180px;
  float: left;
}
#right-col {
  border: 1px solid #000;
  width: 180px;
  float: right;
  height: 200px;
}
#content {
  background: #eee;
  overflow: hidden;
}
.floated {
  float: right;
  width: 180px;
  height: 100px;
  background: #dad;
}
.clear-r {
  clear: right;
}

<div id="left-col">left column</div>
<div id="right-col">right column</div>

<div id="content">
  <h3>Main Content</h3>
  <p>Lorem ipsum etc..</p>
  <div class="floated">this a floated box</div>
  <div class="floated clear-r">this a floated cleared box</div>
</div>

enter image description here

C'est probablement plus conforme à ce que vous attendez, notez que maintenant les flotteurs sont contenus, qu'ils s'effacent correctement en ignorant la colonne de droite, et aussi que l'élément h3 et p les marges sont contenues au lieu d'être réduites.

Avec l'utilisation intensive des réinitialisations de nos jours, les marges sont moins perceptibles (et IE ne les obtient toujours pas tout à fait correctement), mais ce qui vient d'arriver au centre "contenu principal" est qu'il est devenu un contexte de formatage de bloc et est maintenant responsable de ses propres éléments enfants (descendants). C'est en fait très similaire à la notion de hasLayout des premiers jours de Microsoft, qui utilise les mêmes propriétés. display: inline-block , float et overflow tout ce qui n'est pas visible, et bien sûr les cellules de tableau ont toujours une mise en page c'est cependant sans les bugs ;)

J'espère que cela vous aidera un peu, si vous avez des questions, n'hésitez pas à les poser !


Mise à jour : plus d'informations dans la question :

Lorsque vous dites "mais les éléments flottants sont ignorés lorsque l'agent utilisateur dessine la boîte et les prend en compte lorsqu'il remplit le contenu".

Oui, les flotteurs recouvrent normalement leurs conteneurs, c'est ce que vous voulez dire à propos des limites du parent ? Lorsqu'un élément de bloc est dessiné et qu'il contient un flotteur, le parent du bloc lui-même est dessiné comme un rectangle sous le flotteur et ce sont les "boîtes anonymes en ligne" ou simplement les "boîtes de ligne" des autres éléments enfants qui sont raccourcies pour faire de la place au flotteur.

Prenez ce code :

#content {
  background: #eee;
  color #000;
  border: 3px solid #444;
}
.float {
  background: rgba(0, 0, 255, 0.5);
  border: 1px solid #00f;
  width: 150px;
  height: 150px;
  float: left;
  margin: 10px;
}
p {
  background: #444;
  color: #fff;
}

<div id="content">
  <div class="float">floated box</div>
  <h3>This is a content box</h3>
  <p>it contains a left floated box, you can see the actual content div does go under the float, but that it is the &lt;h3&gt; and &lt;p&gt; <b>line boxes</b> that are shortened to make room for the float, this is normal behaviour</p>
</div>

Ce qui donne ceci :

how floats work

Vous voyez que l'élément parent ne contient pas réellement le flotteur, c'est-à-dire qu'il ne l'enveloppe pas entièrement le flotteur est simplement flottant au-dessus du contenu - si vous continuez à ajouter du contenu à la div, il finira par s'enrouler sous le flotteur, car il n'y aura plus besoin des "cases de ligne" (anonymes) de la balise p élément pour se raccourcir davantage.

J'ai coloré l'élément de paragraphe pour que vous puissiez voir qu'il est aussi placé sous la marge, le fond gris foncé est le point de départ du paragraphe, le texte blanc est le point de départ de la "ligne anonyme" - ce ne sont qu'eux qui "font de la place" pour la marge, à moins que vous ne lui disiez le contraire (c'est-à-dire que vous changiez le contexte).

Toujours en se référant à l'image ci-dessus, si vous deviez marginaliser le côté gauche de la p oui, cela empêchera le texte de s'enrouler sous le fond du flotteur parce que les "boîtes de ligne" (le texte blanc) ne toucheront que le bord gauche de leur conteneur, et vous ferez apparaître le fond coloré de l'élément p vers la droite, à l'écart du flotteur, mais vous n'aurez pas modifié le comportement du p Le contexte de la mise en forme. Comme la colonne centrale dans la première image ci-dessus ;)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X