web-dev-qa-db-fra.com

Comment empêcher les parents d'éléments flottants de s'effondrer?

Bien que des éléments tels que <div>s s'adaptent normalement à leur contenu, l'utilisation de la propriété float peut poser un problème inquiétant pour les débutants CSS: Si les éléments flottants ont des éléments parents non flottants, le parent s'effondrera.

Par exemple:

<div>
  <div style="float: left;">Div 1</div>
  <div style="float: left;">Div 2</div>
</div>

Dans cet exemple, la division parent pas développée pour contenir ses enfants flottants - elle semblera avoir height: 0.

Comment pouvez-vous résoudre ce problème?

Je voudrais créer ici une liste exhaustive de solutions. Si vous connaissez des problèmes de compatibilité entre navigateurs, veuillez les signaler.

Solution 1

Flotte le parent.

<div style="float: left;">
  <div style="float: left;">Div 1</div>
  <div style="float: left;">Div 2</div>
</div>

Pros: Code sémantique.
Cons: Vous ne voudrez peut-être pas toujours que le parent soit flottant. Même si vous le faites, faites-vous flotter le parent des parents, et ainsi de suite? Devez-vous faire flotter chaque élément d'ancêtre?

Solution 2

Donnez au parent une hauteur explicite.

<div style="height: 300px;">
  <div style="float: left;">Div 1</div>
  <div style="float: left;">Div 2</div>
</div>

Pros: Code sémantique.
Cons: Pas flexible - si le contenu change ou que le navigateur est redimensionné, la présentation sera brisée.

Solution 3

Ajoutez un élément "spacer" à l'intérieur de l'élément parent, comme ceci:

<div>
  <div style="float: left;">Div 1</div>
  <div style="float: left;">Div 2</div>
  <div class="spacer" style="clear: both;"></div>
</div>

Pros: coder directement.
Cons: Non sémantique; la div division n’existe que sous la forme d’un hack de présentation.

Solution 4

Définissez le parent sur overflow: auto.

<div style="overflow: auto;">
  <div style="float: left;">Div 1</div>
  <div style="float: left;">Div 2</div>
</div>

Pros: Ne nécessite pas de div supplémentaire.
Cons: Cela ressemble à un hack - ce n'est pas le but déclaré de la propriété overflow.

Commentaires? Autres suggestions?

956
Nathan Long

Solution 1:

La méthode la plus fiable et la plus discrète semble être la suivante:

Démo: http://jsfiddle.net/SO_AMK/wXaEH/

HTML:

<div class="clearfix">
    <div style="float: left;">Div 1</div>
    <div style="float: left;">Div 2</div>
</div>​

CSS:

.clearfix::after { 
   content: " ";
   display: block; 
   height: 0; 
   clear: both;
}

Avec un peu de ciblage CSS, vous n'avez même pas besoin d'ajouter une classe au parent DIVname__.

Cette solution est rétro-compatible avec IE8. Vous n'avez donc pas à craindre les échecs des anciens navigateurs.

Solution 2:

Une adaptation sur la solution 1 a été suggérée et se présente comme suit:

Démo: http://jsfiddle.net/wXaEH/162/

HTML:

<div class="clearfix">
    <div style="float: left;">Div 1</div>
    <div style="float: left;">Div 2</div>
</div>​

CSS:

.clearfix::after { 
   content: " ";
   display: block; 
   height: 0; 
   clear: both;
   *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML += '<div class="ie7-clear"></div>' );
}

.ie7-clear {
    display: block;
    clear: both;
}

Cette solution semble être rétro-compatible avec IE5.5 mais n’a pas été testée.

Solution 3:

Il est également possible de définir display: inline-block; et width: 100%; pour émuler un élément de bloc normal sans réduire.

Démo: http://jsfiddle.net/SO_AMK/ae5ey/

CSS:

.clearfix {
    display: inline-block;
    width: 100%;
}

Cette solution devrait être rétro-compatible avec IE5.5 mais n’a été testée que dans IE6.

514
A.M.K

J'utilise habituellement l'astuce overflow: auto; Bien que ce ne soit pas, à proprement parler, l’usage prévu du débordement, il est un peu lié, assez pour qu’il soit facile à retenir, certainement. La signification de float: left lui-même a été étendue de manière plus significative pour diverses utilisations que le dépassement de capacité est dans cet exemple, IMO.

71
Bobby Jack

Plutôt que de mettre overflow:auto sur le parent, mettez overflow:hidden

Le premier CSS que j'écris pour une page Web est toujours:

div {
  overflow:hidden;
}

Ensuite, je n'ai jamais à m'en soucier.

19
tybro0103

