Pourquoi la hauteur d'un élément conteneur n'augmente-t-elle pas s'il contient des éléments flottants?

210

Je voudrais demander comment fonctionnent la hauteur et le flotteur. J'ai un div extérieur et un div intérieur qui contient du contenu. Sa hauteur peut varier en fonction du contenu du div intérieur mais il semble que mon div intérieur déborde de son div extérieur. Quelle serait la bonne façon de procéder?

 <html>
    <body>
        <div style="margin:0 auto;width: 960px; min-height: 100px; background-color:orange">
    	    <div style="width:500px; height:200px; background-color:black; float:right"></div>
        </div>
    </body>
</html>

Boy Pasmo
la source

Réponses:

581

Les éléments flottants n'ajoutent pas à la hauteur de l'élément conteneur, et donc si vous ne les effacez pas, la hauteur du conteneur n'augmentera pas ...

Je vais vous montrer visuellement:

entrez la description de l'image ici

entrez la description de l'image ici

entrez la description de l'image ici

Plus d'explication:

<div>
  <div style="float: left;"></div>
  <div style="width: 15px;"></div> <!-- This will shift 
                                        besides the top div. Why? Because of the top div 
                                        is floated left, making the 
                                        rest of the space blank -->

  <div style="clear: both;"></div> 
  <!-- Now in order to prevent the next div from floating beside the top ones, 
       we use `clear: both;`. This is like a wall, so now none of the div's 
       will be floated after this point. The container height will now also include the 
       height of these floated divs -->
  <div></div>
</div>

Vous pouvez également ajouter overflow: hidden;des éléments de conteneur, mais je vous suggère de les utiliser à la clear: both;place.

Aussi, si vous souhaitez effacer automatiquement un élément que vous pouvez utiliser

.self_clear:after {
  content: "";
  clear: both;
  display: table;
}

Comment fonctionne CSS Float?

Qu'est-ce que le flotteur exactement et que fait-il?

  • La floatpropriété est mal comprise par la plupart des débutants. Eh bien, que fait float- on exactement ? Initialement, la floatpropriété a été introduite pour faire circuler le texte autour des images, flottantes leftou right. Voici une autre explication de @Madara Uchicha.

    Alors, est-ce mal d'utiliser la floatpropriété pour placer des boîtes côte à côte? La réponse est non ; il n'y a aucun problème si vous utilisez la floatpropriété afin de placer des boîtes côte à côte.

  • Flotter un élément inlineou blocklevel fera que l'élément se comportera comme un inline-blockélément.

    Démo

  • Si vous faites flotter un élément leftou right, l' widthélément de l'élément sera limité au contenu qu'il contient, sauf s'il widthest défini explicitement ...

  • Vous ne pouvez pas floatun élément center. C'est le plus gros problème que j'ai toujours vu avec les débutants, en utilisant float: center;, ce qui n'est pas une valeur valide pour la floatpropriété. floatest généralement utilisé pour float/ déplacer le contenu à l'extrême gauche ou à l'extrême droite . Il n'y a que quatre valeurs valides pour la floatpropriété, c'est left-à- dire right, none(par défaut) et inherit.

  • L'élément parent s'effondre, lorsqu'il contient des éléments enfants flottants, afin d'éviter cela, nous utilisons la clear: both;propriété, pour effacer les éléments flottants des deux côtés, ce qui empêchera l'effondrement de l'élément parent. Pour plus d'informations, vous pouvez consulter ma autre réponse ici .

  • (Important) Pensez-y où nous avons une pile de divers éléments. Lorsque nous utilisons l'élément float: left;ou float: right;se déplace au-dessus de la pile par un. Par conséquent, les éléments du flux de documents normal se cacheront derrière les éléments flottants car il se trouve au niveau de la pile au-dessus des éléments flottants normaux. (S'il vous plaît ne faites pas le lien avec cela z-indexcar c'est complètement différent.)


Prenons un cas comme exemple pour expliquer comment les flotteurs CSS fonctionnent, en supposant que nous avons besoin d'une disposition simple à 2 colonnes avec un en-tête, un pied de page et 2 colonnes, voici donc à quoi ressemble le plan ...

entrez la description de l'image ici

Dans l'exemple ci-dessus, nous ne flotterons que les cases rouges, soit vous pouvez les floatdeux à la left, ou vous pouvez floatà left, et une autre à rightainsi, dépend de la mise en page, si c'est 3 colonnes, vous pouvez float2 colonnes à leftun autre l'un rightdépend de la façon dont, dans cet exemple, nous avons une disposition simplifiée à 2 colonnes, de même que l' floatun leftet l'autre pour le right.

Balisage et styles de création de la mise en page expliqués plus loin ...

