Mengapa elemen blok-inline ini didorong ke bawah?


238

Berikut ini adalah kode saya dan saya ingin mengerti mengapa #firstDiv didorong ke bawah oleh semua browser. Saya benar-benar ingin memahami cara kerja fakta bahwa mengapa didorong ke bawah daripada menariknya ke atas dengan satu atau lain cara. (dan saya tahu cara menyelaraskan atasan mereka :))

Dan saya tahu bahwa itu meluap: tersembunyi yang menyebabkannya tetapi tidak yakin mengapa itu mendorong div itu ke bawah.

body {
  width: 350px;
  margin: 0px auto;
}

#container {
  border: 15px solid orange;
}

#firstDiv {
  border: 10px solid brown;
  display: inline-block;
  width: 70px;
  overflow: hidden;
}

#secondDiv {
  border: 10px solid skyblue;
  float: left;
  width: 70px;
}

#thirdDiv {
  display: inline-block;
  border: 5px solid yellowgreen;
}
<div id="container">
  <div id="firstDiv">FIRST</div>
  <div id="secondDiv">SECOND</div>
  <div id="thirdDiv">THIRD
    <br>some more content<br> some more content
  </div>
</div>

http://jsfiddle.net/WGCyu/ .

Jawaban:


361

Pada dasarnya Anda telah menambahkan lebih banyak kekacauan dalam kode Anda yang menciptakan lebih banyak kebingungan, jadi pertama-tama saya mencoba untuk menghilangkan kekacauan yang menghalangi memahami masalah sebenarnya.

Pertama-tama kita harus menetapkan bahwa apa pertanyaan sebenarnya? " inline-block" Itu sebabnya elemen didorong ke bawah.

Sekarang kita mulai memahaminya dan menghapus kekacauan dulu.

1 - Mengapa tidak memberikan ketiga lebar perbatasan divs yang sama? Mari kita berikan.

2 - Apakah elemen mengambang memiliki koneksi dengan elemen blok sebaris didorong ke bawah? Tidak, itu tidak ada hubungannya dengan itu.

Jadi, kami telah menghapus div itu sama sekali . Dan Anda menyaksikan perilaku yang sama elemen inline-blok didorong ke bawah.

Di sinilah giliran beberapa literatur untuk memahami ide kotak garis dan bagaimana mereka berbaris dalam baris yang sama khususnya membaca paragraf terakhir dengan hati-hati karena ada jawaban atas pertanyaan Anda.

Garis dasar 'blok sebaris' adalah garis dasar kotak baris terakhir dalam aliran normal, kecuali jika ia tidak memiliki kotak garis dalam-aliran atau jika properti 'luapannya' memiliki nilai yang dihitung selain 'terlihat', di yang mana baseline adalah tepi margin bawah.

Jika Anda tidak yakin tentang garis dasar maka berikut adalah penjelasan singkat dengan kata-kata sederhana.

Semua karakter kecuali 'gjpqy' ditulis pada garis dasar Anda dapat menganggap garis dasar seolah-olah Anda menggambar garis horizontal sederhana yang sama dengan menggarisbawahi tepat di bawah "karakter acak" ini maka itu akan menjadi garis dasar tetapi sekarang jika Anda menulis salah satu dari 'gjpqy' karakter pada baris yang sama maka bagian bawah dari karakter ini akan jatuh di bawah garis.

Jadi, kita dapat mengatakan bahwa semua karakter kecuali 'gjpqy' ditulis sepenuhnya di atas garis dasar sementara beberapa bagian dari karakter ini ditulis di bawah garis dasar.

3 - Mengapa tidak memeriksa di mana garis dasar dari baris kami? Saya telah menambahkan beberapa karakter yang menunjukkan garis dasar dari baris kami.

4 - Mengapa tidak menambahkan beberapa karakter di div kami juga untuk menemukan garis dasar mereka di div? Di sini, beberapa karakter ditambahkan dalam div untuk memperjelas baseline .

Sekarang ketika Anda memahami tentang garis dasar, baca versi sederhana berikut tentang garis dasar blok-inline.

i) Jika inline-block dalam pertanyaan memiliki properti overflow diatur ke terlihat (yang secara default jadi tidak perlu diatur). Kemudian garis dasar akan menjadi garis dasar dari blok yang mengandung garis.