Le problème se produit lorsqu'un élément flottant se trouve dans une boîte conteneur, cet élément ne force pas automatiquement la hauteur du conteneur à s’ajuster à l’élément flottant. Lorsqu'un élément est flotté, son parent ne le contient plus car il est supprimé du flux. Vous pouvez utiliser 2 méthodes pour résoudre ce problème:

  • { clear: both; }
  • clearfixname__

Une fois que vous avez compris ce qui se passe, utilisez la méthode ci-dessous pour le corriger.

.clearfix:after {
    content: ".";
    display: block;
    clear: both;
    visibility: hidden;
    line-height: 0;
    height: 0;
}

.clearfix {
    display: inline-block;
}

html[xmlns] .clearfix {
    display: block;
}

* html .clearfix {
    height: 1%;
}

démonstration:)

18
Sarfraz

Il existe plusieurs versions du correctif, avec Nicolas Gallagher et Thierry Koblentz en tant qu'auteurs principaux.

Si vous souhaitez que les anciens navigateurs soient pris en charge, utilisez de préférence ce correctif:

.clearfix:before, .clearfix:after {
    content: "";
    display: table;
}

.clearfix:after {
    clear: both;
}

.clearfix {
    *zoom: 1;
}

Dans SCSS, vous devez utiliser la technique suivante:

%clearfix {
  &:before, &:after {
    content:" ";
    display:table;
  }

  &:after {
    clear:both;
  }

  & {
    *zoom:1;
  }
}

#clearfixedelement {
    @extend %clearfix;
}

Si vous ne vous souciez pas du support des navigateurs plus anciens, il existe une version plus courte:

.clearfix:after {
    content:"";
    display:table;
    clear:both;
}
14
John Slegers

Bien que le code ne soit pas parfaitement sémantique, je pense qu'il est plus simple de placer ce que j'appelle une "division de compensation" au bas de chaque conteneur contenant des flotteurs. En fait, j'ai inclus la règle de style suivante dans mon bloc de réinitialisation pour chaque projet:

.clear 
{
   clear: both;
}

Si vous appelez IE6 (Dieu vous aide), vous pouvez également attribuer à cette règle une hauteur de ligne et une hauteur de 0px.

9
Bryan A

Étrange personne n’a encore trouvé de réponse complète à cette question, eh bien la voici.

Solution 1: clair: les deux

Ajouter un élément de bloc avec le style clear: both; sur elle effacera les flotteurs au-delà de ce point et empêchera le parent de cet élément de s’effondrer. http://jsfiddle.net/TVD2X/1/

Avantages: vous permet d'effacer un élément et les éléments que vous ajoutez ci-dessous ne seront pas affectés par les éléments flottants ci-dessus et les CSS valides.

Inconvénients: Requiert l’aide d’une autre balise pour effacer les flotteurs, balises boursouflées.

Remarque: vous ne pouvez pas utiliser: après.

Deuxième solution: display: table

Ajout de display: table; au parent de le faire disparaître des flotteurs et d’afficher la bonne hauteur. http://jsfiddle.net/h9GAZ/1/

Avantages: pas de balisage supplémentaire et est beaucoup plus propre. Fonctionne dans IE6 +

Inconvénients: Nécessite des CSS non valides pour être sûr que tout se déroule bien dans IE6 et 7.

Remarque: IE6 et 7 width auto permettent d'éviter que la largeur ne soit complétée à 100%, ce qui n'est pas le cas dans les nouveaux navigateurs.

Une note sur les autres "solutions"

Ces correctifs fonctionnent de nouveau sur le navigateur le plus bas pris en charge, avec une utilisation globale supérieure à 1% (IE6), ce qui signifie que: after ne le coupe pas.

Le débordement masqué montre le contenu mais n'empêche pas l'élément de se réduire et ne répond donc pas à la question. L'utilisation d'un bloc en ligne peut avoir des résultats erronés, les enfants ayant des marges étranges, etc., la table est bien meilleure.

Le réglage de la hauteur "empêche" l'effondrement, mais ce n'est pas une solution appropriée.

Css invalide

Les css invalides ne font de mal à personne, en fait, c'est maintenant la norme. L'utilisation des préfixes de navigateur est aussi invalide que d'utiliser des hacks spécifiques à un navigateur et n'a aucun impact sur l'utilisateur final.

En conclusion

J'utilise les deux solutions ci-dessus pour que les éléments réagissent correctement et jouent bien l'un avec l'autre. Je vous implore de faire de même.

9
lededje

La solution idéale serait d’utiliser inline-block pour les colonnes au lieu de flottant. Je pense que le support du navigateur est assez bon si vous suivez (a) appliquez inline-block uniquement aux éléments normalement en ligne (par exemple span); et (b) ajoutez -moz-inline-box pour Firefox.

Vérifiez votre page dans FF2 également, car j’ai eu une tonne de problèmes lors de l’imbrication de certains éléments (étonnamment, c’est le seul cas où IE fonctionne beaucoup mieux que FF).

