Bagaimana z-index sebenarnya bekerja

Mungkin hampir setiap dari kita setidaknya sekali dalam hidup kita menggunakan properti z-index. Selain itu, setiap pengembang yakin bahwa ia tahu cara kerjanya. Bahkan, apa yang bisa lebih sederhana daripada operasi dengan bilangan bulat (membandingkan dan menugaskan mereka ke elemen). Tapi apakah semuanya sesederhana seperti yang terlihat pada pandangan pertama?

Mungkin informasi yang akan saya bahas di bawah ini sebenarnya sepele. Namun, saya yakin banyak orang akan merasakan manfaatnya bagi diri mereka sendiri. Mereka yang sudah tahu tentang hal itu akan dapat menggunakan teks ini sebagai lembar contekan di masa-masa sulit. Jadi selamat datang di kucing.

gambar

Bahkan, seseorang biasanya mulai mencoba mencari bidang baru untuk dirinya sendiri dalam tiga kasus: jika ia memenuhi hasil yang tidak terduga di tempat kerja dan tidak mengerti apa yang terjadi; jika ada kebutuhan untuk melampaui dan melihat subjek dari sudut yang berbeda; dan akhirnya, hanya karena minat olahraga.

Kasus saya jelas bukan milik kategori ketiga. Pada awalnya, beberapa kali dalam hidup saya, saya menemukan skenario pertama ketika mengerjakan berbagai proyek; namun, dia tidak sepenuhnya memahami masalah ini karena malas dan kurangnya bahan yang jelas dan dapat dipahami dengan contoh-contoh. Dan kemudian pada awal tahun ini saya mulai menulis mesin web, yang membuat saya mulai membaca standar dan umumnya melihat bagaimana berbagai hal non-sepele bekerja di browser populer, dan yang paling penting, mengapa mereka bekerja seperti itu.

Mari kita mulai dengan yang sederhana. Apa itu z-index dan untuk apa?

Jelas, ini adalah koordinat sepanjang sumbu Z, ditentukan untuk beberapa elemen. Sumbu Z diarahkan ke pengguna. Jumlah yang lebih besar adalah elemen yang lebih dekat.

gambar

Mengapa angka indeks-z bilangan bulat? Semuanya sederhana. Rentang ini praktis tidak terbatas di bagian atas dan bawah, jadi kita tidak perlu menggunakan nilai fraksional. Karena monitor sebenarnya tidak memiliki dimensi ketiga (kami hanya dapat mensimulasikannya), kami memerlukan kuantitas tanpa dimensi, satu-satunya tugasnya adalah memberikan perbandingan elemen (yaitu, pemesanan set). Integer melakukan pekerjaan yang sangat baik dari tugas ini, sementara mereka lebih visual daripada yang nyata.

Tampaknya pengetahuan ini cukup untuk mulai menggunakan indeks-z pada halaman. Namun, tidak semuanya begitu sederhana.

<div style="background: #b3ecf9; z-index: 1"></div> <div style="background: #b3ecb3; margin-top: -86px; margin-left: 38px; z-index: 0"></div> 

gambar

Sepertinya ada yang salah. Kami membuat blok pertama z-indeks lebih dari yang kedua, jadi mengapa itu ditampilkan di bawah ini? Ya, kode ini sudah ada sebelumnya - tetapi tampaknya ini seharusnya hanya berperan dengan nilai indeks-z yang sama.

Pada titik ini, saatnya untuk membuka standar CSS2.1, atau lebih tepatnya aplikasi untuk itu, mengenai pemrosesan konteks overlay. Inilah tautannya .