ii) Jika inline-block dalam pertanyaan memiliki properti overflow diatur ke LAIN DARIPADA terlihat. Kemudian margin bawahnya akan berada di garis dasar garis kotak yang berisi.

  • Poin pertama secara detail

Sekarang lihat ini lagi untuk memperjelas konsep Anda bahwa apa yang terjadi dengan green div . Jika ada kerancuan maka di sini ditambahkan lebih banyak karakter yang dekat dengan green div untuk menetapkan garis dasar blok yang berisi dan baseline hijau div diselaraskan.

Nah, saya sekarang mengklaim bahwa mereka memiliki garis dasar yang sama? BAIK?

5 - Lalu mengapa tidak tumpang tindih mereka dan melihat apakah mereka cocok satu sama lain? Jadi, saya membawa div ketiga-kiri: 35px; untuk memeriksa apakah mereka memiliki baseline yang sama sekarang ?

Sekarang, kami telah mendapatkan poin pertama kami terbukti.

  • Poin kedua secara rinci

Nah, setelah penjelasan titik pertama, titik kedua mudah dicerna dan Anda melihat bahwa div pertama yang memiliki properti melimpah diatur selain terlihat (tersembunyi) memiliki margin bawahnya di garis dasar garis.

Sekarang, Anda dapat melakukan beberapa percobaan untuk menggambarkannya lebih lanjut.

  1. Setel overflow div pertama: terlihat (atau hapus semuanya) .
  2. Setel overflow div kedua: selain terlihat .
  3. Atur kedua divs overflow: selain terlihat .

Sekarang bawa kembali kekacauan Anda dan lihat apakah semuanya tampak baik bagi Anda.

  1. Bawa kembali div Anda yang melayang (tentu saja ada kebutuhan untuk
    menambah lebar tubuh). Anda melihatnya tidak berpengaruh.
  2. Bawa kembali margin ganjil yang sama .
  3. Setel div hijau ke overflow: terlihat saat Anda mengatur dalam pertanyaan Anda (misalignment adalah karena peningkatan lebar perbatasan dari 1px ke 5px jadi jika menyesuaikan kiri negatif Anda akan melihat tidak ada masalah)
  4. Sekarang hapus karakter tambahan yang saya tambahkan untuk membantu memahami . (dan tentu saja hapus kiri negatif)
  5. Akhirnya mengurangi lebar tubuh karena kita tidak perlu lagi lebar.

Dan sekarang kita kembali ke tempat kita mulai.

Semoga saya telah menjawab pertanyaan Anda.


1
Terima kasih atas penjelasan yang luar biasa tapi saya tidak mengerti maksud Anda "Maka garis dasarnya akan menjadi garis dasar dari blok yang berisi garis." Apakah sama dengan garis dasar garis seperti yang Anda jelaskan di poin kedua?
Shawn Taylor

2
Respons lambat. Saya hanya mencatat masalah yang sama, dan saya hanya ingin berterima kasih kepada Gary Lindahl untuk penjelasan NICE.
TimSPQR

+1 ntgCleaner Meskipun saya menghargai jawaban yang baik, Gary Lindahl's sangat banyak membaca dan saya hanya kehilangan beberapa baris yang berbunyi 'Solution: XY'
Basic Coder

Saya menemukan penjelasan terperinci ini sangat informatif, terima kasih. Saya berjuang dengan satu konsep untuk sementara waktu, dan telah membuat Fiddle yang diperbarui yang mungkin menjelaskan untuk yang lain.
jonsanders101

@ntgCleaner terima kasih kawan .. bahkan setelah semua penjelasan saya tidak bisa membuatnya bekerja. tetapi komentar Anda berhasil :)
supersan

330

Nilai default untuk vertical-aligndalam CSS adalah baseline& aturan ini juga berlaku dengan inline-blockmembaca ini http://www.brunildo.org/test/inline-block.html

Tulis vertical-align:topdalam inline-blockDIV Anda .

Lihat ini http://jsfiddle.net/WGCyu/1/


3
Sudahkah Anda membaca pertanyaan saya? Saya tidak pernah meminta untuk memperbaiki masalahnya.
Shawn Taylor

