Z-Indexの実際の仕組み

おそらく、私たちのほぼ全員が少なくとも一度は私たちの生活の中でz-indexプロパティを使用したでしょう。 さらに、各開発者は、それがどのように機能するかを知っていると確信しています。 実際、整数を使用した操作(要素への比較と割り当て)よりも簡単なこともあります。 しかし、すべては一見簡単そうに見えるでしょうか?



おそらく、以下で説明する情報は実際には些細なものです。 しかし、私は多くの人がそれが自分自身にとって有用であると確信していると確信しています。 すでにそれを知っている人は、困難な時にこのテキストをチートシートとして使用することができます。 猫へようこそ。



画像






実際、人は通常、次の3つの場合に自分のために新しい分野を見つけようと試み始めます。 超えて被写体を別の角度から見る必要がある場合; そして最後に、スポーツへの興味がなくなりました。



私のケースは明らかに3番目のカテゴリーに属していません。 最初は、人生で何度か、さまざまなプロジェクトに取り組んでいる最初のシナリオに出くわしました。 しかし、彼は怠と例のある明確で理解可能な資料の不足のために問題を完全に理解していませんでした。 そして、今年の初めに、Webエンジンの作成を開始しました。これにより、標準を読み始め、一般的なブラウザーでさまざまな重要なことをどのように機能させるか 、そして最も重要なこととして、 なぜそのように機能するのを確認し始めました。



簡単なものから始めましょう。 z-indexとは何ですか?



明らかに、これはある要素に対して指定されたZ軸に沿った座標です。 Z軸はユーザーの方向を向いています。 数値が大きいほど、要素が近くなります。



画像



なぜz-indexの数値は整数なのですか? すべてがシンプルです。 範囲は、上部と下部で実質的に無制限なので、小数値を使用する必要はありません。 実際のモニターには3番目の次元がないため(シミュレートすることしかできません)、次元のない数量が必要です。その唯一のタスクは、要素の比較(つまり、セットの順序)を提供することです。 整数は、このタスクの優れた仕事をしますが、実際の整数よりも視覚的です。



この知識は、ページでz-indexの使用を開始するのに十分であると思われます。 ただし、すべてがそれほど単純ではありません。



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





画像



何かが間違っているようです。 最初のz-indexブロックを2番目よりも大きくしたのに、なぜ下に表示されるのですか? はい、それは以前のコードを通過します-しかし、これは等しいz-index値でのみ役割を果たすべきであると思われるでしょう。



この時点で、オーバーレイコンテキストの処理に関して、CSS2.1標準、またはむしろそれに対するアプリケーションを開くときです。 こちらがリンクです。



この小さくて非常に簡潔なテキストから、多くの重要な情報をすぐに抽出できます。



  1. z-indexコントロールは個々の要素ではなくオーバーレイコンテキスト(要素のグループ)をオーバーレイします
  2. 互いに異なるコンテキストの要素を任意に制御することはできません。ここでは階層が機能します。 すでに「低」コンテキストにいる場合、「高」コンテキストの要素の上の要素にすることはできません。
  3. 通常、z-indexは通常のストリーム(positionプロパティが静的である)の要素には意味がありません。 上記の例でこのtrapに陥りました。
  4. 要素が新しいオーバーレイコンテキストを定義するには、配置して、z-indexを割り当てる必要があります。
  5. 要素は配置されているが、z-indexが設定されていない場合、条件付きでゼロに等しいと仮定できます(単純な場合、これはこのように機能します。後でニュアンスを考慮します)。
  6. また、個々のオーバーレイコンテキストは、不透明度値が1未満の要素によって設定されます。 これは、アルファブレンディングをレンダリングの最終段階に簡単に転送して、ビデオカードで処理できるようにするために行われました。


しかし、それだけではありません。 また、z-indexのない要素では、見た目ほど単純ではないことがわかります。



コンテキストサブツリーの要素をレンダリングするプロセスは、いくつかの段階に分けることができます(最初の2つは、コンテキストを設定する現在の要素の背景色と背景画像を直接表示しています)。



したがって、リスト全体を検討してください。



3.負のZインデックスを持つ子コンテキストの派生

