Alasan
Masalahnya adalah bahwa elemen apung tidak mengalir :
Suatu elemen disebut out of flow jika ia melayang, diposisikan secara absolut, atau merupakan elemen root.
Oleh karena itu, mereka tidak mempengaruhi elemen sekitarnya seperti elemen in-flow .
Ini dijelaskan dalam 9.5 Floats :
Karena float tidak ada dalam aliran, kotak blok yang tidak diposisikan dibuat sebelum dan sesudah float box mengalir secara vertikal seolah float tidak ada. Namun, kotak garis saat ini dan selanjutnya yang dibuat di sebelah float dipersingkat seperlunya untuk memberikan ruang bagi kotak margin float.
html {
width: 550px;
border: 1px solid;
}
body {
font-family: sans-serif;
color: rgba(0,0,0,.15);
}
body:after {
content: '';
display: block;
clear: both;
}
div {
position: relative;
}
div:after {
font-size: 200%;
position: absolute;
left: 0;
right: 0;
top: 0;
text-align: center;
}
.block-sibling {
border: 3px solid green;
}
.block-sibling:after {
content: 'Block sibling';
color: green;
}
.float {
float: left;
border: 3px solid red;
height: 90px;
width: 150px;
z-index: 1;
}
.float:after {
content: 'Float';
color: red;
}
<div class="float"></div>
<div class="block-sibling">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor.
</div>
Ini juga ditentukan dalam 10.6 Menghitung ketinggian dan margin . Untuk blok "normal" ,
Hanya anak-anak dalam aliran normal yang diperhitungkan (yaitu, kotak mengambang dan kotak yang diposisikan benar-benar diabaikan [...])
html {
width: 550px;
border: 1px solid;
}
body {
font-family: sans-serif;
color: rgba(0,0,0,.15);
}
body:after {
content: '';
display: block;
clear: both;
}
div {
position: relative;
}
div:after {
font-size: 200%;
position: absolute;
left: 0;
right: 0;
top: 0;
text-align: center;
}
.block-parent {
border: 3px solid blue;
}
.block-parent:after {
content: 'Block parent';
color: blue;
}
.float {
float: left;
border: 3px solid red;
height: 130px;
width: 150px;
}
.float:after {
content: 'Float';
color: red;
}
<div class="block-parent">
<div class="float"></div>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit.
</div>
Solusi peretasan: pembersihan
Cara untuk mengatasi masalah ini adalah dengan memaksa beberapa elemen dalam-aliran ditempatkan di bawah semua pelampung. Kemudian, ketinggian induk akan tumbuh untuk membungkus elemen itu (dan dengan demikian mengapung juga).
Hal ini dapat dicapai dengan menggunakan satu clear
properti :
Properti ini menunjukkan sisi mana dari kotak elemen yang tidak
berdekatan dengan kotak mengambang sebelumnya.
html {
width: 550px;
border: 1px solid;
}
body {
font-family: sans-serif;
color: rgba(0,0,0,.15);
}
body:after {
content: '';
display: block;
clear: both;
}
div {
position: relative;
}
div:after {
font-size: 200%;
position: absolute;
left: 0;
right: 0;
top: 0;
text-align: center;
}
.block-parent {
border: 3px solid blue;
}
.block-parent:after {
content: 'Block parent';
color: blue;
}
.float {
float: left;
border: 3px solid red;
height: 84px;
width: 150px;
}
.float:after {
content: 'Float';
color: red;
}
.clear {
clear: both;
text-align: center;
height: 37px;
border: 3px dashed pink;
}
.clear:after {
position: static;
content: 'Block sibling with clearance';
color: pink;
}
<div class="block-parent">
<div class="float"></div>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra.
<div class="clear"></div>
</div>
Jadi solusinya adalah menambahkan elemen kosong dengan clear: both
sebagai saudara terakhir dari pelampung
<div style="clear: both"></div>
Namun, itu bukan semantik. Jadi lebih baik menghasilkan elemen pseudo di akhir induk:
.clearfix::after {
clear: both;
display: block;
}
Ada beberapa varian dari pendekatan ini, misalnya menggunakan sintaks kolon tunggal yang sudah tidak digunakan lagi :after
untuk mendukung browser lama, atau menggunakan tampilan level blok lainnya seperti display: table
.
Solusi: BFC root
Ada pengecualian untuk perilaku bermasalah yang didefinisikan di awal: jika elemen blok membentuk a Konteks Pemformatan Blok (adalah root BFC), maka ia juga akan membungkus konten apungnya.
Berdasarkan ketinggian 10.6.7 'Otomatis' untuk akar konteks pemformatan blok ,
Jika elemen memiliki keturunan terapung yang tepi margin bawahnya di bawah tepi konten bawah elemen, maka tinggi meningkat untuk menyertakan tepi tersebut.
html {
width: 550px;
border: 1px solid;
}
body {
font-family: sans-serif;
color: rgba(0,0,0,.15);
}
body:after {
content: '';
display: block;
clear: both;
}
div {
position: relative;
}
div:after {
font-size: 200%;
position: absolute;
left: 0;
right: 0;
top: 0;
text-align: center;
}
.block-parent {
border: 3px solid blue;
}
.block-parent.bfc-root:after {
content: 'BFC parent';
color: blue;
}
.float {
float: left;
border: 3px solid red;
height: 127px;
width: 150px;
}
.float:after {
content: 'Float';
color: red;
}
.bfc-root {
overflow: hidden;
}
<div class="block-parent bfc-root">
<div class="float"></div>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit.
</div>
Selain itu, seperti yang dijelaskan 9.5 Mengapung , akar BFC juga berguna karena hal berikut:
Kotak batas tabel, elemen yang diganti level blok, atau elemen dalam aliran normal yang membentuk konteks format blok baru [...] tidak boleh tumpang tindih kotak margin dari pelampung apa pun dalam konteks format blok yang sama dengan elemen itu sendiri .
html {
width: 550px;
border: 1px solid;
}
body {
font-family: sans-serif;
color: rgba(0,0,0,.15);
}
body:after {
content: '';
display: block;
clear: both;
}
div {
position: relative;
}
div:after {
font-size: 200%;
position: absolute;
left: 0;
right: 0;
top: 0;
text-align: center;
}
.block-sibling {
border: 3px solid green;
}
.block-sibling.bfc-root:after {
content: 'BFC sibling';
color: green;
}
.float {
float: left;
border: 3px solid red;
height: 90px;
width: 150px;
z-index: 1;
}
.float:after {
content: 'Float';
color: red;
}
.bfc-root {
overflow: hidden;
}
<div class="float"></div>
<div class="block-sibling bfc-root">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur.
</div>
Konteks pemformatan blok ditetapkan oleh
Memblokir kotak dengan overflow
selain visible
, misalnyahidden
.bfc-root {
overflow: hidden;
/* display: block; */
}
Memblokir kontainer yang bukan kotak blok: kapan display
diatur ke inline-block
, table-cell
atau table-caption
.
.bfc-root {
display: inline-block;
}
Elemen mengambang: kapan float
diatur ke left
atau right
.
.bfc-root {
float: left;
}
Elemen yang benar-benar diposisikan: kapan position
diatur ke absolute
atau fixed
.
.bfc-root {
position: absolute;
}
Perhatikan itu mungkin memiliki efek jaminan yang tidak diinginkan, seperti kliping konten yang meluap, menghitung lebar otomatis dengan algoritma shrink-to-fit , atau menjadi out-of-flow. Jadi masalahnya adalah tidak mungkin untuk memiliki elemen level blok in-flow dengan overflow yang terlihat yang membentuk BFC.
Tampilan L3 mengatasi masalah ini:
Dibuat tipe tampilan dalamflow
dan untuk mengekspresikan tipe tampilan tata letak aliran yang lebih baik dan untuk membuat saklar eksplisit untuk menjadikan elemen sebagai root BFC . (Ini harus menghilangkan kebutuhan untuk hack seperti danflow-root
::after { clear: both; }
overflow: hidden
[...])
Sayangnya, belum ada dukungan browser. Akhirnya kita bisa menggunakan
.bfc-root {
display: flow-root;
}