9
DisgruntledGoat

J'utilise 2 et 4 le cas échéant (c'est-à-dire lorsque je connais la hauteur du contenu ou si le débordement ne nuit pas). Partout ailleurs, je vais avec la solution 3. Soit dit en passant, votre première solution n’a aucun avantage sur 3 (que j’aperçois) car elle n’est plus sémantique car elle utilise le même élément factice.

À propos, la quatrième solution ne me préoccupe pas du tout. Les hackings en CSS ne seraient nuisibles que si leur comportement sous-jacent est sujet à une réinterprétation ou à un autre changement. De cette façon, votre bidouille ne serait pas garantie au travail. Cependant, dans ce cas, votre hack repose sur le comportement exact que overflow: auto est censé avoir. Pas de mal à faire de l'auto-stop.

6
Konrad Rudolph

Ma méthode préférée utilise une classe clearfix pour l'élément parent

.clearfix:after {
    content: ".";
    display: block;
    height: 0;
    clear: both;
    visibility: hidden;
}

.clearfix {
    display: inline-block;
}

* html .clearfix {
    height: 1%;
}

.clearfix {
    display: block;
}
5
Christian Gray

L'une des solutions les plus connues est une variante de votre solution numéro 3 qui utilise un pseudo-élément au lieu d'un élément html non sémantique.

Ca fait plutot comme ca...

.cf:after {
    content: " ";
    display: block;
    visibility: hidden;
    height: 0;
    clear: both;
}

Vous placez cela dans votre feuille de style, et tout ce dont vous avez besoin est d’ajouter la classe "cf" à l’élément contenant les flottants.

Ce que j’utilise, c’est une autre variante de Nicolas Gallagher.

Il fait la même chose, mais il est plus court, plus soigné et peut-être utilisé pour accomplir autre chose qui est très utile - empêcher les marges des éléments enfants de s'effondrer avec celles de leurs parents (mais pour cela vous avez besoin de quelque chose d'autre - lisez-en plus à ce sujet. ici http://nicolasgallagher.com/micro-clearfix-hack/ ).

.cf:after {
    content: " ";
    display: table;
    clear: float;
}
4
banzomaikaka

ajoutez ceci dans la division parent en bas

 <div style="clear:both"></div>
3
Leons Kalapurakal

Une autre solution possible qui, à mon avis, est plus correcte sur le plan sémantique est de changer les éléments internes flottants en "display: inline". Cet exemple et ce sur quoi je travaillais lorsque je suis tombé sur cette page utilisent tous les deux des divs flottants de la même manière qu’une étendue serait utilisée. Au lieu d'utiliser divs, changez pour span, ou si vous utilisez un autre élément qui est par défaut 'display: block' au lieu de 'display: inline', changez le en 'display: inline'. Je crois que c'est la solution 100% correcte sur le plan sémantique.

La solution 1, qui fait flotter le parent, consiste essentiellement à modifier le document entier à faire flotter.

La solution 2, définir une hauteur explicite, revient à dessiner une boîte et à dire que je veux placer une image ici, c’est-à-dire l’utiliser si vous faites une balise img.

La solution 3, qui consiste à ajouter un élément d'espacement pour supprimer les éléments flottants, équivaut à ajouter une ligne supplémentaire en dessous de votre contenu et qui dérange également les éléments environnants. Si vous utilisez cette approche, vous voudrez probablement que la div soit à height: 0px.

La solution 4, débordement: auto, consiste à reconnaître que vous ne savez pas comment mettre en page le document et que vous admettez que vous ne savez pas quoi faire.

2
Jonathan

Le problème principal que vous pouvez rencontrer en changeant de débordement en auto ou hidden est que tout peut devenir déroulant avec le curseur de la souris du milieu et qu'un utilisateur peut gâcher la présentation complète du site.

2
cssisashtandw3tooo

Je pense que la meilleure façon de procéder consiste à définir clear:both sur l'élément à venir.

Voici pourquoi:

1) Le sélecteur :after n’est pas pris en charge dans IE6/7 et erroné dans FF3, cependant,
Si vous ne vous souciez que de IE8 + et de FF3,5 +, effacer avec: after est probablement ce qu'il y a de mieux pour vous ...

2) overflow est supposé faire autre chose, donc ce hack n’est pas assez fiable.

Note à l'auteur: il n'y a rien de mal à effacer ... Effacement signifie ignorer les champs flottants. CLEAR est avec nous depuis HTML3 (qui sait, peut-être même plus longtemps) http://www.w3.org/MarkUp/html3/deflists.html , peut-être qu'ils devraient choisir un nom un peu différent comme page: nouveau, mais c'est juste un détail ...

0
jave.web