23
@ShawnTaylor: Judul pertanyaan sangat menyesatkan. Kami secara naluriah membaca judulnya lalu memotret kodenya, jika ada. Kami jarang membaca teks yang sebenarnya. Ini kebiasaan buruk tetapi Anda mungkin harus mengerti mengapa itu terjadi. : P
Purag

@sandeep: mengenai hasil edit Anda lalu mengapa firstDiv disejajarkan ke atas bahkan ketika penyelarasan vertikal dihapus darinya
Shawn Taylor

@sandeep: Tautan yang Anda berikan informatif, tetapi tidak membantu pertanyaan ini karena tidak menjelaskan perilaku yang display:inline-blockdigabungkan dengan float:left/right.
Zeta

2
@ThomasMcCabe Hampir Tidak; jika seseorang memposting jawaban yang buruk, layak untuk diturunkan untuk memberi sinyal kepada pemirsa di masa depan bahwa ada yang salah dengan itu, terlepas dari niat baik mereka. Yang mengatakan, saya tidak berpikir jawaban ini pantas mendapatkan downvote; bahkan dalam bentuk aslinya, itu memberikan potongan kunci dari teka-teki yang dihilangkan oleh jawaban yang diterima - bahwa penyelarasan garis dasar bukanlah satu-satunya cara elemen-elemen selaras secara vertikal, dan bahwa jika Anda mengubah vertical-alignproperti, tidak ada kompleksitas yang dijelaskan dalam jawaban yang diterima berlaku.
Mark Amery


9

Lihat contoh alternatif ini . Alasan perilaku tersebut dijelaskan dalam modul CSS3: baris: 3.2. Bungkus Kotak Garis [1] :

Secara umum, tepi awal kotak garis menyentuh tepi mulai dari blok yang berisi dan ujung ujung menyentuh tepi ujung dari blok yang mengandungnya. Namun, kotak mengambang mungkin datang di antara tepi blok yang mengandung dan tepi kotak garis. Dengan demikian, meskipun kotak garis dalam konteks format inline yang sama umumnya memiliki kemajuan progres inline yang sama (yaitu blok yang mengandung), mereka dapat bervariasi jika ruang inline-progression yang tersedia berkurang karena mengapung [...]

Seperti yang Anda lihat, elemen ketiga didorong ke bawah, meskipun tidak memiliki overflowproperti. Alasannya pasti ada di tempat lain untuk ditemukan. Perilaku kedua yang Anda perhatikan dijelaskan dalam Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Spesifikasi: 9.5 Floats [2] :

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.

Semua display:inline-block;div Anda menggunakan jenis khusus baselinedalam hal ini 10.8 Perhitungan tinggi baris: properti 'tinggi-garis' dan 'rata-rata-vertikal' (sangat akhir) [3] :

Garis dasar 'blok sebaris' adalah garis dasar kotak baris terakhir dalam aliran normal, kecuali jika ia tidak memiliki kotak garis dalam-aliran atau jika properti 'luapannya' memiliki nilai yang dihitung selain 'terlihat', di yang mana baseline adalah tepi margin bawah.

Jadi ketika Anda menggunakan elemen dan inline-blockelemen mengambang, elemen mengambang akan didorong ke samping dan pemformatan sebaris akan dihitung ulang sesuai dengan 1 . Di sisi lain, elemen-elemen selanjutnya dipersingkat jika tidak cocok. Karena Anda sudah bekerja dengan jumlah ruang minimum, tidak ada cara lain untuk memodifikasi elemen Anda kemudian mendorongnya 2 . Dalam hal ini, elemen tertinggi akan menentukan ukuran div pembungkus Anda, sehingga mendefinisikan baseline 3 , sementara di sisi lain modifikasi posisi dan lebar yang dinyatakan dalam 2 tidak dapat diterapkan pada elemen tinggi minimum spasi minimum tersebut. Dalam hal ini perilaku seperti pada demo pertama saya akan muncul.

Terakhir, alasan Anda overflow:hiddenakan mencegah #firstDivdidorong ke tepi bawah Anda #container, meskipun saya tidak dapat menemukan alasan di bagian 11 . Tanpanya overflow:hiddenberfungsi sebagai dikecualikan dan didefinisikan oleh 2 dan 3 . Demo

