Centrer les div flottantes dans une autre div

142

J'ai cherché d'autres questions et, bien que ce problème semble similaire à quelques autres, rien de ce que j'ai vu jusqu'à présent ne semble résoudre le problème que je rencontre.

J'ai un div qui contient un certain nombre d'autres div, dont chacun est flottant à gauche. Ces divs contiennent chacun une photo et une légende. Tout ce que je veux, c'est que le groupe de photos soit centré dans le div contenant.

Comme vous pouvez le voir dans le code ci-dessous, j'ai essayé d'utiliser à la fois overflow:hiddenet margin:x autosur les div parent, et j'ai également ajouté un clear:both(comme suggéré dans un autre sujet) après les photos. Rien ne semble faire de différence.

Je vous remercie. J'apprécie toutes les suggestions.

<div style="position: relative; margin: 0 auto; overflow: hidden; text-align: center;">
    <h4>Section Header</h4>

    <div style="margin: 2em auto;">

        <div style="float: left; margin: auto 1.5em;">
            <img src="photo1.jpg" /><br />
             Photo Caption
        </div>
        <div style="float: left; margin: auto 1.5em;">
            <img src="photo2.jpg" /><br />
             Photo Caption
        </div>
        <div style="float: left; margin: auto 1.5em;">
            <img src="photo3.jpg" /><br />
             Photo Caption
        </div>

        <div style="clear: both; height: 0; overflow: hidden;"> </div>

    </div>

</div>
Darren
la source
duplication possible de Comment centrer les éléments flottants?
TylerH
@TylerH Comment ça? Il suffit de voir la date à laquelle cela a été demandé. On dirait que la question dans votre lien est le vrai doublon.
The Pragmatick
@ThePragmatick Parce que celui-là a deux fois plus de vues, plus de réponses, plus d'activité (et plus récente), et sa formulation est une meilleure question canonique que celle-ci.
TylerH

Réponses:

266

Tout d'abord, supprimez l' floatattribut sur le divs interne . Ensuite, mettez text-align: centerl'extérieur principal div. Et pour les intérieurs div, utilisez display: inline-block. Il serait peut-être aussi judicieux de leur donner des largeurs explicites.


<div style="margin: auto 1.5em; display: inline-block;">
  <img title="Nadia Bjorlin" alt="Nadia Bjorlin" src="headshot.nadia.png"/>
  <br/>
  Nadia Bjorlin
</div>
Sampson
la source
6
@Darren: as-tu arrêté de flotter quand tu as essayé? Vous ne pourrez pas accomplir ce que vous voulez tant que vous flotterez / à moins que / vous ne définissiez une largeur fixe sur le conteneur des flotteurs.
Ken Browning
1
Oh ... j'ai tort. Le retrait du flotteur a l'air d'accomplir exactement ce que je veux. Je ne suis pas sûr de comprendre pourquoi, mais ... Merci beaucoup.
Darren
9
@Darren, remarquez dans mon exemple de code que je n'ai pas inclus le flottant;) Lisez plus attentivement la prochaine fois, cela vous évitera une certaine frustration :) Heureux que vous ayez compris. Continuez votre bon travail et bienvenue à SO.
Sampson
2
Cette approche commence à échouer lorsque certaines des légendes d'image sont suffisamment longues pour un retour à la ligne. D'autres suggestions?
greg.kindel
3
Nevermind, a constaté que le problème des légendes à nombre de lignes variable peut être résolu avec 'vertical-align: top'. =)
greg.kindel
33

Avec Flexbox, vous pouvez facilement centrer horizontalement (et verticalement) les enfants flottants à l' intérieur d'un div.

Donc, si vous avez un balisage simple comme celui-ci:

<div class="wpr">
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
</div>

avec CSS:

.wpr
{
    width: 400px;
    height: 100px;
    background: pink;
    padding: 10px 30px;
}

.wpr span
{
    width: 50px;
    height: 50px;
    background: green;
    float: left; /* **children floated left** */
    margin: 0 5px;
}

