Centrare div galleggianti all'interno di un'altra div


142

Ho cercato altre domande e, mentre questo problema sembra simile a un paio di altri, nulla di ciò che ho visto finora sembra affrontare il problema che sto riscontrando.

Ho un div che contiene un numero di altri div, ognuno dei quali è flottato a sinistra. Queste div contengono ciascuna una foto e una didascalia. Tutto quello che voglio è che il gruppo di foto sia centrato all'interno del div contenente.

Come si può vedere dal codice qui sotto, ho provato utilizzando sia overflow:hiddene margin:x autodei div genitore, e ho anche aggiunto una clear:both(come suggerito in un altro argomento), dopo le foto. Nulla sembra fare la differenza.

Grazie. Apprezzo qualsiasi suggerimento.

<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>


@TylerH Come mai? Basta vedere la data in cui è stato chiesto. Sembra che la domanda nel tuo link sia il vero duplicato.
The Pragmatick,

@ThePragmatick Perché quello ha il doppio delle visualizzazioni, più risposte, più attività (e più recenti) e la sua formulazione serve come una domanda canonica migliore di questa.
TylerH,

Risposte:


266

Per prima cosa, rimuovi l' floatattributo dalla finestra interna div. Quindi, indossa text-align: centerl'esterno principale div. E per gli interni div, usare display: inline-block. Potrebbe anche essere saggio dare loro anche larghezze esplicite.


<div style="margin: auto 1.5em; display: inline-block;">
  <img title="Nadia Bjorlin" alt="Nadia Bjorlin" src="headshot.nadia.png"/>
  <br/>
  Nadia Bjorlin
</div>

6
@Darren: hai smesso di galleggiare quando hai provato? Non sarai in grado di realizzare ciò che desideri fintanto che stai fluttuando / a meno che / non imposti una larghezza fissa sul contenitore dei galleggianti.
Ken Browning,

1
Oh ... mi sbaglio. La rimozione del galleggiante sembra che compia esattamente quello che voglio. Non sono sicuro di aver capito il perché, ma ... Grazie mille.
Darren,

9
@Darren, nota nel mio esempio di codice che non ho incluso il floating;) Leggi più attentamente la prossima volta, ti farà risparmiare un po 'di frustrazione :) Sono contento che tu l'abbia capito però. Continuate così e benvenuti in SO.
Sampson,

2
Questo approccio inizia a fallire quando alcune didascalie dell'immagine sono abbastanza lunghe da avvolgere la linea. Altri suggerimenti?
greg.kindel,

3
Non importa, ho scoperto che il problema dei sottotitoli di conteggio delle righe variabili può essere risolto con "vertical-align: top". =)
greg.kindel,

33

Con Flexbox puoi facilmente centrare orizzontalmente (e verticalmente) i bambini fluttuanti all'interno di un div.

Quindi se hai un markup semplice in questo modo:

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

con 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;
}

(Questo è il RISULTATO (previsto - e indesiderabile) )

Ora aggiungi le seguenti regole al wrapper:

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

e i bambini galleggianti vengono allineati al centro ( DEMO )

Per divertimento, per ottenere l'allineamento verticale basta aggiungere:

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

DEMO


devo ancora verificare la compatibilità del browser, ma questo sembra essere fantastico!
low_rents,

Puoi anche usare display: inline anziché flex per centrare div. Flex ha problemi con Safari e Opera.
TU

inline non funziona con me. Il problema di questa soluzione è che le caselle non vanno alla seconda riga se traboccano la larghezza del div. Quindi li hai trasformati in un tavolo ...
Pavel Jiri Strnad,

10

Ho realizzato quanto sopra usando il posizionamento relativo e fluttuando a destra.

Codice 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/

Funzionerà in IE8 e versioni successive, ma non prima (sorpresa, sorpresa!)

Purtroppo non ricordo la fonte di questo metodo, quindi non posso dare credito all'autore originale. Se qualcun altro lo sa, si prega di pubblicare il link!


+1 Funziona magnificamente. La risposta accettata non ha funzionato per me. Ha creato problemi di allineamento verticale ...
TimH - Codidact

@TimH In ritardo alla festa, lo so, ma il problema dell'allineamento verticale può essere risolto aggiungendo 'vertical-align: top' al contenitore
Alfie

Spiacente, intendevo div interno, non div contenitore *
Alfie

Funziona quasi perfettamente. Gli elementi passeranno alla riga successiva se l'overflow, ma quando lo fanno non sono centrati.
Pavel Jiri Strnad,

5

La seguente soluzione non utilizza blocchi in linea. Tuttavia, richiede due div helper:

  1. Il contenuto è mobile
  2. L'helper interno è flottato (si estende tanto quanto il contenuto)
  3. L'helper interno viene spinto a destra del 50% (la sua sinistra si allinea al centro dell'helper esterno)
  4. Il contenuto viene tirato a sinistra del 50% (il suo centro si allinea con la sinistra dell'helper interno)
  5. L'helper esterno è impostato per nascondere l'overflow

.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>


4

display: inline-block;non funzionerà in nessuno dei browser IE. Ecco cosa ho usato.

// 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;
}

3

Soluzione:

<!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>

Questa soluzione è fuori tema. L'interno dovrebbe essere mobile: lasciato per soddisfare i requisiti del PO.
s15199d,

1

Nel mio caso, non sono riuscito a far funzionare la risposta di @Sampson per me, nella migliore delle ipotesi ho una singola colonna centrata sulla pagina. Nel processo, tuttavia, ho imparato come funziona il float e ho creato questa soluzione. Fondamentalmente la correzione è molto semplice ma difficile da trovare come evidente da questo thread che ha avuto più di 146k visualizzazioni al momento di questo post senza menzione.

Tutto ciò che serve è il totale della quantità di spazio dello schermo che occuperà il layout desiderato, quindi rendere il genitore della stessa larghezza e applicare il margine: auto. Questo è tutto!

Gli elementi nel layout dettano la larghezza e l'altezza del div "esterno". Prendi ogni "myFloat" o la larghezza o l'altezza dell'elemento + i suoi bordi + i suoi margini e le sue imbottiture e aggiungili tutti insieme. Quindi aggiungi gli altri elementi insieme nello stesso modo. Questo ti darà la larghezza del genitore. Possono avere dimensioni leggermente diverse e puoi farlo con meno o più elementi.

Es. (Ogni elemento ha 2 lati, quindi bordo, margine e imbottitura si moltiplicano x2)

Quindi un elemento che ha una larghezza di 10px, bordo 2px, margine 6px, riempimento 3px sarebbe simile a questo: 10 + 4 + 12 + 6 = 32

Quindi aggiungi tutte le larghezze totali del tuo elemento insieme.

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

In questo esempio la larghezza per il div "esterno" sarebbe 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>


Questa è la risposta che stavo cercando, grazie. Come si calcola il px necessario? Non mi è chiaro.
SilverSurfer,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.