TL; DR: Lihat sangat dekat pada rekomendasi W3 dan implementasinya di browser. Menurut pendapat saya yang sederhana elemen mengambang bertekad untuk menunjukkan perilaku yang tidak terduga jika Anda tidak tahu semua perubahan yang terjadi pada elemen di sekitarnya. Berikut ini demo lain yang menunjukkan masalah umum dengan pelampung.


3
"Standar" ini adalah kekacauan yang tidak bisa dipercaya. Sungguh menakjubkan mereka bisa membuat hal ini berperilaku konsistensi di seluruh browser. Oh, tunggu, tidak, mereka tidak pernah bisa melakukan itu.
Triynko

6

Saya awalnya mulai menjawab pertanyaan ini , tetapi dikunci sebagai dupe sebelum saya bisa menyelesaikan, jadi saya mengirim jawabannya di sini.

Pertama, kita perlu memahami apa inline-blockitu.
The definisi dalam MDN mengatakan:

Elemen menghasilkan kotak elemen blok yang akan dialirkan dengan konten di sekitarnya seolah-olah itu adalah kotak inline tunggal (berperilaku seperti elemen yang diganti akan)

Untuk memahami apa yang terjadi di sini, kita perlu melihatnya vertical-align, dan itu adalah nilai default baseline.

visualisasi posisi vertikal
Dalam ilustrasi ini Anda memiliki bagan warna ini:
Biru: Garis dasar
Merah: Bagian atas dan bawah tinggi garis
Hijau: Bagian atas dan bawah kotak konten sebaris.

Di elemen #left, Anda memiliki beberapa konten teks yang mengontrol apa yang menjadi garis dasar. Ini berarti teks di dalamnya menentukan garis dasar untuk #left.
Di # hak, tidak ada konten, sehingga browser tidak memiliki pilihan lain selain menggunakan kotak di bawah sebagai garis dasar.

Lihat visualisasi ini di mana saya telah menggambar garis dasar pada contoh di mana wadah inline pertama memiliki beberapa teks, dan yang berikutnya kosong:

Gambar dasar

Jika Anda secara khusus meluruskan satu elemen ke atas, Anda benar-benar mengatakan bahwa Anda menyelaraskan bagian atas elemen ini ke bagian atas kotak garis.

Ini mungkin lebih mudah dipahami dengan sebuah contoh.

div {
    display: inline-block;
    width: 100px;
    height: 150px;
    background: gray;
    vertical-align: baseline;
}
div#middle {
    vertical-align: top;
    height: 50px
}
   
div#right {
    font-size: 30px;
    height: 100px
}
<div id="left">
  <span>groovy</span>
</div>
<div id="middle">groovy</div>

<div id="right">groovy</div>

Hasilnya adalah ini - dan saya menambahkan garis dasar biru, dan kotak garis merah: Apa yang terjadi di sini, adalah bahwa ketinggian kotak garis tergantung pada bagaimana isi seluruh garis ditata. Ini berarti bahwa untuk menghitung perataan atas, perataan garis dasar harus dihitung terlebih dahulu. The elemen memiliki , jadi ini tidak digunakan untuk posisi dasar. tetapi dan diposisikan secara vertikal sehingga garis dasar mereka sejajar. Ketika ini dilakukan, ketinggian kotak garis telah meningkat, karena elemen telah didorong sedikit karena ukuran font yang lebih besar. Kemudian posisi teratas untuk elemen dapat dihitung, dan ini di sepanjang bagian atas kotak garis.Dijelaskan garis-vertikal
#middlevertical-align:top#left#right#right#middle


1

masalahnya adalah karena Anda telah menerapkan float: left on the div kedua. yang membuat div kedua datang di sisi kiri dan div pertama Anda turun dan datang setelah div kedua Anda. Jika Anda menerapkan float: left on the div pertama juga, masalah Anda akan hilang.

overflow: tersembunyi tidak menyebabkan masalah pada tata letak Anda, overflow: tersembunyi hanya memengaruhi elemen dalam div, itu tidak ada hubungannya dengan elemen lain yang ada di luar.


Nah jika itu didorong karena datang kedua setelah floated div lalu mengapa thirdDiv tidak turun?
Shawn Taylor

