この世界では、すべてに順序があり、すべてに年功序列があります。たとえば、食堂で食べ物を買うために列に並ばなければならないとします。それは先着順なので、一度に殺到することはできません。もう一つの例は、妻の言葉は常に正しく、上司の言葉は常に正しいです。
CSS の世界でも同じことが当てはまります。しかし、通常の状態では、誰もが平和に歌い踊り、差は見られず、いわゆるすべての生き物の平等です。しかし、衝突やもつれが生じた場合、完全な同等性を達成することが不可能であることは明らかであり、アイデンティティの差異が順番に現れます。たとえば、ジャックとローズは単独でボード上に浮かぶことしかできません。このとき、衝突が発生し、その結果は誰もが知っています。では、CSSの世界における要素にとって、いわゆる「競合」とは何を意味するのでしょうか?その中でも非常に重要な要素が「カスケード表示の競合」です。
デフォルトでは、Web コンテンツはオフセット角度なしで垂直に表示されます。コンテンツを積み重ねる場合、前から後ろへの積み重ね順序が必要になります。これは、現実世界の年功序列の感覚に似ています。
Web ページ内の要素がどのように「年功序列」でランク付けされるかを理解するには、CSS のカスケード コンテキストとカスケード順序を深く理解する必要があります。
CSS の z-index プロパティについては皆さんよくご存じかと思いますが、ここでお伝えしなければならないのは、z-index は実際には CSS のスタック コンテキストおよびスタック順序における小さなボートにすぎないということです。
スタッキングコンテキストは英語で「スタッキングコンテキスト」と呼ばれ、HTMLにおける三次元の概念です。要素にカスケード コンテキストが含まれている場合、この要素が Z 軸上で「優れている」ことがわかります。
ここに z 軸 という名詞があります。これは何を指しますか?
は、ユーザーと画面の間の目に見えない垂直線を表します (下の図を参照 - 赤い線):
カスケード コンテキストは、「ブロック」に似た概念です。 BFC フォーマット コンテキスト (BFC) に似ています。ただし、概念は比較的架空で抽象的なので、それを簡単に理解するには、視覚化する必要があります。
具体的にはどのような方法でしょうか?
「カスケード コンテキスト」を公式として 理解できます : Web ページには、現実世界のすべての生き物と考えることができる要素が多数あります。現実の世界では、私たちのほとんどは一般人であり、役人もいます。ここでの「公式」は、Web ページ内のカスケード状のコンテキスト要素として理解できます。
つまり、私たち一般人が役人になるのと同じように、ページ上の要素は役人になると一般人よりも天皇に近づくのと同じですよね。 Web ページ内の要素のレベルをユーザーに近づけます。
スタッキング レベルについて話しましょう。 「積み重ねレベル」は英語では「stacking level」といい、同じ積み重ねコンテキスト内の要素のz軸上の表示順序を決定します。レベルという言葉は、現実世界における 3 つ、6 つ、または 9 つのレベルと年功序列を簡単に思い出させます。現実の世界では、一卵性双生児も含めて、誰もが独立した個人です。違いがあるところには違いがあります。たとえば、双子は Ctrl+C/Ctrl+V で得られるもののように見えますが、実際には、生まれた時間の順序があり、先に生まれた方が年上の、長兄または長姉になります。 Web ページ内の要素にも同様のことが当てはまり、ページ内の各要素は独立したものであり、同様のランキングを持つ必要があります。そして、このランキングと年功序列は、ここでは「カスケード レベル」と呼ばれるものです。カスケード コンテキスト要素のカスケード レベルは、通常の要素の場合は役人の階級、1 級と 2 級、郡判事、知事などとして理解できます。これは自分で理解できます。
したがって、カスケード コンテキスト要素を含むすべての要素にカスケード レベルがあることは明らかです。カスケード コンテキスト要素のカスケード レベルは、役人の階級、1 級、2 級、郡判事、知事などとして理解できます。 。次に、通常の要素のスタッキング レベルについては、現在のスタッキング コンテキスト要素に限定して説明します。なぜ?そうしないと意味がないからです。
このように理解しましょう~ 上で述べたように、重複する文脈を持つ要素は役人であることに似ています。誰もが知っているように、役人の家族にはメイド、ボディガード、家政婦などがいます。主人次第とはよく言ったもので、役人Aの家の家政婦と役人Bの家の家政婦を競うことは実は無意味で、スゴイかどうかは完全に主人が決めるのです。一人の人でも悟りを開くことができ、鶏や犬は天国に昇ることができます。ヘシェンの家の家政婦は、鹿下町のロウジ県の判事の家の家政婦に匹敵すると思いますか。リー首相の秘書は、あなたの村の支部の秘書(もしいたとしたら)の秘書を数分で殺害しましたか?
言い換えると、通常の要素のスタッキング レベルは最初にスタッキング コンテキストによって決定されます。したがって、スタッキング レベルの比較は現在のスタッキング コンテキスト要素内でのみ意味を持ちます。
スタッキング レベルと CSS の z-index プロパティを混同しないように注意してください。確かに、z-index は場合によってはスタッキング レベルに影響を与える可能性がありますが、スタッキング レベルのすべての要素が存在する場合、それは位置決めされた要素とフレックス ボックスの子要素にのみ限定されます。
スタッキングシーケンスについて説明します。 「重なり順」は英語で「stacking order」といい、要素を積み重ねる際に特定の垂直方向の表示順序を持つことを意味します。上記の 重なりコンテキストと重なりレベルは概念です。 。ここでの の重ね順は です。
CSS3 が登場する前の CSS2.1 の時代には (ここでの前提に注意してください)、カスケード順序ルールは以下の図に従っていました:
誰か見たことがあるかもしれません似たような絵は何年も前に外国人によって描かれました。内容は英語です。しかし、もっと重要なことは、国内の同業他社がそれを検証し実践していないことが推定されていることです。実際、多くの重要な情報が欠落しています。上記は中国語版であり、私が手動で再描画し、他では絶対に入手できない多くの重要な知識と情報を追加しました。透かしのない大きな高解像度の写真が必要な場合は、ここをクリックして購入してください (0.5 元)。
重要な欠落情報は次のとおりです。
ここで質問したいのですが、なぜインライン要素の重なり順がフローティング要素やブロック要素よりも高いのか考えたことはありますか?
なぜですか?フローティング要素とブロック要素の方が明らかに扱いにくいと感じます。
あまりうるさく言うつもりはありませんが、下の図の注釈を見てください:
境界線や背景などは通常、装飾的な属性です。 while フローティング要素とブロック要素 通常、レイアウトに使用されますが、インライン要素はコンテンツです。 Web ページで最も重要なことは何ですか?もちろん内容ですよね?
したがって、コンテンツのスタック順序をかなり高く保つようにして、スタックが発生する場合は、重要なテキストと画像コンテンツが最初に画面に表示されるようにするのが良いでしょう。たとえば、テキストとフローティング画像が重なっている場合:
上記の重なり順ルールはまだ古いものですが、CSS3 も関与すると、状況は異なります。
ラミネートの分野における黄金律は次の 2 つです。要素がカスケードされる場合、そのカバレッジ関係は次の 2 つの基準に従います:
CSS と HTML の分野では、要素が重なる限り、上記 2 つの黄金律は切り離すことができません。後で複数の例が出てくるので、ここでやめておきます。
カスケードコンテキスト要素には次のような特徴があります。
を現実世界の言語に翻訳すると、次のようになります:
ははは。ブロック書式設定コンテキストと同様に、カスケード コンテキストは基本的に、いくつかの特定の CSS プロパティを使用して作成されます。それを3つの流派、つまり役人になるための3つの方法にまとめました:
①. ルート カスケード コンテキスト
は、スクロール バーのデフォルトの作成元である 要素を指します。このため、絶対に配置される要素が左/上などに配置される場合、他の配置要素の制限がない場合、それらはブラウザ ウィンドウを基準にして配置されます。
②. 位置決め要素と従来のカスケードコンテキスト
Position:relative / Position:absolute を含む位置決め要素、および FireFox/IE ブラウザ用 (Chrome を除く) Webkit カーネル ブラウザー (現在、つまり 2016 年初頭) でposition:fixed 宣言が含まれている場合、その z-index 値が auto ではない場合、カスケード コンテキストが作成されます。
これを知ると、いくつかの現象が理解しやすくなります。
次の HTML コード:
<div style="position:relative; z-index:auto;"> <img src="mm1.jpg" style="position:absolute; z-index:2;"> <-- 横妹子 --></div><div style="position:relative; z-index:auto;"> <img src="mm2.jpg" style="position:relative; z-index:1;"> <-- 竖妹子 --></div>
縦の女の子 (mm2) が横の女の子 (mm1) に与えられていることがわかります。 )カバーされています。
次に、親を調整し、同じカスケード レベルで z-index:auto を z-index:0 に変更します。コードは次のとおりです。
<div style="position:relative; z-index:0;"> <img src="mm1.jpg" style="position:absolute; z-index:2;"> <-- 横妹子 --></div><div style="position:relative; z-index:0;"> <img src="mm2.jpg" style="position:relative; z-index:1;"> <-- 竖妹子 --></div>
誰もが、状況が逆転して、今度は直立した女の子 (mm2) が水平な女の子 (mm1) の上に横たわっていることに気づくでしょう。
なぜ小さな変化がアイデアに影響を与えるのでしょうか?
違いは、z-index:0 が配置されている
「年上の人が先に行く」という原則に従って、z-index 2 の水平方向の女の子が z-index 1 の垂直方向の女の子の上に横たわりました。 z-index が数値 (0 であっても) になると、スタッキング コンテキストが作成されます。この時点で、カスケード ルールが変更されます。カスケード コンテキストの最後の機能は自己完結型です。 2 人の 女の子の重なり順の比較は、親の重なりコンテキスト要素の重なり順の優先比較になります。ここで、両方とも z-index:0 であるため、スタック順序は両方と同じサイズになります。このとき、スタックの黄金律のもう 1 つの基準は、「
最後のもの」に従います。 DOMフローでの位置 誰が上になるか決まっているので、当然後ろの直立の女の子が横の女の子の上に乗ります。はい、そうです。 要素の z-index は機能しています。 Web ページを再構築すると、z-index のネストが親のカスケード コンテキスト要素によって妨げられているかどうかを確認してみましょう。それから、あまり意味がないかもしれませんが、トリビュートとして、IE6/IE7 ブラウザーにはバグがあることについて言及しておきます。つまり、z-index:auto の位置決め要素もカスケード コンテキストを作成します。これが、IE6/IE7 の z-index が過去に人々を殺した理由です。
次に、position:fixed についてもう一度触れておきます。以前は、position:fixed と相対/絶対はスタッキング コンテキストでは同じものであり、どちらも z-index が数値である必要がありました。ただし、Chrome などの Webkit ベースのブラウザーで、z-index が数値である必要がなく、position:fixed 要素がコンテキスト要素を自然にカスケードするようになったのはいつ頃からかわかりません。私のテストによると、現時点では IE と FireFox はまだ古いままです。
③ CSS3 とカスケードコンテキストの新時代
CSS3的出现除了带来了新属性,同时还对过去的很多规则发出了挑战。例如,CSS3 transform 对overflow隐藏对position:fixed定位的影响 等。而这里,层叠上下文这一块的影响要更加广泛与显著。
如下:
基本上每一项都有很多槽点。
1. display:flex|inline-flex与层叠上下文
注意,这里的规则有些负责。要满足两个条件才能形成层叠上下文:条件1是父级需要是 display:flex 或者 display:inline-flex 水平,条件2是子元素的z-index不是 auto ,必须是数值。此时,这个子元素为层叠上下文元素,没错,注意了,是子元素,不是flex父级元素。
眼见为实,给大家上例子吧。
如下HTML和CSS代码:
<div class="box"> <div> <img src="mm1.jpg"> </div></div>
.box { }.box > div { background-color: blue; z-index: 1; } /* 此时该div是普通元素,z-index无效 */.box > div > img { position: relative; z-index: -1; right: -150px; /* 注意这里是负值z-index */}
结果如下:
会发现,妹子跑到蓝色背景的下面了。为什么呢?层叠顺序图可以找到答案,如下:
从上图可以看出负值z-index的层叠顺序在block水平元素的下面,而蓝色背景 div 元素是个普通元素,因此,妹子直接穿越过去,在蓝色背景后面的显示了。
现在,我们CSS微调下,增加 display:flex , 如下:
.box { display: flex; }.box > div { background-color: blue; z-index: 1; } /* 此时该div是层叠上下文元素,同时z-index生效 */.box > div > img { position: relative; z-index: -1; right: -150px; /* 注意这里是负值z-index */}
结果:
会发现,妹子在蓝色背景上面显示了,为什么呢?层叠顺序图可以找到答案,如下:
从上图可以看出负值 z-index 的层叠顺序在当前第一个父层叠上下文元素的上面,而此时,那个 z-index 值为 1 的蓝色背景
另外,另外,这个例子也颠覆了我们传统的对 z-index 的理解。在CSS2.1时代, z-index 属性必须和定位元素一起使用才有作用,但是,在CSS3的世界里,非定位元素也能和 z-index 愉快地搞基。
2. opacity与层叠上下文
我们直接看代码,原理和上面例子一样,就不解释了。
如下HTML和CSS代码:
<div class="box"> <img src="mm1.jpg"></div>
.box { background-color: blue; }.box > img { position: relative; z-index: -1; right: -150px;}
结果如下:
然后价格透明度,例如50%透明:
.box { background-color: blue; opacity: 0.5; }.box > img { position: relative; z-index: -1; right: -150px;}
结果如下:
原因就是半透明元素具有层叠上下文,妹子图片的 z-index:-1 无法穿透,于是,在蓝色背景上面乖乖显示了。
3. transform与层叠上下文
应用了transform变换的元素同样具有菜单上下文。
我们直接看应用后的结果,如下CSS代码:
.box { background-color: blue; transform: rotate(15deg); }.box > img { position: relative; z-index: -1; right: -150px;}
结果如下:
妹子同样在蓝色背景之上。
4. mix-blend-mode与层叠上下文
mix-blend-mode 类似于PS中的混合模式,之前专门有文章介绍-“ CSS3混合模式mix-blend-mode简介 ”。
元素和白色背景混合。无论哪种模式,要么全白,要么没有任何变化。为了让大家有直观感受,因此,下面例子我特意加了个原创平铺背景:
.box { background-color: blue; mix-blend-mode: darken; }.box > img { position: relative; z-index: -1; right: -150px;}
结果如下:
需要注意的是,目前,IE浏览器(包括IE14)还不支持 mix-blend-mode ,因此,要想看到妹子在背景色之上,请使用Chrome或FireFox。
同样的,因为蓝色背景元素升级成了层叠上下文,因此, z-index:-1 无法穿透,在蓝色背景上显示了。
5. filter与层叠上下文
此处说的 filter 是CSS3中规范的滤镜,不是旧IE时代私有的那些,虽然目的类似。同样的,我之前有提过,例如图片的灰度或者 图片的毛玻璃效果 等。
我们使用常见的模糊效果示意下:
.box { background-color: blue; filter: blur(5px); }.box > img { position: relative; z-index: -1; right: -150px;}
结果如下:
好吧,果然被你猜对了,妹子蓝色床上躺着,只是你眼镜摘了,看得有些不够真切罢了。
6. isolation:isolate与层叠上下文
isolation:isolate 这个声明是 mix-blend-mode 应运而生的。默认情况下, mix-blend-mode 会混合z轴所有层叠在下面的元素,要是我们不希望某个层叠的元素参与混合怎么办呢?就是使用 isolation:isolate 。由于一言难尽,我特意为此写了篇文章:“ 理解CSS3 isolation: isolate的表现和作用 ”,解释了其阻隔混合模式的原理,建议大家看下。
要演示这个效果,我需要重新设计下,如下HTML结构:
<div class="box"> <img src="mm1.jpg"></div>
CSS主要代码如下:
.mode { /* 竖妹子绝对定位,同时混合模式 */ position: absolute; mix-blend-mode: darken;} .box { background: blue; }.box > img { position: relative; z-index: -1;}
结构如下:
会发现,横妹子被混合模式了。此时,我们给妹子所在容器增加 isolation:isolate ,如下CSS所示:
.mode { /* 竖妹子绝对定位,同时混合模式 */ position: absolute; mix-blend-mode: darken;} .box { background: blue; isolation:isolate; }.box > img { position: relative; z-index: -1;}
结果为:
会发现横着的妹子跑到蓝色背景上面了。这表明确实创建了层叠上下文。
7. will-change与层叠上下文
关于 will-change ,如果有同学还不了解,可以参见我之前写的文章:“ 使用CSS3 will-change提高页面滚动、动画等渲染性能 ”。
都是类似的演示代码:
.box { background-color: blue; will-change: transform; }.box > img { position: relative; z-index: -1; right: -150px;}
结果如下:
果然不出所料,妹子上了蓝色的背景。
本文多次提到,一旦普通元素具有了层叠上下文,其层叠顺序就会变高。那它的层叠顺序究竟在哪个位置呢?
这里需要分两种情况讨论:
于是乎,我们上面提供的层叠顺序表,实际上还是缺少其他重要信息。我又花功夫重新绘制了一个更完整的7阶层叠顺序图(同样的版权所有,商业请购买,可得无水印大图):
大家知道为什么定位元素会层叠在普通元素的上面吗?
其根本原因就在于,元素一旦成为定位元素,其 z-index 就会自动生效,此时其 z-index 就是默认的 auto ,也就是 0 级别,根据上面的层叠顺序表,就会覆盖 inline 或 block 或 float 元素。
而不支持z-index的层叠上下文元素天然 z-index:auto 级别,也就意味着,层叠上下文元素和定位元素是一个层叠顺序的,于是当他们发生层叠的时候,遵循的是“后来居上”准则。
我们可以速度测试下:
<img src="mm1" style="position:relative"><img src="mm2" style="transform:scale(1);">
<img src="mm2" style="transform:scale(1);"><img src="mm1" style="position:relative">
会发现,两者样式一模一样,仅仅是在DOM流中的位置不一样,导致他们的层叠表现不一样,后面的妹子趴在了前面妹子的身上。这也说明了,层叠上下文元素的层叠顺序就是 z-index:auto 级别。
z-index值与层叠顺序
如果元素支持z-index值,则层叠顺序就要好理解些了,比较数值大小嘛,小盆友都会,本质上是应用的“谁大谁上”的准则。在以前,我们只需要关心定位元素的z-index就好,但是,在CSS3时代,flex子项也支持 z-index ,使得我们面对的情况比以前要负复杂。然而,好的是,规则都是一样的,对于 z-index 的使用和表现也是如此,套用上面的7阶层叠顺序表就可以了。
同样,举个简单例子,看下 z-index:-1 和 z-index:1 变化对层叠表现的影响,如下两段HTML:
<div style="display:flex; background:blue;"> <img src="mm1.jpg" style="z-index:-1;"></div>
<div style="display:flex; background:blue;"> <img src="mm1.jpg" style="z-index:1;"></div>
最后,会发现, z-index:-1 跑到了背景色小面,而 z-index:1 高高在上。
一个与层叠上下文相关的有趣的显示现象
在实际项目中,我们可能会渐进使用CSS3的fadeIn淡入animation效果增强体验,于是,我们可能就会遇到类似下面的现象:
您可以狠狠地点击这里: CSS3 fadeIn淡入animation动画有趣现象
有一个绝对定位的黑色半透明层覆盖在图片上,默认显示是这样的:
但是,一旦图片开始走fadeIn淡出的CSS3动画,文字跑到图片后面去了
:
为什么会这样?
实际上,学了本文的内容,就很简单了!fadeIn动画本质是 opacity 透明度的变化:
@keyframes fadeIn { 0% { opacity: 0; } 100% { opacity: 1; }}
要知道, opacity 的值不是 1 的时候,是具有层叠上下文的,层叠顺序是 z-index:auto 级别,跟没有 z-index 值的 absolute 绝对定位元素是平起平坐的。而本demo中的文字元素在图片元素的前面,于是,当CSS3动画只要不是最终一瞬间的 opacity: 1 ,位于DOM流后面的图片就会遵循“后来居上”准则,覆盖文字。
这就是原因,于是,我们想要解决这个问题就很简单。
1. 调整DOM流的先后顺序;
2. 提高文字的层叠顺序,例如,设置 z-index:1 ;
只要元素发生层叠,要解释其表现,基本上就本文的这些内容了。
我发现很多重构小伙伴都有z-index滥用,或者使用不规范的问题。我觉得最主要的原因还是对理解层叠上下文以及层叠顺序这些概念都不了解。例如,只要使用了定位元素,尤其 absolute 绝对定位,都离不开设置一个 z-index 值;或者只要元素被其他元素覆盖了,例如变成定位元素或者增加 z-index 值升级。页面一复杂,必然搞得乱七八糟。
实际上,在我看来,觉得多数常见,z-index根本就没有出现的必要。知道了内联元素的层叠水平比块状元素高,于是,某条线你想覆盖上去的时候,需要设置 position:relative 吗?不需要, inline-block 化就可以。因为IE6/IE7 position:relative 会创建层叠上下文,很烦的。
OK,本文已经够长了,就不多啰嗦了。
行为匆忙,出错在所难免,欢迎大力指正。也欢迎各种形式的交流,或者指出文中概念性的错误。
感谢阅读!
本文为原创文章,会经常更新知识点,因此转载请保留原出处,方便溯源,避免陈旧错误知识的误导,同时内置样式和其他重要知识链接,有更好的阅读体验。
本文地址: http://www.zhangxinxu.com/wordpress/?p=5115
(本篇完)