2012-03-30 6 views
53

La specifica CSS2.1 mandates that overflow other than visible establish a new "block formatting context". Questo mi sembra strano, che una proprietà il cui ovvio scopo è nascondere l'overflow senza influenzare il layout, in realtà influisce sul layout in modo sostanziale.Perché i CSS2.1 definiscono valori di overflow diversi da "visibili" per stabilire un nuovo contesto di formattazione dei blocchi?

Sembra che i valori di overflow diversi da visible uniscano due funzioni completamente indipendenti: se viene creato un BFC e se l'overflow è nascosto. Non è come "overflow: hidden" è completamente privo di significato senza un BFC, perché i float possono storicamente eccedere il loro elemento genitore, hiding the overflow without changing the layout sembra ragionevole.

Quali sono le ragioni di questa decisione, supponendo che siano conosciute? Le persone che hanno lavorato sulle specifiche hanno descritto il motivo per cui questo è stato deciso?

+3

Stavo per chiedere questo, ma non volevo rubare le luci della ribalta :) +1 e recitato. – BoltClock

+3

Questo è insolito; altre domande che invitano allo stesso modo risposte speculative e/o che rispondono solo alle poche persone coinvolte nella decisione, normalmente vengono chiuse. Questo sito è davvero incoerente con la chiusura delle domande. – Timwi

+2