(Ceci est le RÉSULTAT (attendu - et indésirable) )

Ajoutez maintenant les règles suivantes au wrapper:

display: flex;
justify-content: center; /* align horizontal */

et les enfants flottants sont alignés au centre ( DEMO )

Juste pour le plaisir, pour obtenir un alignement vertical, ajoutez simplement:

align-items: center; /* align vertical */

DEMO

Danield
la source
il faut encore vérifier les compatibilités du navigateur, mais cela semble génial!
low_rents
Vous pouvez également utiliser display: inline au lieu de flex pour centrer les divs. Flex a des problèmes avec Safari et Opera.
VOUS
inline ne fonctionne pas pour moi. Le problème de cette solution est qu'alors les boîtes ne vont pas à la deuxième ligne si elles dépassent la largeur du div. Vous les avez donc transformés en table ...
Pavel Jiri Strnad
10

J'ai accompli ce qui précède en utilisant un positionnement relatif et en flottant vers la droite.

Code HTML:

<div class="clearfix">                          
    <div class="outer-div">
        <div class="inner-div">
            <div class="floating-div">Float 1</div>
            <div class="floating-div">Float 2</div>
            <div class="floating-div">Float 3</div>
        </div>
    </div>
</div>

CSS:

.outer-div { position: relative; float: right; right: 50%; }
.inner-div { position: relative; float: right; right: -50%; }
.floating-div { float: left; border: 1px solid red; margin: 0 1.5em; }

.clearfix:before,
.clearfix:after { content: " "; display: table; }
.clearfix:after { clear: both; }
.clearfix { *zoom: 1; }

JSFiddle: http://jsfiddle.net/MJ9yp/

Cela fonctionnera dans IE8 et plus, mais pas plus tôt (surprise, surprise!)

Je ne me souviens malheureusement pas de la source de cette méthode, je ne peux donc pas donner de crédit à l'auteur original. Si quelqu'un d'autre sait, veuillez poster le lien!

Kendolein
la source
+1 Cela fonctionne à merveille. La réponse acceptée n'a pas fonctionné pour moi. Cela a créé des problèmes d'alignement vertical ...
TimH - Codidact
@TimH En retard à la fête, je sais, mais le problème d'alignement vertical peut être résolu en ajoutant 'vertical-align: top' au conteneur
Alfie
Désolé, je voulais dire div interne, pas div conteneur *
Alfie
Cela fonctionne presque parfaitement. Les éléments vont à la ligne suivante si le débordement, mais quand ils le font, ils ne sont pas centrés.
Pavel Jiri Strnad
5

La solution suivante n'utilise pas de blocs en ligne. Cependant, il nécessite deux div d'assistance:

  1. Le contenu est flotté
  2. L'aide interne est flottante (elle s'étire autant que le contenu)
  3. L'assistant interne est poussé à droite de 50% (sa gauche s'aligne avec le centre de l'aide externe)
  4. Le contenu est tiré à gauche à 50% (son centre s'aligne avec la gauche de l'aide interne)
  5. L'assistant externe est configuré pour masquer le débordement

.ca-outer {
  overflow: hidden;
  background: #FFC;
}
.ca-inner {
  float: left;
  position: relative;
  left: 50%;
  background: #FDD;
}
.content {
  float: left;
  position: relative;
  left: -50%;
  background: #080;
}
/* examples */
div.content > div {
  float: left;
  margin: 10px;
  width: 100px;
  height: 100px;
  background: #FFF;
}
ul.content {
  padding: 0;
  list-style-type: none;
}
ul.content > li {
  margin: 10px;
  background: #FFF;
}
<div class="ca-outer">
  <div class="ca-inner">
    <div class="content">
      <div>Box 1</div>
      <div>Box 2</div>
      <div>Box 3</div>
    </div>
  </div>
