Elementi fluttuanti all'interno di un div, galleggiano all'esterno del div. Perché?


274

Di 'che hai un div, dagli un preciso widthe mettici degli elementi, nel mio caso un imge un altro div.

L'idea è che il contenuto del contenitore divcauserà l' divallungamento del contenitore e costituirà uno sfondo per il contenuto. Ma quando lo faccio, il contenimento si divrestringe per adattarsi agli oggetti non fluttuanti e gli oggetti fluttuanti saranno o completamente fuori, o metà fuori, metà dentro e non avranno alcun impatto sulla dimensione del grande div.

Perchè è questo? C'è qualcosa che mi manca e come posso ottenere elementi fluttuati per allungare il heightdi un contenitore div?

Risposte:


398

Il più semplice è mettere overflow:hiddenil div genitore e non specificare un'altezza:

#parent { overflow: hidden }

Un altro modo è far fluttuare anche il div parent:

#parent { float: left; width: 100% }

Un altro modo utilizza un elemento chiaro:

<div class="parent">
   <img class="floated_child" src="..." />
   <span class="clear"></span>
</div>

CSS

span.clear { clear: left; display: block; }

17
Funziona, ma ora sono il doppio confuso: c'è una spiegazione per questo o è proprio così?
David,

8
Sì, c'è una spiegazione, ma da allora l'ho dimenticato :( È proprio così. overflow:hiddenForza il browser nel modo migliore per contenere gli elementi figlio del genitore. Ecco perché lo risolve.
Doug Neiner,

5
Penso che la spiegazione overflow: hiddensia qui: link . E grazie mille, ha funzionato per me
Vikas Arora,

6
@DavidR La spiegazione più semplice è che html / css è una tecnologia datata, scarsamente ponderata e mal implementata. In realtà, questo ragionamento spiega in realtà molte stranezze html / css che non hai dubbi da quando hai pubblicato questo post.
Leggero

1
Tieni presente che overflow: hiddennasconderà qualsiasi parte di un elemento che fuoriesce dal contenitore padre. Per me, ciò ha reso illeggibili alcune parti di testo.
Top Cat

160

Motivo

Il problema è che gli elementi mobili sono fuori flusso :

Un elemento viene chiamato fuori flusso se viene fluttuato, posizionato in modo assoluto o è l'elemento radice.

Pertanto, non influiscono sugli elementi circostanti come farebbe un elemento in-flow .

Questo è spiegato in 9.5 Float :

Poiché un galleggiante non è nel flusso, le scatole di blocchi non posizionate create prima e dopo la scatola del galleggiante scorrono verticalmente come se il galleggiante non esistesse. Tuttavia, le caselle di riga correnti e successive create accanto al float vengono accorciate se necessario per fare spazio alla casella del margine del float.

inserisci qui la descrizione dell'immagine

Questo è anche specificato in 10.6 Calcolo delle altezze e dei margini . Per blocchi "normali" ,

Vengono presi in considerazione solo i bambini nel flusso normale (ovvero, le caselle mobili e le caselle posizionate in modo assoluto vengono ignorate […])

inserisci qui la descrizione dell'immagine

Soluzione Hacky: liquidazione

Un modo per risolvere il problema è forzare un elemento in-flow da posizionare sotto tutti i galleggianti. Quindi, l'altezza del genitore crescerà per avvolgere quell'elemento (e quindi anche i galleggianti).

Ciò può essere ottenuto utilizzando la clearproprietà :

Questa proprietà indica quali lati dei riquadri di un elemento potrebbero non essere adiacenti a un riquadro mobile precedente.

inserisci qui la descrizione dell'immagine

Quindi una soluzione sta aggiungendo un elemento vuoto con clear: bothl'ultimo fratello dei float

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

Tuttavia, ciò non è semantico. Quindi meglio generare uno pseudo-elemento alla fine del genitore:

.clearfix::after {
  clear: both;
  display: block;
}

Esistono più varianti di questo approccio, ad esempio l'utilizzo della sintassi dei due punti deprecata :afterper supportare i vecchi browser o l'utilizzo di altri display a livello di blocco come display: table.

Soluzione: radici di BFC

Esiste un'eccezione al comportamento problematico definito all'inizio: se un elemento a blocchi stabilisce un contesto di formattazione dei blocchi (è una radice BFC), avvolgerà anche il suo contenuto mobile.

Secondo le altezze 10.6.7 "Auto" per le root di contesto di formattazione dei blocchi ,

Se l'elemento ha discendenti mobili il cui bordo del margine inferiore è inferiore al bordo del contenuto inferiore dell'elemento, l'altezza viene aumentata per includere tali bordi.

inserisci qui la descrizione dell'immagine

Inoltre, come spiegato 9.5 Float , anche le radici BFC sono utili a causa di quanto segue:

Il riquadro di bordo di una tabella, un elemento sostituito a livello di blocco o un elemento nel flusso normale che stabilisce un nuovo contesto di formattazione del blocco […] non deve sovrapporsi al riquadro del margine di alcun float nello stesso contesto di formattazione del blocco dell'elemento stesso .

inserisci qui la descrizione dell'immagine

Un contesto di formattazione dei blocchi è stabilito da

  • Bloccare le scatole con overflowaltro visible, ad eshidden

    .bfc-root {
      overflow: hidden;
      /* display: block; */
    }
  • Blocca contenitori che non sono caselle di blocco: quando displayè impostato su inline-block, table-cello table-caption.

    .bfc-root {
      display: inline-block;
    }
  • Elementi mobili: quando floatè impostato su lefto right.

    .bfc-root {
      float: left;
    }
  • Elementi posizionati in modo assoluto: quando positionè impostato su absoluteo fixed.

    .bfc-root {
      position: absolute;
    }

Si noti che potrebbero avere effetti collaterali indesiderati, come il ritaglio del contenuto traboccante, il calcolo delle larghezze automatiche con l' algoritmo di riduzione o l'adattamento o il fuori flusso. Quindi il problema è che non è possibile avere un elemento a livello di blocco in-flow con overflow visibile che stabilisce un BFC.

Display L3 risolve questi problemi:

Creato i tipi di visualizzazione internaflow e per esprimere meglio i tipi di visualizzazione del layout di flusso e per creare un interruttore esplicito per rendere un elemento una radice BFC . (Questo dovrebbe eliminare la necessità di hack come e […])flow-root ::after { clear: both; }overflow: hidden

Purtroppo, non esiste ancora alcun supporto per il browser. Alla fine potremmo essere in grado di usare

.bfc-root {
  display: flow-root;
}

1
Quindi le scatole fluttuanti non sono riconosciute dai loro contenitori principali, quindi l'altezza crolla, ma sono riconosciute dai loro fratelli, quindi il clearfix?
link simbolico

@symlink Sì, i contenitori padre non crescono per racchiudere i float, a meno che non siano root BFC. I fratelli che non sono root BFC non sono influenzati direttamente dai blocchi (ma le loro caselle di linea lo sono). Tuttavia, il gioco li sposta sotto qualsiasi float precedente.
Oriol,

"I fratelli che non sono root BFC non sono influenzati direttamente dai blocchi (ma le loro caselle di linea lo sono)." - Puoi chiarire questo per favore? Vuoi dire che in questo jsFiddle: jsfiddle.net/aggL3Lk7/2 , l'immagine in linea fluttuata non sta influenzando l'intervallo (quindi il bordo dell'intervallo si sovrappone ad esso) ma l'immagine sta influenzando il testo (che è la casella di linea) come mostrato dal fatto che il testo non si sta sovrapponendo all'immagine?
link simbolico

1
@symlink Sì, esattamente. Bene, nel tuo violino il confine appartiene al genitore, ma sarebbe sostanzialmente lo stesso per i fratelli: jsfiddle.net/aggL3Lk7/3
Oriol

1
Concordo. Questa dovrebbe essere la risposta accettata. È interessante per me che il W3 stia chiamando il modo in cui siamo costretti a programmare un "hack". Qualcuno ha fatto un casino.
DR01D



11

Non manca nulla. Float è stato progettato per il caso in cui si desidera che un'immagine (ad esempio) venga posizionata accanto a diversi paragrafi di testo, in modo che il testo scorra intorno all'immagine. Ciò non accadrebbe se il testo "allungasse" il contenitore. Il tuo primo paragrafo finirebbe, e poi il tuo prossimo paragrafo inizierebbe sotto l'immagine (probabilmente diverse centinaia di pixel in basso).

Ed è per questo che stai ottenendo il risultato che sei.


3
In che modo ciò ha a che fare con l'elemento mobile che allunga correttamente l'altezza del genitore?
Leggero

11

In alcuni casi, vale a dire quando (se) stai solo usando gli floatelementi per scorrere sulla stessa "linea", potresti usare

display: inline-block;

invece di

float: left;

Altrimenti, usare un clearelemento alla fine funziona, anche se può andare contro il grano per avere bisogno di un elemento per fare quello che dovrebbe essere il lavoro CSS.


11

Ecco un approccio più moderno:

.parent {display: flow-root;} 

Niente più correzioni.

ps Utilizzo di overflow: nascosto; nasconde l'ombra della scatola così ...


Funziona anche in Safari 11
pendingfox il

7

Grazie LSerni l' hai risolto per me.

Per realizzare questo :

+-----------------------------------------+
| +-------+                     +-------+ |
| | Text1 |                     | Text1 | |
| +-------+                     +-------+ |
|+----------------------------------------+

Devi fare questo:

<div style="overflow:auto">
    <div style="display:inline-block;float:left"> Text1 </div>
    <div style="display:inline-block;float:right"> Text2 </div>
</div>

4

Come dice Lucas, quello che stai descrivendo è il comportamento previsto per la proprietà float. Ciò che confonde molte persone è che float è stato spinto ben oltre il suo uso originale previsto al fine di compensare le carenze nel modello di layout CSS.

Dai un'occhiata a Floatutorial se vuoi capire meglio come funziona questa proprietà.


0

Puoi fare facilmente con prima puoi rendere flessibile il div e applicare giustificare il contenuto a destra o a sinistra e il tuo problema è risolto.

<div style="display: flex;padding-bottom: 8px;justify-content: flex-end;">
					<button style="font-weight: bold;outline: none;background-color: #2764ff;border-radius: 3px;margin-left: 12px;border: none;padding: 3px 6px;color: white;text-align: center;font-family: 'Open Sans', sans-serif;text-decoration: none;margin-right: 14px;">Sense</button>
				</div>

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.