@Timwi: Idealmente, domande come questa che * fanno * hanno risposte definitive * non dovrebbero * essere chiuse, ma è davvero compito della comunità decidere. Vedi [questo meta post] (http://meta.stackexchange.com/questions/96310/is-miscategorization-of-obscure-questions-as-not-real-a-problem). In realtà ero piuttosto riluttante a postare questo su SO per il motivo menzionato, così come l'intera faccenda della speculazione, e invece lo porto alla mailing list. Ma ho capito che diamine, vediamo come va. Se ci sono troppe risposte speculative, possiamo lasciare che sia la comunità a gestirle, oppure posso rispondere alle bandiere. – BoltClock

risposta

61

ho chiesto questo sulla mailing list a vostro nome; il thread può essere trovato here. In sintesi, this has to do with scrolling content for the most part:

Fondamentalmente, perché se le specifiche non ha detto questo, allora hanno carri si intersecano con qualcosa che è scorrevole richiederebbe il browser per Rewrap (circa intrusione carri) il contenuto dell'elemento scorrevole ogni volta scorre. Questo è tecnicamente ciò che è richiesto dal CSS 2.0 , ma non è mai stato implementato e sarebbe stato un grosso problema per la velocità di scorrimento.

-David

Molto probabilmente, si riferisce al contenuto scorrevole in una scatola che può verificarsi al di fuori della madre del galleggiante, ma si intersecano con il galleggiante. Non penso che questo sia legato al rewrapping di contenuti attorno a un float all'interno di un contenitore scorrevole, come succede già in natura, più the float would clip into the container and scroll along with the rest of its content anyway.

Finalmente questo ha senso per me. In effetti, fornirò un esempio qui, quindi spero che abbia senso per te e per chiunque altro si stia chiedendo.Si consideri uno scenario che coinvolge due scatole con la stessa altezza fissa e overflow: visible (il default), di cui il primo contiene un galleggiante che si estende al di là altezza del suo genitore:

<div> 
    <p>...</p> 
</div> 
<div> 
    <p>...</p> 
    <p>...</p> 
</div> 
/* Presentational properties omitted */ 
div { 
    height: 80px; 
} 

div:first-child:before { 
    float: left; 
    height: 100px; 
    margin: 10px; 
    content: 'Float'; 
} 

Avviso la somiglianza a uno degli esempi forniti in section 9.5. La seconda casella qui viene semplicemente mostrata per avere contenuti in eccesso ai fini di questa risposta.

Questo va bene poiché il contenuto non verrà mai scostato, ma quando overflow è impostato su un valore diverso da visible, ciò fa sì che il contenuto non solo venga ritagliato dai limiti della casella, ma anche per diventare scorrevole. Se la seconda casella ha overflow: auto, questo è ciò che sarebbe simile ha avuto un browser implementato le specifiche CSS2 originale:

A causa del galleggiante, tentando di scorrere il contenuto causerebbe il browser di dover Rewrap così non diventa oscurato dal float (e cosa dovrebbe accadere alla parte che scorre fuori dal bordo superiore?). Sarebbe probabilmente cercare qualcosa di simile quando scorrere verso il basso:

Il fermo qui è che il browser deve Rewrap il contenuto ogni volta che ridisegna durante lo scorrimento. Per i browser che sono in grado di eseguire lo scorrimento uniforme basato su pixel, vale a dire tutti, posso capire perché sarebbe un disastro di prestazioni! (E anche l'esperienza utente.)

Ma questo è per quando l'utente può scorrere il contenuto, giusto? Questo avrebbe senso per overflow: auto e overflow: scroll, ma che dire di overflow: hidden?

Bene, un malinteso comune è che un contenitore con overflow: hidden nasconda semplicemente il contenuto da ritaglio e non può essere scostato. This is not completely true:

Durante lo scorrimento UI non è previsto, il contenuto è ancora scorrevole di programmazione, e un certo numero di pagine eseguire proprio tale scorrimento (ad esempio impostando scrollTop sull'elemento corrispondente).

-Boris

In effetti, questo è ciò che sarebbe guardare come se la seconda casella è stata impostata su overflow: hidden e poi scorrere verso il basso con il seguente JavaScript:

var div = document.getElementsByTagName('div')[1]; 
div.scrollTop = div.scrollHeight; 

Ancora una volta, si noti che il contenuto dovrebbe essere riavvolto per evitare di essere oscurato dal galleggiante.

Anche se questo non sarebbe così dolorosa per le prestazioni come aveva scorre UI stato disponibile, la mia ipotesi migliore è che hanno fatto scatole con qualsiasioverflow valore diverso da visible generare un nuovo BFC principalmente per motivi di coerenza.


E così, questo cambiamento è stato determinato in CSS 2.1, documentato here. Ora se si applica un valore overflow diverso da visible solo alla seconda casella, ciò che fa un browser è spingere l'intera casella a parte per far posto al float, poiché la casella ora crea un nuovo contesto di formattazione dei blocchi che ne racchiude il contenuto, invece di scorrere attorno al galleggiante. Questo particolare comportamento è specificato nella seguente paragraph:

Il bordo casella di una tabella, un elemento a livello di blocco sostituito, o un elemento nel flusso normale che stabilisce un nuovo contesto di formattazione a blocchi (come un elemento con 'overflow' diverso da 'visible') non deve sovrapporsi al margine di qualsiasi float nello stesso contesto di formattazione del blocco dell'elemento stesso. Se necessario, le implementazioni dovrebbero liberare il suddetto elemento posizionandolo al di sotto dei galleggianti precedenti, ma può posizionarlo adiacente a tali galleggianti se c'è spazio sufficiente. Possono persino rendere la casella di confine di detto elemento più stretta di quella definita da section 10.3.3. CSS2 non definisce quando un UA può mettere detto elemento accanto al float o da quanto detto elemento può diventare più stretto.

Ecco come si presenta con overflow: auto per esempio:

Si noti che non v'è alcun gioco; se la seconda casella fosse stata clear: left o clear: both, verrà spinto in basso, non di lato, indipendentemente dal fatto che abbia stabilito il proprio BFC.

Se si applica overflow: auto alla prima casella invece, il galleggiante è ritagliato nella sua contenente dialogo con il resto del contenuto grazie alla sua altezza fissa, che è impostato per 80px nel codice di esempio dato sopra:

Se si ripristina la prima casella per height: auto (il valore di default), o sovrascrivendo o rimuovendo la dichiarazione height: 80px dall'alto, allora estende all'altezza del galleggiante:

Questo sembra essere new in CSS2.1 as well, dal fatto che un elemento con height: auto che genera un contesto nuovo blocco formattazione (cioè a root del contesto di formattazione del blocco) si estenderà verticalmente fino all'altezza dei suoi float e non solo quanto basta per contenere il contenuto del flusso in uscita a differenza di un normale riquadro. Le modifiche sono documentate here e here. La modifica che porta all'effetto collaterale del restringimento della scatola in modo che non intersechi il galleggiante è documentata here.

In entrambi questi casi, indipendentemente da ciò che si fa alla seconda casella, non verrà mai influenzato dal float perché è stato limitato dai limiti del suo contenitore.

+8

Una risposta davvero buona, dubito che molte persone si imbattano in questa, ma quando lo fanno ..., +1 :) –

+0

Non è anche "overflow: visibile" scorrevole? – HRJ

+1

@HRJ: No, non lo è. – BoltClock

4

So che questo sarà una risposta speculativa, ma dopo aver letto le specifiche di un paio di volte qui è la mia opinione su questo:

quale sezione 9.4.1 sta parlando è un qualsiasi elemento di blocco che non contiene in tutto o in non riempie lo spazio di contenimento. Ad esempio, quando si fa galleggiare un elemento non si riempie più il 100% del genitore, come fanno gli elementi di flusso. Blocchi in linea, celle di tabella e didascalie delle tabelle sono anche elementi che possono influenzare altezza e larghezza ma che non sono intrinsecamente il 100% del genitore (si tabella> tr> td è uno che riempirebbe il 100% del suo genitore ma è progettato per consentire più td in modo che il td non contenga dato che si ridurrà automaticamente per ospitare td aggiuntivi) ciò si applica anche a qualsiasi overflow diverso da visibile perché interrompe il contenimento dell'elemento di blocco.

Quindi, se sto leggendo correttamente questo il modo in cui funziona è la sezione 9.4.1 si riferisce a bloccare gli elementi che infrangono le regole predefinite di contenimento degli elementi di blocco, come specificato dalla sezione 9.2.1

+1

Il tuo riepilogo risulta parzialmente corretto. Sebbene, piuttosto che infrangere le regole, stabiliscono semplicemente regole diverse per loro. Vedi l'ultima parte della mia risposta per una spiegazione. – BoltClock

Problemi correlati