karena div ketiga memiliki div kedua sebelum yang tidak mengambang: kiri;
Pal Singh

Tetapi di mana aturan ini menyebutkan bahwa jika beberapa div akan datang setelah floated div maka akan turun ke bawah? Saya memeriksa w3.org.
Shawn Taylor

elemen yang tidak mengambang turun ke baseline dan jika Anda telah melakukan pemungutan suara negatif daripada saya harus mengatakan bahwa itu adalah jawaban yang paling logis
Pal Singh

Tidak, saya tidak memberikan suara negatif dan ya jawaban Anda tidak layak negatif. Cukup memilih ke atas.
Shawn Taylor

0

Coba tambahkan padding:0;ke badan dan hapus margin div Anda.

Tambahkan background-color:*anywarna selain dari latar belakang * untuk memeriksa perbedaannya.


Edit jawaban untuk memformat kode, Anda dapat memformat kode dengan menambahkan simbol `sebelum memulai kode dan setelah mengakhiri kode. sebagai codecontoh:. background-color:any color
JINO SHAJI

0

Coba buat semua properti CSS dari semua Elemen sama.

Saya memiliki masalah yang sama dan ketika memperbaiki ini saya mengidentifikasi bahwa saya menjatuhkan sebuah Elemen dengan properti Font ke dalam Elemen Div.

Setelah menjatuhkan Elemen itu dengan properti Font keselarasan semua DIV terganggu. Untuk memperbaiki ini, saya mengatur properti Font ke semua elemen DIV sama dengan elemen yang dimasukkan ke dalamnya.

Dalam contoh berikut ini, elemen Dropped kelas ".dldCuboidButton" didefinisikan dengan ukuran font: 30 px.

Jadi saya menambahkan properti yang sama ke kelas yang tersisa yaitu .cuboidRecycle, .liCollect, .dldCollect yang digunakan oleh elemen DIV. Dengan cara itu semua elemen DIV mengikuti Pengukuran yang sama sebelum dan sesudah menjatuhkan elemen ke dalamnya.

.cuboidRecycle {
    height:40px; 
    width:'20px; float:right';
    overflow:'none';
    background-color:#cab287;
    color:#ffffff; 
    border-radius:8px; 
    text-align:'center'; 
    vertical-align:'top';
    display: inline-block;
    font-size: 30px; /* Set a font-size */
}


.liCollect {
    height:40px; 
    width:'20px; float:right';
    overflow:'none';
    background-color:#cab287;
    color:#ffffff; 
    border-radius:8px; 
    text-align:'center'; 
    vertical-align:'top';
    display: inline-block;
    font-size: 30px; /* Set a font-size */
}

.dldCollect {
    height:40px; 
    width:'20px; float:right';
    overflow:'none';
    background-color:#009933;
    color:#ffffff; 
    border-radius:8px; 
    text-align:'center'; 
    vertical-align:'top';
    display: inline-block;
    font-size: 30px; /* Set a font-size */
}


.dldCuboidButton {
    background-color:  #7c6436;
    color: white; /* White text */
    font-size: 30px; /* Set a font-size */
    border-radius: 8px;
    margin-top: 1px;
  }

Berikut adalah contoh HTML yang dibuat secara dinamis menggunakan CSS di atas.

$("div#tabs").append(
  "<div id='" + newTabId + "'>#" + uniqueId + 
  "<input type=hidden id=hdn_tmsource_" + uniqueId + "  value='" + divTmpfest + "'>" + 
  "<input type=hidden id=leCuboidInfo_" + uniqueId + " value=''>" + 
  "<div id='" + divRecycleCuboid + "' class=cuboidRecycle ondrop='removeDraggedCuboids(event, ui)'  ondragover='allowDrop(event)'><font size='1' color='red'> Trash bin </font></div>" +
  "<div id='" + divDropLeCuboid  + "' class=liCollect ondrop='dropForLinkExport(event)'  ondragover='allowDrop(event)'><font size='1' color='red'>Drop Template Manifest Cuboid here</font></div>" +
  "<div id='" + divDropDwldCuboid  + "' class=dldCollect ondrop='dropForTMEntry(event)'  ondragover='allowDrop(event)'><font size='1' color='red'>Drop Template Cuboids here..</font></div>" +
  "</div>" 
);
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.