html - float - Comment empêchez-vous les parents d'éléments flottants de s'effondrer?




float css (11)

Cette question a déjà une réponse ici:

Bien que des éléments comme <div> se développent normalement pour s'adapter à leur contenu, l'utilisation de la propriété float peut provoquer un problème surprenant 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>

Le div parent dans cet exemple ne se développera pas pour contenir ses enfants flottants - il semblera avoir height: 0 .

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

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

Solution 1

Flotter le parent.

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

Avantages : code sémantique.
Inconvénients : Vous ne pouvez pas toujours vouloir que le parent flotte. Même si vous le faites, faites-vous flotter le parent des parents, et ainsi de suite? Doit-on faire flotter chaque élément 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>

Avantages : code sémantique.
Inconvénients : Non flexible - si le contenu change ou que le navigateur est redimensionné, la mise en page sera interrompue.

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>

Avantages : Facile à coder.
Contre : Pas sémantique; la div d'entretoise n'existe que comme un hack de mise en page.

Solution 4

Définir le parent à overflow: auto .

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

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

Commentaires? D'autres suggestions?


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 à la DIV parent.

Cette solution est rétrocompatible avec IE8, vous n'avez donc pas à vous soucier de l'échec des anciens navigateurs.

Solution 2:

Une adaptation sur la solution 1 a été suggérée et est la suivante:

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étrocompatible avec IE5.5 mais n'a pas été testée.

Solution 3:

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

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

CSS:

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

Cette solution devrait être rétrocompatible avec IE5.5 mais n'a été testée que dans IE6.


Étrange personne n'a encore trouvé une réponse complète à cette question, ah bien voilà.

Solution un: effacer: les deux

Ajouter un élément de bloc avec le style clear: both; Cela 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/

Pour: 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 css valide.

Inconvénients: Nécessite une autre balise pour effacer les flottants, balisage balisage.

Note: Pour revenir à IE6 et pour travailler sur des parents abstinents (c'est-à-dire l'élément input) vous n'êtes pas capable d'utiliser: after.

Solution deux: afficher: table

Ajouter un affichage: table; au parent pour lui faire oublier les flotteurs et afficher avec la bonne taille. http://jsfiddle.net/h9GAZ/1/

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

Inconvénients: Nécessite un css invalide pour s'assurer que tout se joue bien dans IE6 et 7.

Remarque: La largeur IE6 et la largeur 7 sont utilisées pour empêcher la largeur d'être 100% + padding, ce qui n'est pas le cas dans les nouveaux navigateurs.

Une note sur les autres "solutions"

Ces correctifs fonctionnent sur le navigateur supporté le plus bas, avec plus de 1% d'utilisation globale (IE6), ce qui signifie utiliser: after ne le coupe pas.

Le débordement masqué affiche le contenu mais n'empêche pas l'élément de s'effondrer et ne répond donc pas à la question. Utiliser un bloc en ligne peut avoir des résultats buggés, les enfants ayant des marges étranges et ainsi de suite, la table est beaucoup mieux.

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

Css invalide

Css invalide ne fait jamais de mal à personne, en fait, c'est maintenant la norme. L'utilisation de préfixes de navigateur est tout aussi invalide que l'utilisation de hacks spécifiques au 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 les uns avec les autres, je vous implore de faire de même.


Il existe plusieurs versions du clearfix, avec Nicolas Gallagher et Thierry Koblentz comme auteurs clés.

Si vous souhaitez prendre en charge les anciens navigateurs, il est préférable d'utiliser 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 de la prise en charge des navigateurs plus anciens, il existe une version plus courte:

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

J'utilise 2 et 4 le cas échéant (ie quand je connais la hauteur du contenu ou si le débordement ne nuit pas). Partout ailleurs, je vais avec la solution 3. A ce propos, votre première solution n'a pas d'avantage sur 3 (que je peux repérer) car elle n'est plus sémantique puisqu'elle utilise le même élément fictif.

Au fait, je ne serais pas préoccupé par le fait que la quatrième solution soit un hack. Hacks en CSS ne serait nuisible que si leur comportement sous-jacent est soumis à une réinterprétation ou d'autres changements. De cette façon, votre hack ne serait pas garanti au travail. Cependant, dans ce cas, votre piratage repose sur le comportement exact que le overflow: auto est censé avoir. Aucun mal à atteler un tour gratuit.


Je crois que le meilleur moyen est de définir clear:both à l'élément à venir.

Voici pourquoi:

1) :after sélecteur n'est pas pris en charge dans IE6 / 7 et buggy dans FF3, cependant,
si vous vous souciez seulement de la compensation IE8 + et FF3.5 + avec: after est probablement le meilleur pour vous ...

2) le overflow est supposé faire quelque chose d'autre donc ce hack n'est pas assez fiable.

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


L'une des solutions les plus connues est une variante de votre numéro de solution 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 est une autre variation qui vient 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 ses parents (mais pour cela vous avez besoin d'autre chose - en savoir plus ici http://nicolasgallagher.com/micro-clearfix-hack/ ).

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

Le problème principal que vous pouvez rencontrer en changeant le débordement en auto ou hidden est que tout peut devenir défilement avec le bouton central de la souris et qu'un utilisateur peut gâcher toute la mise en page du site.


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

  • { clear: both; }
  • clearfix

Une fois que vous comprenez ce qui se passe, utilisez la méthode ci-dessous pour la "supprimer".

.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%;
}

Manifestation :)


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

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

div {
  overflow:hidden;
}

Ensuite, je ne dois jamais m'inquiéter à ce sujet.


Une autre solution possible, qui est plus sémantiquement correcte à mon avis, consiste à remplacer les éléments internes flottants par 'display: inline'. Cet exemple et ce sur quoi je travaillais quand je suis tombé sur cette page utilisent tous les deux des divs flottants exactement de la même manière qu'un span serait utilisé. Au lieu d'utiliser divs, passez à 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% sémantiquement correcte.

La solution 1, qui consiste à faire flotter le parent, consiste essentiellement à modifier l'ensemble du document à faire flotter.

La solution 2, en définissant une hauteur explicite, est comme dessiner une boîte et dire que je veux mettre une image ici, c'est-à-dire l'utiliser si vous faites une balise img.

La solution 3, ajouter une entretoise pour effacer le flottant, est comme ajouter une ligne supplémentaire au-dessous de votre contenu et gâcher avec les éléments environnants aussi. Si vous utilisez cette approche, vous voulez probablement définir la div à hauteur: 0px.

Solution 4, débordement: auto, reconnaît que vous ne savez pas comment mettre en page le document et vous admettez que vous ne savez pas quoi faire.






css-float