Dari teks kecil dan sangat ringkas ini Anda dapat langsung mengekstraksi banyak informasi penting.

  1. overlay kontrol indeks-z bukan atas elemen individual, tetapi konteks overlay (grup elemen)
  2. Kami tidak dapat secara sewenang-wenang mengontrol elemen-elemen dalam konteks yang berbeda relatif satu sama lain: di sini hierarki berfungsi. Jika kita sudah berada dalam konteks "rendah", maka kita tidak dapat menjadikannya elemen di atas elemen konteks "lebih tinggi".
  3. z-index sama sekali tidak masuk akal untuk elemen-elemen dalam aliran normal (dimana properti posisi statis). Kami jatuh ke dalam perangkap ini dalam contoh di atas.
  4. Agar elemen dapat mendefinisikan konteks overlay baru, elemen harus diposisikan dan harus diberi indeks-z.
  5. Jika elemen diposisikan, tetapi indeks-z tidak disetel, maka kita dapat mengasumsikan secara kondisional bahwa itu sama dengan nol (untuk kasus sederhana ini berfungsi seperti ini, kami akan mempertimbangkan nuansa nanti).
  6. Dan konteks overlay individual ditetapkan oleh elemen dengan nilai opacity kurang dari satu. Ini dilakukan agar Anda dapat dengan mudah mentransfer alpha blending ke tahap terakhir rendering untuk diproses oleh kartu video.

Tapi itu belum semuanya. Ternyata dengan elemen tanpa indeks-z juga tidak sesederhana kelihatannya.

Proses rendering elemen subtree konteks dapat dibagi menjadi beberapa tahap (dua yang pertama secara langsung menghasilkan warna latar belakang dan gambar latar belakang elemen saat ini yang mengatur konteks).

Jadi, pertimbangkan seluruh daftar.

3. Penurunan konteks anak dengan z-indeks negatif
4. Output elemen blok anak dalam aliran normal (hanya latar belakang)
5. Output elemen float anak
6. Keluaran konten elemen dalam aliran normal: keturunan inline dan inline-blok, konten inline di dalam turunan blok, termasuk baris teks *
7. Output dari konteks anak dengan nol dan indeks z otomatis **
8. Penurunan konteks anak dengan z-index positif

* untuk melintasi pohon kedalaman-pertama
** untuk konteks dengan z-index: otomatis, anggap semua konteks anak sebagai turunan dari konteks saat ini, yaitu, "tarik" mereka ke level saat ini

Sudah tidak mudah, bukan? Anda dapat secara kasar menggambarkan skema ini dengan gambar berikut:

gambar

Dimungkinkan juga untuk membuka contoh pada codepen dan memainkannya dengan tangan Anda sendiri.

Tapi itu belum semuanya. Tampaknya algoritme sudah cukup rumit: kita harus terlebih dahulu menarik konteks anak di dalam konteks semu (ingat nilainya otomatis?), Lalu mengurutkan untuk dua daftar indeks-z, mengaturnya dalam serangkaian angka, kemudian melalui anak-anak: pertama, blok dalam aliran normal, lalu mengambang, lalu sebaris dan sebaris-blok ...

Tapi di sini kita menunggu dua kejutan. Yang pertama, dengan keberuntungan, tidak akan menjadi perhatian kita. Hal ini terhubung dengan fakta bahwa latar belakang dengan bingkai dan isi elemen blok ditampilkan pada tahapan yang berbeda - tetapi jika mesin yang kami buat sendiri untuk setiap node teks menciptakan elemen inline otomatis, maka semuanya akan beres, semuanya akan ditampilkan secara alami nanti.

Tapi yang kedua tidak begitu sepele. Itu ditandai
Untuk masing-masing dari ini, perlakukan elemen seolah-olah itu menciptakan konteks susun baru, tetapi setiap keturunan diposisikan dan keturunan yang benar-benar membuat konteks susun baru harus dianggap sebagai bagian dari konteks susun induk, bukan yang baru ini.

elemen float dan inline-block / inline (tetapi tidak menghalangi!).