<div class="main_wrap">
    <header>Header</header>
    <div class="wrapper clear">
        <div class="floated_left">
            This<br />
            is<br />
            just<br />
            a<br />
            left<br />
            floated<br />
            column<br />
        </div>
        <div class="floated_right">
            This<br />
            is<br />
            just<br />
            a<br />
            right<br />
            floated<br />
            column<br />
        </div>
    </div>
    <footer>Footer</footer>
</div>

* {
    -moz-box-sizing: border-box;       /* Just for demo purpose */
    -webkkit-box-sizing: border-box;   /* Just for demo purpose */
    box-sizing: border-box;            /* Just for demo purpose */
    margin: 0;
    padding: 0;
}

.main_wrap {
    margin: 20px;
    border: 3px solid black;
    width: 520px;
}

header, footer {
    height: 50px;
    border: 3px solid silver;
    text-align: center;
    line-height: 50px;
}

.wrapper {
    border: 3px solid green;
}

.floated_left {
    float: left;
    width: 200px;
    border: 3px solid red;
}

.floated_right {
    float: right;
    width: 300px;
    border: 3px solid red;
}

.clear:after {
    clear: both;
    content: "";
    display: table;
}

Allons étape par étape avec la mise en page et voyons comment fonctionne le flotteur.

Tout d'abord, nous utilisons l'élément wrapper principal, vous pouvez simplement supposer qu'il s'agit de votre fenêtre d'affichage, puis nous utilisons headeret affectons un élément heightde 50pxrien de spécial là-bas. C'est juste un élément de niveau de bloc non flottant normal qui prendra de 100%l'espace horizontal à moins qu'il ne flotte ou que nous ne lui attribuions inline-block.

La première valeur valide pour floatest leftainsi dans notre exemple, nous utilisons float: left;pour .floated_left, nous avons donc l'intention de faire flotter un bloc vers le leftde notre élément conteneur.

La colonne flottait à gauche

Et oui, si vous voyez, l'élément parent, qui est .wrappereffondré, celui que vous voyez avec une bordure verte ne s'est pas développé, mais il devrait bien? J'y reviendrai dans un moment, pour l'instant, nous avons une colonne flottante left.

Venir à la deuxième colonne, laisse celui float-ci à laright

Une autre colonne flottait à droite

Ici, nous avons une 300pxlarge colonne que nous avons floatà la right, qui va s'asseoir à côté de la première colonne pendant qu'elle flotte vers la left, et comme elle flotte vers la left, elle a créé une gouttière vide vers la right, et puisqu'il y avait beaucoup d'espace sur la right, notre rightL'élément flottant était parfaitement assis à côté de leftcelui.

Pourtant, l'élément parent est réduit, eh bien, corrigeons cela maintenant. Il existe de nombreuses façons d'empêcher l'élément parent de s'effondrer.

  • Ajoutez un élément de niveau bloc vide et utilisez-le clear: both;avant la fin de l'élément parent, qui contient des éléments flottants, maintenant celui-ci est une solution bon marché à clearvos éléments flottants qui fera le travail pour vous mais, je recommanderais de ne pas l'utiliser.

Ajoutez, <div style="clear: both;"></div>avant les .wrapper divfins, comme

<div class="wrapper clear">
    <!-- Floated columns -->
    <div style="clear: both;"></div>
</div>

Démo

Eh bien, cela corrige très bien, plus aucun parent réduit, mais cela ajoute un balisage inutile au DOM, donc certains suggèrent, à utiliser overflow: hidden;sur l'élément parent contenant des éléments enfants flottants qui fonctionnent comme prévu.

Utiliser overflow: hidden;sur.wrapper

.wrapper {
    border: 3px solid green;
    overflow: hidden;
}

Démo

Cela nous sauve un élément à chaque fois que nous en avons besoin, clear floatmais comme j'ai testé divers cas avec cela, il a échoué dans un cas particulier, qui utilise box-shadowles éléments enfants.

