Elementy pływające w div, unosi się na zewnątrz div. Czemu?

274

Powiedz, że masz div, nadaj temu określony widthi umieść w nim elementy, w moim przypadku jeszcze imgjedno div.

Chodzi o to, że zawartość pojemnika divspowoduje jego divrozciągnięcie i będzie tłem dla zawartości. Ale kiedy to robię, zawierające się divkurczą się, aby dopasować się do obiektów nie pływających, a obiekty pływające będą albo całkowicie wysunięte, albo w połowie wysunięte, w połowie, i nie będą miały żadnego wpływu na wielkość dużego div.

Dlaczego to? Czy brakuje mi czegoś i jak mogę uzyskać pływające przedmioty, aby wyciągnęły się heightz zawartości div?

DavidR
źródło

Odpowiedzi:

397

Najłatwiej jest nałożyć overflow:hiddendiv rodzica i nie określać wysokości:

#parent { overflow: hidden }

Innym sposobem jest także przeniesienie div rodzica:

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

Inny sposób wykorzystuje wyraźny element:

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

CSS

span.clear { clear: left; display: block; }
Doug Neiner
źródło
17
Działa, ale teraz jestem dwukrotnie bardziej zdezorientowany: czy istnieje na to wytłumaczenie, czy tak właśnie jest?
DavidR
8
Tak, istnieje wyjaśnienie, ale odtąd zapomniałem :( Tak po prostu jest. overflow:hiddenZmusza przeglądarkę do najlepszego, aby zawierał elementy potomne rodzica. Właśnie dlatego to naprawia.
Doug Neiner
5
Myślę, że wyjaśnienie overflow: hiddenjest tutaj: link . I dzięki bardzo, to zadziałało dla mnie
Vikas Arora
6
@DavidR Najłatwiejszym wyjaśnieniem jest to, że html / css jest przestarzałą, źle przemyślaną i źle zaimplementowaną technologią. W rzeczywistości to rozumowanie tłumaczy wiele dziwactw HTML / CSS, z którymi bez wątpienia się spotkałeś, odkąd napisałeś ten post.
Niewielkie
1
Pamiętaj, że overflow: hiddenpo prostu ukryje każdą część elementu wypływającą z kontenera nadrzędnego. Dla mnie spowodowało to, że niektóre fragmenty tekstu stały się nieczytelne.
Top Cat
160

Powód

Problem polega na tym, że elementy pływające są poza przepływem :

Element jest wywoływany z przepływu, jeśli jest pływający, pozycjonowany absolutnie lub jest elementem głównym.

Dlatego nie wpływają one na otaczające elementy, jak miałby to wpływ element dopływowy .

Jest to wyjaśnione w 9.5 Floats :

Ponieważ liczba zmiennoprzecinkowa nie znajduje się w przepływie, niepozycjonowane pola bloków utworzone przed i za zmiennoprzecinkową pływają pionowo, tak jakby zmiennoprzecinkowa nie istniała. Jednak bieżące i kolejne pola liniowe utworzone obok pływaka są w razie potrzeby skracane, aby zrobić miejsce dla pola marginesu pływaka.

wprowadź opis zdjęcia tutaj

Jest to również określone w 10.6 Obliczanie wysokości i marginesów . Dla „normalnych” klocków ,

Uwzględniane są tylko dzieci w normalnym przepływie (tzn. Pola pływające i pola absolutnie pozycjonowane są ignorowane […])

wprowadź opis zdjęcia tutaj

Hacky rozwiązanie: rozliczenie

Sposobem na rozwiązanie tego problemu jest wymuszenie umieszczenia elementu przepływowego pod wszystkimi pływakami. Następnie wysokość rodzica wzrośnie, aby owinąć ten element (a tym samym również elementy pływające).

Można to osiągnąć za pomocą clearwłaściwości :

Ta właściwość wskazuje, które boki pola elementu nie mogą przylegać do wcześniejszego pola swobodnego.

wprowadź opis zdjęcia tutaj

Rozwiązaniem jest więc dodanie pustego elementu clear: bothjako ostatniego rodzeństwa elementów pływających

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

Nie jest to jednak semantyczne. Lepiej więc wygeneruj pseudoelement na końcu elementu nadrzędnego:

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

Istnieje wiele wariantów tego podejścia, np. Użycie przestarzałej składni pojedynczego dwukropka :afterdo obsługi starych przeglądarek lub użycie innych wyświetlaczy na poziomie bloku, takich jak display: table.

Rozwiązanie: Korzenie BFC

Istnieje wyjątek od problematycznego zachowania zdefiniowanego na początku: jeśli element bloku ustanawia kontekst formatowania bloku (jest katalogiem głównym BFC), wówczas również zawinie swoją swobodną zawartość.

Zgodnie z 10.6.7 wysokości „Auto” dla kontekstowych katalogów formatowania bloku ,

Jeśli element ma pływających potomków, których dolna krawędź marginesu znajduje się poniżej dolnej krawędzi zawartości elementu, wówczas wysokość jest zwiększana, aby uwzględnić te krawędzie.

wprowadź opis zdjęcia tutaj

Dodatkowo, jak wyjaśniono 9.5 Floats , korzenie BFC są również przydatne z następujących powodów:

Obramowanie tabeli, element zastępowany na poziomie bloku lub element w normalnym przepływie, który ustanawia nowy kontekst formatowania bloku […] nie może nakładać się na pole marginesu dowolnych elementów pływających w tym samym kontekście formatowania bloku, co sam element .

wprowadź opis zdjęcia tutaj

Kontekst formatowania bloku jest tworzony przez

  • Blokuj skrzynki overflowinnymi niż visible, nphidden

    .bfc-root {
      overflow: hidden;
      /* display: block; */
    }
  • Blokuj kontenery, które nie są blokami: kiedy displayjest ustawiony na inline-block, table-celllub table-caption.

    .bfc-root {
      display: inline-block;
    }
  • Elementy pływające: kiedy floatjest ustawiony na leftlub right.

    .bfc-root {
      float: left;
    }
  • Elementy absolutnie pozycjonowane: kiedy positionjest ustawiony na absolutelub fixed.

    .bfc-root {
      position: absolute;
    }

Należy pamiętać, że mogą one mieć niepożądane efekty uboczne, takie jak wycinanie przepełnionej zawartości, obliczanie automatycznych szerokości za pomocą algorytmu zmniejszania lub dopasowywanie lub wypływanie. Problem polega na tym, że nie można mieć elementu na poziomie bloku z widocznym przepełnieniem, który ustanawia BFC.

Wyświetlacz L3 rozwiązuje te problemy:

Stworzył flowi wewnętrzne rodzaje wyświetlaczy lepiej wyrazić układ przepływu typów wyświetlaczy oraz stworzenie wyraźnej przełącznik do dokonywania elementu A BFC korzeniowy. (To powinno wyeliminować potrzebę takich hacków i […])flow-root ::after { clear: both; }overflow: hidden

Niestety, nie ma jeszcze obsługi przeglądarki. W końcu możemy być w stanie korzystać

.bfc-root {
  display: flow-root;
}
Oriol
źródło
1
Tak więc pływające pudełka nie są rozpoznawane przez ich kontenery nadrzędne, stąd wysokość załamuje się, ale są rozpoznawane przez ich rodzeństwo, stąd poprawka?
dowiązanie symboliczne
@symlink Tak, kontenery nadrzędne nie rosną, aby zamykać zmiennoprzecinkowe, chyba że są korzeniami BFC. Bloki nie mają bezpośredniego wpływu na rodzeństwo, które nie są korzeniami BFC (ale ich pola liniowe są). Jednak luz przesuwa je poniżej dowolnego poprzedniego pływaka.
Oriol
„Rodzeństwo, które nie są korzeniami BFC, nie mają bezpośredniego wpływu na bloki (ale ich pola liniowe są)”. - Czy możesz to wyjaśnić? Czy masz na myśli, że w tym jsFiddle: jsfiddle.net/aggL3Lk7/2 , pływający obraz liniowy nie wpływa na rozpiętość (stąd ramka rozpiętości go pokrywa), ale obraz wpływa na tekst (który jest polem liniowym), jak pokazano przez fakt, że tekst nie pokrywa obrazu?
dowiązanie symboliczne
1
@symlink Tak, dokładnie. Cóż, w twoim skrzypcach granica należy do rodzica, ale w zasadzie byłaby taka sama dla rodzeństwa: jsfiddle.net/aggL3Lk7/3
Oriol
1
Zgadzam się. To powinna być zaakceptowana odpowiedź. Interesujące jest dla mnie to, że W3 nazywa sposób, w jaki jesteśmy zmuszeni kodować „hack”. Ktoś źle spieprzył.
DR01D,
11

Nic nie brakuje. Float został zaprojektowany dla przypadków, w których obraz (na przykład) ma być umieszczony obok kilku akapitów tekstu, dzięki czemu tekst przepływa wokół obrazu. Nie zdarzyłoby się to, gdyby tekst „rozciągnął” pojemnik. Twój pierwszy akapit skończy się, a następnie następny akapit zacznie się pod obrazem (być może kilkaset pikseli poniżej).

I właśnie dlatego otrzymujesz wynik, którym jesteś.

Lucas Wilson-Richter
źródło
3
Jak to ma coś wspólnego z elementem pływającym odpowiednio rozciągającym wysokość rodzica?
Niewielkie
11

W niektórych przypadkach, np. Gdy (jeśli) używasz tylko floatelementów do przepływu w tej samej „linii”, możesz użyć

display: inline-block;

zamiast

float: left;

W przeciwnym razie użycie clearelementu na końcu działa, nawet jeśli może być sprzeczne z ziarnem, aby potrzebować elementu do tego, co powinno działać CSS.

LSerni
źródło
11

Oto bardziej nowoczesne podejście:

.parent {display: flow-root;} 

Nigdy więcej wyraźnych poprawek.

ps Korzystanie z przelewu: ukryty; ukrywa cień pudełka, więc ...

pendingfox
źródło
Działa również w Safari 11
oczekiwaniu na
7

Dziękuję LSerni , rozwiązałeś to dla mnie.

Osiągnąć to :

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

Musisz to zrobić :

<div style="overflow:auto">
    <div style="display:inline-block;float:left"> Text1 </div>
    <div style="display:inline-block;float:right"> Text2 </div>
</div>
Flyout91
źródło
4

Jak mówi Lucas, opisujesz zamierzone zachowanie właściwości float. Tym, co dezorientuje wiele osób, jest fakt, że float został znacznie przesunięty poza pierwotne zamierzone użycie w celu uzupełnienia braków w modelu układu CSS.

Zajrzyj do Floatutoriala, jeśli chcesz lepiej zrozumieć, jak działa ta właściwość.

Sam Murray-Sutton
źródło
0

Możesz łatwo zrobić to po pierwsze, możesz ustawić div div i zastosować justowanie zawartości w prawo lub w lewo, a problem zostanie rozwiązany.

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

Vijay Tiwari
źródło