Apa artinya ini dalam praktik? Dan ini berarti bahwa kita harus memprosesnya dengan cara yang sama seperti elemen dengan z-index: auto. Artinya, pertama-tama, berkeliling di sekitar anak pohon mereka dan menarik keluar konteks anak dari sana, menempatkan mereka pada level saat ini. Tetapi untuk yang lain, kita harus memperlakukan mereka sebagai elemen yang mendefinisikan konteks kita. Ini berarti bahwa semua subtree di dalamnya, membentang setelah merangkak ke daftar linear, harus tetap atom. Atau, dengan kata lain, kita tidak dapat mengocok urutan elemen sehingga keturunan dari elemen seperti itu "mengambang" di atas induknya. Dan jika untuk konteks anak jelas secara intuitif (karena algoritme bersifat rekursif), maka di sini tidak demikian.

Oleh karena itu, ketika menulis kode mesin, kita harus menipu diri kita sendiri sehingga elemen float, inline, dan inline-block tidak untuk saat ini mengungkapkan turunannya (dengan pengecualian anak-anak dengan positioning dan z-index, yang membentuk konteks overlay), dan kemudian berlari untuk mereka seluruh fungsi bersifat rekursif, tetapi sebaliknya, dengan mempertimbangkan fakta bahwa konteks anak harus dilewati selama traversal.

Beberapa contoh untuk menunjukkan fenomena ini:

 <div style="float: left; background: #b3ecf9;"> <div style="width: 40px; height: 40px; background: #fff700; position: relative; z-index: -1; top: -20px; left: -20px;"></div> </div> 

gambar

Di sini anak memiliki indeks-z dan diposisikan. Itu muncul, tetapi ditampilkan di bawah kotak biru, karena elemen dengan indeks z negatif ditampilkan di tahap 3, dan elemen mengapung di tahap 5.

 <div style="float: left; margin-top: -30px; background: #b3ecf9;"> <div style="width: 40px; height: 40px; background: #fff700; position: relative; z-index: 0;"></div> </div> <div style="background: #b3ecb3; margin-top: 52px; margin-left: 38px;"> <div style="width: 40px; height: 40px; background: #ff0000; position: relative; z-index: 0;"></div> </div> 

gambar

Dalam contoh ini, elemen kedua (hijau) ditampilkan sebelum yang pertama (biru), dan karenanya di bawah ini. Namun, anak-anak ditarik (karena mereka mengatur konteks mereka sendiri), jadi dalam hal ini mereka pergi dalam urutan yang sama di mana mereka pergi tepat di pohon asli (urutan leluhur mereka tidak penting setelah permutasi!). Jika kita menetapkan anak pertama ke indeks-z sama dengan 1, maka kita mendapatkan gambar berikut:

gambar

Tambahkan lebih banyak elemen.

 <div style="float: left; background: #b3ecf9;"> <div style="float: left"> <div style="width: 40px; height: 40px; background: #fff700; position: relative; z-index: 0;"></div> </div> </div> <div style=" background: #b3ecb3; margin-top: 32px; margin-left: 40px;"> <div style="position: relative"> <div style="width: 40px; height: 40px; background: #ff0000; position: relative; z-index: 0;"></div> </div> </div> 

gambar

Di sini, konteks anak ditarik dari kedua pelampung dan balok biasa, sementara urutannya dipertahankan seperti di pohon aslinya.

Akhirnya, contoh terakhir:

 <div style="background: #b3ecf9;"> <div style="display: inline-block; width: 40px; height: 40px; background: #fc0;"></div> </div> <div style="background: #b3ecb3; margin-top: -100px; margin-left: 22px;"></div> 

gambar

Seperti yang Anda lihat, "melompat" dari elemen blok, berbeda dengan kasus lain, sangat mungkin, dan karena kita memiliki elemen inline-blok yang muncul, itu akan menjadi yang terakhir dalam dokumen ini.

Seperti yang Anda lihat, indeks-z memungkinkan Anda melakukan banyak trik menarik (yang bernilai setidaknya menyembunyikan elemen di bawah induk langsungnya menggunakan indeks-z negatif pada anak). Saya harap artikel ini bermanfaat bagi Anda.

Source: https://habr.com/ru/post/id431046/


All Articles