4.通常ストリーム内の子ブロック要素の出力(背景のみ)

5.子フロート要素の出力

6.通常のストリームの要素のコンテンツの出力:インラインおよびインラインブロックの子孫、テキストの行を含むブロックの子孫内のインラインコンテンツ*

7.ゼロおよび自動z-index **を持つ子コンテキストの出力

8.正のZインデックスを持つ子コンテキストの派生



*深さ優先ツリーをトラバースするため

** z-index:autoを使用したコンテキストの場合、すべての子コンテキストを現在のコンテキストの子孫と見なします。つまり、現在のレベルまで「プル」します



すでにそれほど簡単ではありませんか? このスキームを次の図で大まかに説明できます。



画像



codepenでサンプルを開いて、自分の手でプレイすることもできます。



しかし、それだけではありません。 アルゴリズムはすでにかなり複雑に思えます:最初に擬似コンテキスト内の子コンテキストをプルアップする必要があります(値autoを覚えていますか?)、次に2つのz-indexリストをソートし、それらを番号シリーズに並べ、次に子要素を通過します:最初にブロックごとに通常のストリームで、次にフローティング、次にインラインおよびインラインブロック...



しかし、ここでは2つの驚きを待っています。 最初は、運が良ければ、私たちには関係ありません。 フレームを含む背景とブロック要素のコンテンツが異なる段階で表示されるという事実に関連していますが、各テキストノードのsamopisnyエンジンが自動的にインライン要素を作成する場合、すべてが正常になり、それらは後で自然に表示されます。



しかし、2番目はそれほど簡単ではありません。 マークされています

これらのそれぞれについて、要素を新しいスタッキングコンテキストを作成したかのように扱いますが、配置された子孫および実際に新しいスタッキングコンテキストを作成する子孫は、この新しいものではなく、親スタッキングコンテキストの一部と見なされる必要があります。


floatおよびinline-block / inline(しかし、ブロックではない!)要素。



これは実際にはどういう意味ですか? これは、z-index:autoを使用した要素と同じ方法で処理する必要があることを意味します。 つまり、まず、サブツリーを回って、そこから子コンテキストを引き出し、それらを現在のレベルに配置します。 ただし、残りの部分については、コンテキストを定義する要素として扱う必要があります。 これは、クロール後に線形リストに引き伸ばされたサブツリー内のすべてのサブツリーがアトミックのままであることを意味します。 または、言い換えると、そのような要素の子孫が親の上に「浮く」ように要素の順序を入れ替えることはできません。 (アルゴリズムが再帰的であるため)子コンテキストの場合、直感的に明確であれば、ここではそうではありません。



したがって、エンジンコードを記述するときは、float、inline、inline-block要素が当面子孫を開かないように自分自身をだます必要があります(オーバーレイコンテキストを形成するポジショニングとz-indexの子を除く)。関数全体は再帰的ですが、逆に、トラバース中に子コンテキストをスキップする必要があるという事実を考慮に入れています。



この現象を示すいくつかの例:



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





画像



ここでは、子にはz-indexがあり、配置されています。 ポップアップは表示されますが、Zインデックスが負の要素はステージ3に、フロート要素はステージ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>
      
      





画像



この例では、2番目の要素(緑)が最初の要素(青)の前に表示されるため、下に表示されます。 ただし、子は(独自のコンテキストを設定するため)プルアップされるため、この場合、元のツリーとまったく同じ順序で移動します(順列の後、祖先の順序は重要ではありません!)。 最初の子を1に等しいz-indexに設定すると、次の図が表示されます。



画像



さらに要素を追加します。



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





画像



ここで、子コンテキストはフロートと通常のブロックの両方から引き出されますが、順序は元のツリーと同じように保持されます。



最後に、最後の例:



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





画像



ご覧のように、ブロック要素の「飛び出し」は、他の場合とは異なり、非常に可能です。また、インラインブロック要素がポップアップしているため、このドキュメントの最後の行に表示されます。



ご覧のとおり、z-indexを使用すると、多くの興味深いトリックを実行できます(少なくとも子の負のz-indexを使用して、直接の親の下に要素を非表示にする価値があります)。 この記事がお役に立てば幸いです。



All Articles