Jak działa kontekst formatowania bloków CSS ?
Specyfikacje CSS2.1 mówią, że w kontekście formatowania blokowego, pola są ułożone pionowo, zaczynając od góry. Dzieje się tak nawet wtedy, gdy przeszkadzają elementy pływające, chyba że pole bloku ustanowiło nowy kontekst formatowania bloku. Jak wiemy, kiedy przeglądarki renderują pola bloków w kontekście formatowania bloków, element pływający jest pomijany, dlaczego działa ustanowienie nowego kontekstu formatowania bloków?
Jak układane są pudełka (pudełka blokowe i pudełka inline) w normalnym przepływie?
Czytałem gdzieś, że elementy blokowe generują bloki, ale elementy pływające są ignorowane, gdy agent użytkownika rysuje pudełko i bierze je pod uwagę podczas wypełniania treści. Podczas gdy elementy pływające będą nakładać się na granice ramek innych elementów, rozwiązaniem jest ustanowienie nowego kontekstu formatowania bloków dla nakładających się elementów przy użyciu overflow:hidden
.
„Nowy kontekst formatowania bloku nadal jest formatowaniem blokowym”, więc podczas rysowania ramki będzie również traktował element pływający tak, jakby nie był zamykany. Czy to prawda, czy też źle zrozumiałem „nowy kontekst formatowania bloków”?
Aktualizacja: więcej pytań
Mówiąc: „To zachowanie jest przydatne w układach w stylu kolumnowym. Jednak jego głównym zastosowaniem jest zatrzymywanie elementów zmiennoprzecinkowych, powiedzmy w elemencie DIV„ głównej zawartości ”, a właściwie czyszczenie pływających kolumn bocznych, tj. Elementów zmiennoprzecinkowych, które pojawiają się wcześniej w kodzie źródłowym”.
Nie rozumiem znaczenia, podam przykład, może mnie zrozumiesz.
Pomyślałem, że pływające pudełko powinno wypłynąć na szczyt zawartego bloku - div z klasą content
. Poza tym, jeśli pływające pole pojawi się wcześniej w znaczniku, wyświetli to, co myślę, że powinno być.
Jak możemy to wyjaśnić? Czy możemy użyć „kontekstu formatowania blokowego i kontekstu formatowania wbudowanego”, aby to wyjaśnić?
Odpowiedzi:
Blokowe konteksty formatowania
Z moim pogrubienie, że to nawiązania transmisji, która jest ważna
Oznacza to, że element, którego używasz
overflow
(cokolwiek innego niż widoczny)float
lub ...inline-block
itd., Staje się odpowiedzialny za układ swoich elementów potomnych. To elementy potomne są następnie „zawarte”, niezależnie od tego, czy są to marginesy zmiennoprzecinkowe, czy zwijane, powinny być w całości zawarte przez rodzica ograniczającego.Co oznacza powyższa linia:
Ponieważ pudełko może być tylko prostokątne i nie ma nieregularnego kształtu, oznacza to, że nowy kontekst formatowania bloku między dwoma pływakami (lub nawet obok jednego) nie będzie zawijał się wokół sąsiednich bocznych elementów pływających. Wewnętrzne pudełka podrzędne mogą sięgać tylko tak daleko, jak dotykają ich rodziców po lewej (lub prawej w RTL) krawędzi. To zachowanie jest przydatne w przypadku układów kolumnowych. Jednak jego głównym zastosowaniem jest zatrzymywanie elementów zmiennoprzecinkowych, powiedzmy w elemencie div „głównej zawartości”, a właściwie czyszczenie pływających kolumn bocznych, tj. Elementów zmiennoprzecinkowych, które pojawiają się wcześniej w kodzie źródłowym.
Wyprzedaż pływaka
W normalnych okolicznościach elementy zmiennoprzecinkowe powinny usuwać wszystkie poprzednie elementy pływające, które wcześniej znajdowały się w całym kodzie źródłowym, a nie tylko w wyświetlanej "kolumnie". Cytat ze "specyfikacji prześwitu pływającego" to:
Więc załóżmy, że masz układ trzech kolumn, w którym lewa i prawa kolumna są przestawione odpowiednio po lewej i prawej stronie, boczne kolumny są teraz w nowych kontekstach formatowania bloku, ponieważ są pływające (pamiętaj, że zmiennoprzecinkowa jest również jedną z właściwości, które ustanawiają nowy BFC ), więc możesz szczęśliwie unosić elementy listy wewnątrz nich i usuwają one tylko elementy zmiennoprzecinkowe, które są już w bocznych kolumnach, o których już nie dbają, pływające wcześniej w kodzie źródłowym
Aby uczynić główną treść nowym kontekstem formatowania bloku, czy nie?
Teraz tę środkową kolumnę możesz po prostu zabezpieczyć z obu stron, tak aby wyglądała równo między dwiema bocznymi kolumnami pływającymi i przyjmowała pozostałą szerokość, co jest powszechnym sposobem uzyskania pożądanej szerokości, jeśli środkowa kolumna jest „płynna” - będzie dobrze, dopóki nie będziesz musiał używać pływaków / luzów wewnątrz elementu div z treścią (typowe zjawisko w przypadku osób używających hacków typu „clearfix” lub zawierających je szablonów)
Weź ten bardzo prosty kod:
Pokaż fragment kodu
#left-col { border: 1px solid #000; width: 180px; float: left; } #right-col { border: 1px solid #000; width: 180px; float: right; height: 200px; } #content { background: #eee; margin: 0 200px; } .floated { float: right; width: 180px; height: 100px; background: #dad; }
<div id="left-col">left column</div> <div id="right-col">right column</div> <div id="content"> <h3>Main Content</h3> <p>Lorem ipsum etc..</p> <div class="floated">this a floated box</div> <div class="floated">this a floated box</div> </div>
Wytwarza następujące elementy:
W ogóle to jest w porządku, zwłaszcza jeśli nie mają kolory tła lub wewnętrznych (w głównej zawartości) pływa - Ogłoszenie pływaki są w porządku (jeszcze nie rozliczone) robią to, czego prawdopodobnie oprócz nich , ale oni The
H3
„s top margin ip
dolny margines nie są tak naprawdę zawarte w treści div (jasnoszare tło).Więc do tego samego prostego scenariusza z marginesem powyższego kodu dodaj:
.clear-r {clear: right;}
do CSS i zmień drugie pływające pole HTML na:
<div class="floated clear-r"> this a floated cleared box</div>
Pokaż fragment kodu
#left-col { border: 1px solid #000; width: 180px; float: left; } #right-col { border: 1px solid #000; width: 180px; float: right; height: 200px; } #content { background: #eee; margin: 0 200px; } .floated { float: right; width: 180px; height: 100px; background: #dad; } .clear-r { clear: right; }
<div id="left-col">left column</div> <div id="right-col">right column</div> <div id="content"> <h3>Main Content</h3> <p>Lorem ipsum etc..</p> <div class="floated">this a floated box</div> <div class="floated clear-r">this a floated cleared box</div> </div>
Tym razem otrzymujesz to:
Drugi element pływający oczyszcza prawą stronę, ale oczyszcza całą wysokość prawej kolumny. Prawa kolumna jest wstawiana wcześniej w kodzie źródłowym, więc czyści ją zgodnie z instrukcją! Prawdopodobnie nie jest to jednak pożądany efekt, zwróć też uwagę, że marginesy
h3
ip
są nadal zwinięte (nie są zawarte).Niech ustanowi kontekst formatowania bloków, dla dobra dzieci!
i wreszcie spraw, aby główna kolumna treści wzięła odpowiedzialność - stań się kontekstem formatowania bloku - za jej zawartość: usuń
margin: 0 200px;
z głównej zawartości CSS i ADD,overflow: hidden;
a otrzymasz to:Pokaż fragment kodu
#left-col { border: 1px solid #000; width: 180px; float: left; } #right-col { border: 1px solid #000; width: 180px; float: right; height: 200px; } #content { background: #eee; overflow: hidden; } .floated { float: right; width: 180px; height: 100px; background: #dad; } .clear-r { clear: right; }
<div id="left-col">left column</div> <div id="right-col">right column</div> <div id="content"> <h3>Main Content</h3> <p>Lorem ipsum etc..</p> <div class="floated">this a floated box</div> <div class="floated clear-r">this a floated cleared box</div> </div>
Prawdopodobnie jest to znacznie bardziej podobne do tego, czego można się spodziewać, zwróć uwagę, że teraz elementy zmiennoprzecinkowe są zawarte, usuwają się prawidłowo ignorując prawą kolumnę boczną, a także marginesy
h3
ip
są zawarte zamiast zwiniętego.Przy szerokim użyciu resetowania w dzisiejszych czasach marginesy są mniej zauważalne (a IE nadal ich nie widzi), jednak to, co właśnie stało się z "główną zawartością" centrum, to fakt, że stał się kontekstem formatowania blokowego i jest teraz odpowiedzialny za jego własne elementy podrzędne (potomne). To rzeczywiście bardzo podobny do Microsoft pierwszych dniach pojęciem hasLayout, wykorzystuje te same właściwości
display: inline-block
,float
ioverflow
wszystko inne niż widoczne, i komórki tabeli oczywiście zawsze mają układ .. to jest jednak bez błędów;)Mam nadzieję, że to trochę pomoże, wszelkie pytania nie krępuj się!
Aktualizacja: ponownie więcej informacji:
Kiedy mówisz „ale elementy pływające są ignorowane, gdy klient użytkownika rysuje ramkę i bierze je pod uwagę podczas wypełniania treści”.
Tak, elementy pływające zwykle nakładają się na kontenery. Czy to masz na myśli mówiąc o granicach nadrzędnych? Kiedy element blokowy jest rysowany i zawiera element zmiennoprzecinkowy, sam nadrzędny blok jest rysowany jako prostokąt pod elementem zmiennoprzecinkowym i są to „anonimowe pola w wierszu” lub po prostu „pola liniowe” innych elementów podrzędnych, które są skracane, aby zrobić miejsce na pływak
Weź ten kod:
Pokaż fragment kodu
#content { background: #eee; color #000; border: 3px solid #444; } .float { background: rgba(0, 0, 255, 0.5); border: 1px solid #00f; width: 150px; height: 150px; float: left; margin: 10px; } p { background: #444; color: #fff; }
<div id="content"> <div class="float">floated box</div> <h3>This is a content box</h3> <p>it contains a left floated box, you can see the actual content div does go under the float, but that it is the <h3> and <p> <b>line boxes</b> that are shortened to make room for the float, this is normal behaviour</p> </div>
Który to produkuje:
Widzisz, że element nadrzędny w rzeczywistości nie zawiera elementu zmiennoprzecinkowego, ponieważ nie zawija go w całości .. element zmiennoprzecinkowy po prostu unosi się nad zawartością - jeśli chcesz nadal dodawać zawartość do elementu div, ostatecznie zawinie się pod zmienną, ponieważ nie byłoby już potrzeby, aby (anonimowe) „pola liniowe”
p
elementu się skracały.Pokolorowałem element akapitu, abyś mógł zobaczyć, że on również faktycznie znajduje się pod elementem pływającym, ciemnoszare tło jest miejscem rozpoczęcia akapitu, biały tekst jest miejscem, w którym zaczyna się „anonimowe pole wiersza” - tak naprawdę tylko one „robią miejsce” "dla pływaka, chyba że powiesz inaczej (tj. zmienisz kontekst)
Odnosząc się ponownie do powyższego obrazu, jeśli miałbyś marginesować lewą stronę
p
elementu, tak, zatrzyma to zawijanie tekstu pod spodem pływaka, ponieważ "pola liniowe" (biały tekst) będą dotykać tylko lewej krawędzi ich kontenera i przeniesiesz kolorowe tłop
po prawej stronie, z dala od pływaka, ale nie zmienisz zachowaniap
kontekstu formatowania. Jak środkowa kolumna na pierwszym obrazku powyżej;)źródło
<span>
stanie się on jak poziom bloku<div>
.p
tło przechodzi pod zmienną jest to, że pływające elementy są usuwane z przepływu, ponieważ w sąsiednich elementach naprawdę nie wiedzą, że tam są, i ponieważ należą do tego samego kontekstu formatowania, na któryp
wygląda jest kontenerem nadrzędnym dla jego wymiarów ... (dlatego nie możesz umieścić rzeczy szerokiej na 100% obok pływaka - ponieważ 100% to 100% kontenera. Tylko anonimowe pola w końcu dowiadują się, że pływak tam jest; )