Jak działa kontekst formatowania bloków CSS?

80

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

eileen Tao
źródło
Czy możesz dodać obraz, aby udokumentować to, czego nie rozumiesz?
mrk
Wiem, że nie pytałeś wprost o elementy pływające, ale myślę, że ten artykuł jest naprawdę dobry w wyjaśnianiu, jak działa przepływ strony internetowej i może pomóc ci to zrozumieć.
Niklas Wulff

Odpowiedzi:

126

Blokowe konteksty formatowania

Elementy pływające, elementy pozycjonowane bezwzględnie, kontenery blokowe (takie jak bloki śródliniowe, komórki tabel i podpisy tabel), które nie są polami blokowymi, oraz pola blokowe z „przepełnieniem” innym niż „widoczne” (z wyjątkiem sytuacji, gdy ta wartość została propagowana do rzutni) ustalają nowe konteksty formatowania bloków dla ich zawartości.

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) floatlub ... inline-blockitd., 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.

W kontekście formatowania blokowego lewa zewnętrzna krawędź każdego pola dotyka lewej krawędzi zawierającego bloku (w przypadku formatowania od prawej do lewej prawe krawędzie dotykają się)

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:

Ta właściwość wskazuje, które boki ramki elementu mogą nie sąsiadować z wcześniejszą ramką swobodną. Właściwość „clear” nie uwzględnia elementów pływających wewnątrz samego elementu ani w innych kontekstach formatowania bloku

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:

Wytwarza następujące elementy:

wprowadź opis obrazu tutaj

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

Tym razem otrzymujesz to:

wprowadź opis obrazu tutaj

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 h3i psą 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:

wprowadź opis obrazu tutaj

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 h3i psą 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, floati overflowwszystko 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:

Który to produkuje:

jak działają pływaki

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” pelementu 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ę pelementu, 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ło ppo prawej stronie, z dala od pływaka, ale nie zmienisz zachowania pkontekstu formatowania. Jak środkowa kolumna na pierwszym obrazku powyżej;)

clairesuzy
źródło
clairesuzy, bardzo dziękuję! Naprawdę bardzo mi to pomaga, ale wciąż mam kilka pytań. Dodałem to do oryginalnych pytań. Mam nadzieję, że możesz mi pomóc.
eileen Tao
1
@eileen mają miejsce dwie rzeczy - myślę, że twoje dodatkowe pytanie jest wyjaśnione w pierwszym przykładzie .. fioletowe pola pływające pojawiają się po treści, ponieważ tam są w źródle, pływak nie przesuwa się na górę, przejdź powyżej poprzedniego zawartość (ponieważ jej górny margines nie może być wyższy niż tam, gdzie powinien) - lewa i prawa kolumna to również pola pływające, które znajdują się wcześniej w źródle i bez środkowej kolumny, która nie staje się nowym BFC, jeśli spróbujesz wyczyścić fioletowe elementy pływające, usunie również wcześniejsze kolumny pływające po stronie źródła. czy to pomaga?
clairesuzy
1
@eileen to łącze opisuje elementy na poziomie bloku i element na poziomie liniowym, tylko podstawy nie tyle w kontekście formatowania. elementy blokowe zawsze przyjmują 100% szerokości i leżą jeden na drugim (domyślnie) - elementy inline są umieszczone obok siebie, takie jak łącza, przęsła itp., nawet nie przyjmują szerokości ani wysokości, więc nie mają opcji. Element pływający automatycznie staje się elementem na poziomie bloku, więc jeśli umieścisz poziom w wierszu, <span>stanie się on jak poziom bloku <div>.
clairesuzy
1
cd .. powodem, dla którego ptł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óry pwyglą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; )
clairesuzy
1
@clairesuzy - Opublikowane przez Ciebie zdjęcie zostało opublikowane, czy możesz je ponownie opublikować?
bfavaretto