Démo (ne peut pas voir l'ombre sur les 4 côtés,overflow: hidden;provoque ce problème)

Et maintenant? Enregistrez un élément, overflow: hidden;alors optez pour un hack de correction clair, utilisez l'extrait ci-dessous dans votre CSS, et tout comme vous l'utilisez overflow: hidden;pour l'élément parent, appelez le classci - dessous sur l'élément parent pour qu'il s'auto-efface.

.clear:after {
    clear: both;
    content: "";
    display: table;
}

<div class="wrapper clear">
    <!-- Floated Elements -->
</div>

Démo

Ici, l'ombre fonctionne comme prévu, elle efface également automatiquement l'élément parent, ce qui empêche l'effondrement.

Et enfin, nous utilisons le pied de page après clearles éléments flottants.

Démo


Quand est-il float: none;utilisé de toute façon, comme c'est la valeur par défaut, donc toute utilisation pour déclarer float: none;?

Eh bien, cela dépend, si vous optez pour une conception réactive, vous utiliserez cette valeur beaucoup de fois, lorsque vous souhaitez que vos éléments flottants se rendent les uns en dessous des autres à une certaine résolution. Car cette float: none;propriété y joue un rôle important.


Peu d'exemples concrets de l' floatutilité.

  • Le premier exemple que nous avons déjà vu est de créer une ou plusieurs dispositions de colonne.
  • Utiliser imgflotté à l'intérieur pqui permettra à notre contenu de circuler.

Démo (sans flottementimg)

Démo 2 (imgflottant vers leleft)

  • Utilisation floatpour créer un menu horizontal - Démo

Flottez également le deuxième élément ou utilisez `margin`

Dernier point mais non le moindre, je veux expliquer ce cas particulier où vous n'avez floatqu'un seul élément à la leftmais vous ne faites pas floatl'autre, alors que se passe-t-il?

Supposons que si nous supprimons float: right;de notre .floated_right class, le divsera rendu de l'extrême leftcar il ne flotte pas.

Démo

Donc dans ce cas, vous pouvez soit floatl'au leftet

OU

Vous pouvez utiliser margin-leftce qui sera égal à la taille de la colonne flottante gauche, c'est-à-dire 200pxlarge .

Alien
la source
3
Le fait que les flottants ne contribuent pas à la hauteur d'un parent de niveau bloc est explicitement mentionné ici dans la spécification: w3.org/TR/CSS21/visudet.html#normal-block La raison pour laquelle l'ajout d'un clearfix fonctionne est parce que 1) le clearfix est (généralement) dans le flux normal 2) le nettoyage des flotteurs nécessite que le clearfix soit placé tout en bas des flotteurs 3) le conteneur doit être étiré pour contenir ce clearfix.
BoltClock
@BoltClock, il serait préférable que vous annuliez la modification du titre, car cela affectera sérieusement le référencement pour les utilisateurs qui trouvent comment fonctionne float .. vous pouvez écrire ces termes sur google et vérifier .. sinon cette réponse canonique est inutile si les gens sont pas en mesure de trouver ce qu'ils recherchent.
M. Alien
"Comment fonctionne CSS float?" est un titre extrêmement large, et il induit également les gens en erreur en votant pour fermer n'importe quelle question flottante en tant que dupe de celle-ci. La question ici ne couvre qu'un aspect: les conteneurs qui enveloppent (ou non) les flotteurs.
BoltClock
@BoltClock Quoi qu'il en soit, la technicité reste la même que celle expliquée dans clear: both;, mais c'est bien si vous sentez que le montage le justifie, alors continuez ainsi
M. Alien
1
réponse brillante. "Flottant n'importe quel élément vers la gauche ou la droite, la largeur de l'élément sera limitée au contenu qu'il contient, à moins que la largeur ne soit définie explicitement" - j'ai observé la même chose et je cherchais juste à confirmer. Merci
Deen John
38

Vous devez ajouter overflow:autoà votre div parent pour qu'il englobe le div flottant intérieur:

<div style="margin:0 auto;width: 960px; min-height: 100px; background-color:orange;overflow:auto">
    <div style="width:500px; height:200px; background-color:black; float:right">
    </div>
</div>

Exemple jsFiddle

j08691
la source
6
ce n'est pas une solution, vous cachez le contenu qui sort des limites du div extérieur.
Alejandro Ruiz Arias
@AlejandroRuizArias - Exactement comment quelque chose est-il caché?
j08691
3
Dans cet exemple, rien, mais si vous introduisez suffisamment de contenu dans la div intérieure, oui.
Alejandro Ruiz Arias
Cela ne fait pas ce que le PO recherchait: Forked jsfiddle.net/h0ceb5ra
TecBrat
1
Impressionnant. La seule solution d'attribut que je cherchais, si tout le reste était aussi simple, il n'y aurait pas besoin de rétrécissements.
YK
10

Vous rencontrez le bug flottant (bien que je ne sois pas sûr s'il s'agit d'un bug technique en raison du nombre de navigateurs présentant ce comportement). Voici ce qui se passe:

Dans des circonstances normales, en supposant qu'aucune hauteur explicite n'a été définie, un élément de niveau bloc tel qu'un div définira sa hauteur en fonction de son contenu. Le bas de la div parent s'étendra au-delà du dernier élément. Malheureusement, flotter un élément empêche le parent de prendre en compte l'élément flottant lors de la détermination de sa hauteur. Cela signifie que si votre dernier élément est flottant, il ne "détendra" pas le parent de la même manière qu'un élément normal.

Clairière

Il existe deux façons courantes de résoudre ce problème. La première consiste à ajouter un élément "clearing"; c'est-à-dire un autre élément en dessous de l'élément flottant qui forcera le parent à s'étirer. Ajoutez donc le code HTML suivant comme dernier enfant:

<div style="clear:both"></div>

Il ne doit pas être visible et en utilisant clear: les deux, vous vous assurez qu'il ne se trouvera pas à côté de l'élément flottant, mais après.

Débordement:

La deuxième méthode, qui est préférée par la plupart des gens (je pense) est de changer le CSS de l'élément parent afin que le débordement soit tout sauf "visible". Le fait de régler le débordement sur "caché" forcera le parent à s'étendre au-delà du bas de l'enfant flottant. Cela n'est vrai que si vous n'avez pas défini de hauteur sur le parent, bien sûr.

Comme je l'ai dit, la deuxième méthode est préférée car elle ne vous oblige pas à ajouter des éléments sémantiquement dénués de sens à votre balisage, mais il y a des moments où vous avez besoin que le overflowsoit visible, auquel cas l'ajout d'un élément de suppression est plus qu'acceptable .

Malorique
la source
3

C'est à cause du flotteur du div. Ajoutez overflow: hiddenl'élément extérieur.

<div style="overflow:hidden; margin:0 auto;width: 960px; min-height: 100px; background-color:orange;">
    <div style="width:500px; height:200px; background-color:black; float:right">
    </div>
</div>

Démo

Starx
la source
3

Vous confondez la façon dont les navigateurs rendent les éléments lorsqu'il y a des éléments flottants. Si un élément de bloc est flottant (votre div intérieur dans votre cas), les autres éléments de bloc l'ignoreront car le navigateur supprime les éléments flottants du flux normal de la page Web. Ensuite, parce que le div flotté a été retiré du flux normal, le div extérieur est rempli, comme le div intérieur n'est pas là. Cependant, les éléments en ligne (images, liens, texte, guillemets noirs) respecteront les limites de l'élément flottant. Si vous introduisez du texte dans la division externe, le texte sera placé autour de la division interne.

En d'autres termes, les éléments de bloc (en-têtes, paragraphes, divs, etc.) ignorent les éléments flottants et remplissent, et les éléments en ligne (images, liens, texte, etc.) respectent les limites des éléments flottants.

Un exemple de violon ici

<body>
    <div style="float:right; background-color:blue;width:200px;min-height:400px;margin-right:20px">
           floating element
    </div>
    <h1 style="background-color:red;"> this is a big header</h1>
    <p style="background-color:green"> this is a parragraph with text and a big image. The text places arrounds the floating element. Because of the image is wider than space between paragrah and floating element places down the floating element. Try to make wider the viewport and see what happens :D
        <img src="http://2.bp.blogspot.com/_nKxzQGcCLtQ/TBYPAJ6xM4I/AAAAAAAAAC8/lG6XemOXosU/s1600/css.png">
     </p>
Alejandro Ruiz Arias
la source
3
Ne mettez pas en surbrillance le texte et ne partagez pas les liens de violon, les codes postaux dans votre réponse de la prochaine fois, car si le lien de violon est mort, le futur utilisateur ne recevra aucune aide ici et votre réponse n'aura aucun sens
M. Alien
2

Essaye celui-là

.parent_div{
    display: flex;
}
Yusufbek
la source
1

vous pouvez utiliser la propriété overflow sur le div du conteneur si vous n'avez aucun div à afficher sur le conteneur, par exemple:

<div class="cointainer">
    <div class="one">Content One</div>
    <div class="two">Content Two</div>
</div>

Voici le css suivant:

.container{
    width:100%;/* As per your requirment */
    height:auto;
    float:left;
    overflow:hidden;
}
.one{
    width:200px;/* As per your requirment */
    height:auto;
    float:left;
}

.two{
    width:200px;/* As per your requirment */
    height:auto;
    float:left;
}

-----------------------OU-------------------------- ----

    <div class="cointainer">
        <div class="one">Content One</div>
        <div class="two">Content Two</div>
        <div class="clearfix"></div>
    </div>

Voici le css suivant:

    .container{
        width:100%;/* As per your requirment */
        height:auto;
        float:left;
        overflow:hidden;
    }
    .one{
        width:200px;/* As per your requirment */
        height:auto;
        float:left;
    }

    .two{
        width:200px;/* As per your requirment */
        height:auto;
        float:left;
    }
    .clearfix:before,
    .clearfix:after{
        display: table;
        content: " ";
    }
    .clearfix:after{
        clear: both;
    }
Nishant Rana
la source