</div>
<hr>
<div class="ca-outer">
  <div class="ca-inner">
    <ul class="content">
      <li>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</li>
      <li>Nullam efficitur nulla in libero consectetur dictum ac a sem.</li>
      <li>Suspendisse iaculis risus ut dapibus cursus.</li>
    </ul>
  </div>
</div>

Salman A
la source
4

display: inline-block;ne fonctionnera dans aucun des navigateurs IE. Voici ce que j'ai utilisé.

// change the width of #boxContainer to 
// 1-2 pixels higher than total width of the boxes inside:

#boxContainer {         
    width: 800px; 
    height: auto;
    text-align: center;
    margin-left: auto;
    margin-right: auto;
}

#Box{
    width: 240px; 
    height: 90px;
    background-color: #FFF;
    float: left;
    margin-left: 10px;
    margin-right: 10px;
}
Abdulla Kaleem
la source
3

Solution:

<!DOCTYPE HTML>
<html>
    <head>
        <title>Knowledge is Power</title>
        <script src="js/jquery.js"></script>
        <script type="text/javascript">
        </script>
        <style type="text/css">
            #outer {
                text-align:center;
                width:100%;
                height:200px;
                background:red;
            }
            #inner {
                display:inline-block;
                height:200px;
                background:yellow;
            }
        </style>
    </head>
    <body>
        <div id="outer">
            <div id="inner">Hello, I am Touhid Rahman. The man in Light</div>
        </div>
    </body>
</html>
Touhid Rahman
la source
Cette solution est hors sujet. L'intérieur doit être flottant: laissé pour répondre aux exigences du PO.
s15199d
1

Dans mon cas, je n'ai pas pu obtenir la réponse de @Sampson pour moi, au mieux j'ai une seule colonne centrée sur la page. Dans le processus cependant, j'ai appris comment le flotteur fonctionne réellement et j'ai créé cette solution. Au fond, le correctif est très simple mais difficile à trouver, comme en témoigne ce fil qui a eu plus de 146k vues au moment de cet article sans mention.

Tout ce qui est nécessaire est de totaliser la largeur de l'espace d'écran que la mise en page souhaitée occupera, puis de donner au parent la même largeur et d'appliquer la marge: auto. C'est tout!

Les éléments de la mise en page dicteront la largeur et la hauteur du div "extérieur". Prenez chaque "myFloat" ou la largeur ou la hauteur de chaque élément + ses bordures + ses marges et ses rembourrages et ajoutez-les tous ensemble. Ensuite, ajoutez les autres éléments ensemble de la même manière. Cela vous donnera la largeur du parent. Ils peuvent tous être de tailles quelque peu différentes et vous pouvez le faire avec moins ou plus d'éléments.

Ex. (Chaque élément a 2 côtés donc la bordure, la marge et le remplissage sont multipliés par 2)

Donc, un élément qui a une largeur de 10px, une bordure 2px, une marge 6px, un remplissage de 3px ressemblerait à ceci: 10 + 4 + 12 + 6 = 32

Ajoutez ensuite toutes les largeurs totalisées de votre élément.

Element 1 = 32
Element 2 = 24
Element 3 = 32
Element 4 = 24

Dans cet exemple, la largeur du div "extérieur" serait de 112.

.outer {
  /* floats + margins + borders = 270 */
  max-width: 270px;
  margin: auto;
  height: 80px;
  border: 1px;
  border-style: solid;
}

.myFloat {
    /* 3 floats x 50px = 150px */
    width: 50px;
    /* 6 margins x 10px = 60 */
    margin: 10px;
    /* 6 borders x 10px = 60 */
    border: 10px solid #6B6B6B;
    float: left;
    text-align: center;
    height: 40px;
}
<div class="outer">
  <div class="myFloat">Float 1</div>
  <div class="myFloat">Float 2</div>
  <div class="myFloat">Float 3</div>
</div>

dimmech
la source
C'est la réponse que je cherchais, merci. Comment calculez-vous le px dont vous avez besoin? N'est pas clair pour moi.
SilverSurfer