Model kotak CSS agak rumit, terutama dalam hal menggulir konten. Sementara browser menggunakan nilai-nilai dari CSS Anda untuk menggambar kotak, menentukan semua dimensi menggunakan JS tidak lurus jika Anda hanya memiliki CSS.
Itu sebabnya setiap elemen memiliki enam sifat DOM untuk kenyamanan Anda: offsetWidth
, offsetHeight
, clientWidth
, clientHeight
, scrollWidth
dan scrollHeight
. Ini adalah atribut read-only yang mewakili tata letak visual saat ini, dan semuanya adalah integer (sehingga mungkin mengalami kesalahan pembulatan).
Mari kita telusuri secara terperinci:
offsetWidth
, offsetHeight
: Ukuran kotak visual yang mencakup semua batas. Dapat dihitung dengan menambahkan width
/ height
dan paddings dan borders, jika elemen memilikidisplay: block
clientWidth
, clientHeight
: Bagian visual dari konten kotak, tidak termasuk batas atau bilah gulir, tetapi termasuk padding. Tidak dapat dihitung langsung dari CSS, tergantung pada ukuran bilah gulir sistem.
scrollWidth
, scrollHeight
: Ukuran semua konten kotak, termasuk bagian yang saat ini disembunyikan di luar area gulir. Tidak bisa dihitung langsung dari CSS, tergantung kontennya.
Karena offsetWidth
memperhitungkan lebar bilah gulir, kami dapat menggunakannya untuk menghitung lebar bilah gulir melalui rumus
scrollbarWidth = offsetWidth - clientWidth - getComputedStyle().borderLeftWidth - getComputedStyle().borderRightWidth
Sayangnya, kami mungkin mendapatkan kesalahan pembulatan, karena offsetWidth
dan clientWidth
selalu bilangan bulat, sedangkan ukuran sebenarnya mungkin fraksional dengan tingkat zoom selain 1.
Perhatikan bahwa ini
scrollbarWidth = getComputedStyle().width + getComputedStyle().paddingLeft + getComputedStyle().paddingRight - clientWidth
tidak tidak bekerja andal di Chrome, karena Chrome kembali width
dengan scrollbar sudah dikurangi. (Juga, Chrome membuat paddingBottom ke bagian bawah konten gulir, sementara browser lain tidak)
element.getBoundingClientRect()
(lihat catatan di developer.mozilla.org/en-US/docs/Web/API/Element.clientWidth )naturalWidth
dannaturalHeight
scrollHeight
termasukpadding-bottom
tetapiscrollWidth
tidak termasukpadding-right
clientWidth
untukdocument.documentElement.clientWidth
berbeda karena tampaknya untuk menyertakanpadding
,borders
, danmargin
Saya membuat versi yang lebih komprehensif dan lebih bersih yang mungkin berguna bagi beberapa orang untuk mengingat nama mana yang sesuai dengan nilai mana. Saya menggunakan kode warna Chrome Dev Tool dan label disusun secara simetris untuk mengambil analogi lebih cepat:
Catatan 1:
clientLeft
juga termasuk lebar bilah gulir vertikal jika arah teks diatur ke kanan ke kiri (karena bilah ditampilkan ke kiri dalam kasus itu)Catatan 2: garis terluar mewakili induk yang diposisikan terdekat (elemen yang
position
propertinya diatur ke nilai yang berbeda daristatic
atauinitial
). Dengan demikian, jika wadah langsung bukan elemen yang diposisikan , maka garis tidak mewakili wadah pertama dalam hierarki tetapi elemen lain yang lebih tinggi dalam hierarki. Jika tidak ditemukan induk yang diposisikan , browser akan menggunakan elemenhtml
ataubody
sebagai referensiSemoga seseorang menemukan itu berguna, hanya 2 sen saya;)
sumber
Jika Anda ingin menggunakan scrollWidth untuk mendapatkan WIDTH / HEIGHT KONTEN "NYATA" (karena kontennya bisa LEBIH BESAR daripada lebar / tinggi-kotak yang ditentukan css) scrollWidth / Height sangat TIDAK DAPAT DIANDALKAN karena beberapa browser tampaknya "PINDAHKAN" paddingRIGHT & paddingBOTTOM jika kontennya terlalu besar. Mereka kemudian menempatkan bantalan di KANAN / BOTTOM dari "konten terlalu luas / tinggi" (lihat gambar di bawah).
==> Karena itu untuk mendapatkan WIDTH KONTEN NYATA di beberapa browser Anda harus mengurangi KEDUA bantalan dari scrollwidth dan di beberapa browser Anda hanya perlu mengurangi KIRI Padding.
Saya menemukan solusi untuk ini dan ingin menambahkan ini sebagai komentar, tetapi tidak diizinkan. Jadi saya mengambil gambar dan membuatnya sedikit lebih jelas dalam hal "paddings yang dipindahkan" dan "scrollWidth yang tidak dapat diandalkan". Di BIRU AREA Anda menemukan solusi saya tentang cara mendapatkan "KONTEN WIDTH" NYATA!
Semoga ini bisa membantu membuat segalanya lebih jelas!
sumber
Ada artikel bagus tentang MDN yang menjelaskan teori di balik konsep-konsep tersebut: https://developer.mozilla.org/en-US/docs/Web/API/CSS_Object_Model/Determining_the_dimensions_of_elements
Ini juga menjelaskan perbedaan konseptual yang penting antara lebar / tinggi boundingClientRect vs offsetWidth / offsetHeight.
Kemudian, untuk membuktikan teorinya benar atau salah, Anda perlu beberapa tes. Itulah yang saya lakukan di sini: https://github.com/lingtalfi/dimensions-cheatsheet
Ini pengujian untuk chrome53, ff49, safari9, edge13 dan ie11.
Hasil tes membuktikan bahwa teorinya secara umum benar. Untuk pengujian, saya membuat 3 div yang masing-masing berisi 10 paragraf lorem ipsum. Beberapa css diterapkan pada mereka:
Dan inilah hasilnya:
div1
bcr.tinggi: 330 (chrome53, ff49, safari9, edge13, ie11)
clientWidth: 505 (chrome53, ff49, safari9)
clientHeight: 320 (chrome53, ff49, safari9, edge13, ie11)
scrollLebar: 505 (chrome53, safari9, ff49)
div2
clientHeight: 290 (chrome53, ff49, safari9, edge13, ie11)
scrollLebar: 475 (chrome53, safari9, ff49)
div3
clientHeight: 320 (chrome53, ff49, safari9, edge13, ie11)
scrollLebar: 505 (chrome53, safari9, ff49)
Jadi, terlepas dari nilai tinggi boundingClientRect (299,9999694824219, bukan yang diharapkan 300) di edge13 dan ie11, hasilnya mengkonfirmasi bahwa teori di balik ini bekerja.
Dari sini, inilah definisi saya tentang konsep-konsep itu:
Catatan: lebar bilah gulir vertikal default adalah 12px di edge13, 15px di chrome53, ff49 dan safari9, dan 17px di ie11 (dilakukan dengan pengukuran di photoshop dari tangkapan layar, dan terbukti benar dengan hasil pengujian).
Namun, dalam beberapa kasus, mungkin aplikasi Anda tidak menggunakan lebar bilah gulir vertikal bawaan.
Jadi, mengingat definisi konsep-konsep tersebut, lebar bilah gulir vertikal harus sama dengan (dalam kode pseudo):
dimensi tata letak: offsetWidth - clientWidth - (borderLeftWidth + borderRightWidth)
dimensi render: boundingClientRect.width - clientWidth - (borderLeftWidth + borderRightWidth)
Catatan, jika Anda tidak memahami tata letak vs render, harap baca artikel mdn.
Juga, jika Anda memiliki browser lain (atau jika Anda ingin melihat hasil tes sendiri), Anda dapat melihat halaman pengujian saya di sini: http://codepen.io/lingtalfi/pen/BLdBdL
sumber