box-shadow css-不規則邊框 css position css z-index

CSS 切版 - 不規則邊框

陳建融 Randy Chen 2022/03/14 11:30:28
1291

起源

本篇文章的切版練習,是跟著這部切版教學影片一起切出來的,如果有興趣的話,可以去看看原本教學者的系列影片,蠻有趣的。
本篇文章紀錄的內容,是筆者覺得這篇切版練習很值得注意並記錄下來的切版技巧,那我們就開始吧!

學習點

1. 圈圈製作的方式 - 用 box-shadow

主要是透過 box-shadow 達到圈圈水平、垂直偏移 和 放大的效果

首先,我們會先製作第一個圓,然後,再以這個圓為基準,利用它的 box-shadow 屬性來長出其他顏色的圓 和 陰影的圓

程式寫法如下

.circle {
	margin: 30px auto;
	width: 100px;
	height: 100px;
  border-radius: 50%;
	background-color: #fff;
	box-shadow: 
      150px 0px 0px 0px #f00,
      250px 0px 0px 0px #f00,
      400px 0px 0px 20px #ff0,

      -150px 0px 0px 0px #00f,
      -250px 0px 0px 0px #00f,
      -400px 0px 0px 20px #ff0;
}

上面的程式碼畫面會長得像下方的圖片這樣

首先,值得特別注意的點是 box-shadow 屬性可以設定多組,這就是我們用來製作多個圓的方法。
第二,box-shadow 的第一, 二個參數 h-offeset 和 v-offset : 它們可以決定陰影要往水平方向和垂直方向偏移多少,
如此,我們就可以在不同的位置放置由 box-shadow 製作出的圓。
第三,box-shadow 的第四個參數 size: 它可以決定陰影區域要放大(值是正的)或縮小多少(值是負的),由此我們就可以製作出大小不一的圓型囉。

 

這個效果真的很酷 XD,都沒想過要這樣使用 box-shadow 真的蠻酷的!!

 

2. 蓋住圈圈多餘的部分 - 有關 position 和 z-index 的順序的複合影響

按照課堂上的步驟完成圈圈的特效之後,會發現圈圈會出現在 .container 區塊上方,但這是我們不要的效果

那我們就要用一些技巧來遮住這些我們不想要的區塊

solution: 用 :before 偽元素來遮不要的部分

我們用 .secondary 的 :before 偽元素來遮。 寫法如下

.secondary {
	position: relative;
}
.secondary:before {
	content: '';
	height: 200px;
	position: absolute;
	left: 0;
	right: 0;
	top: 0;
	background: #fff;
	z-index: 1; // 為了要覆蓋掉 .secondary:after 的部分
}

結果長的像下面這樣

但是,它連 .container 的都遮掉了,所以,我們在 .container 加入 z-index: 2 的設定,企圖讓它在 .secondary:before 的上面讓內容出現

.secondary {
	position: relative;
}
.secondary:before {
	content: '';
	height: 200px;
	position: absolute;
	left: 0;
	right: 0;
	top: 0;
	background: #fff;
	z-index: 1; // 為了要覆蓋掉 .secondary:after 的部分
}
.secondary .container {
	z-index: 2;
}

但你會發現沒用,但是,我們在加上了 position: relative 這行,就發現可以達成我們要的效果囉

.secondary .container {
	position: relative;
	z-index: 2;
}

 

z-indexposition 對 stacking order 的影響

上述的範例,有關加入了 position: relative 之後 z-index 才生效的原因,最主要是因為 stacking order 的不同所造成的。
我在這邊稍微整理一下它們兩個屬性對元素的 stacking order 的影響。

首先,在這篇文章中,有提到以下有 設定 position 屬性的元素特性

According to this rule, positioned elements will display on top of unpositioned elements.

意思是,有設定 position 屬性的元素會覆蓋在沒有設定 position 屬性元素的上層, 這邊說的 position 屬性設定,是指除了 static 以外的設定,例如 absolute, relative

第二,接著,我們加入 z-index 的設定

往常來說,我們都知道 z-index 數值越大的元素會疊在畫面的越上層。 但是,精確的來說,z-index 只有在那些有設定 position 屬性,且 position 屬性不是設定 static 的元素上,才有效用。

Notice: 這邊說的 position 屬性設定,是指除了 static 以外,例如 absolute, relative

舉個例子

.box1, 
.box2 {
	width: 100px;
	height: 100px;
}
.box1 {
	background-color: red;
	z-index: 10;
}
.box2 {
	background-color: red;
	position: absolute;
	left: 0;
	top: 0;
	z-index: 1;
}

你會發現 z-index: 10 在 box1 上是沒有效用的,就算它的 z-index 比 .box2 還大,它還是疊在 .box2 下面。
這也是為什麼在課堂上的範例中,我們直接對 .container 設定 z-index: 2 會沒有效果,但是,加上了 position: relative 之後,才會有效果的原因囉。

 

子層 z-index 受制於父層的 z-index

這邊延續一下 z-index 影響 stacking order 的內容,在這篇文章的第四點,有提到以下這段話

But yet another aspect of stacking context is that a child element is limited to the stacking context of its parent.

大意是 子層元素的 z-index 會受制於父層元素的 z-index
假如有以下狀況

--- HTML ---

<div class="content">
	<div class="modal"></div>
</div>
<div class="side-nav"></div>

--- CSS ---

.content {
	z-index: 1;
}
.modal {
	z-index: 100
}
.side-nav {
	z-index: 5;

以上範例,我們原本希望的效果為 modal 會在所有元素的上方,也就是覆蓋在 content 和 side-nav 的上方,但是,因為 modal 是 content 的子層,所以,它會受制於父層的 z-index, 它相對於 content 內部的其他子層的元素是 z-index: 100 ,但是,content 和 side-nav 是同一階層的,所以,modal 的 z-index 對於 side-nav 來說是 z-index: 1 這就是為什麼 modal 沒有覆蓋掉所有元素的原因。

解決辦法

Solution 1: 將 modal 移到外層與其他元素同層

方法如下

<div class="content"></div>
<div class="side-nav"></div>
<div class="modal"></div>

如此一來,modal 就沒有任何父層的限制囉,它的 z-index: 100 就會發揮覆蓋在任何元素上方的效果囉~

Solution 2: 移除父層 content 的 stacking context 的角色

這篇文章有提到,製作出 stacking context 的方法其中一種,就是為元素加入 position 和 z-index 的設定。
那現在我們將父層 content 的 position 屬性拿掉,此時,z-index: 1 的設定對 .content 就不再具有效用,進而它就不再影響其所擁有子層的 stacking order。

也因為如此,.modal 就擁有自己獨立的 z-index: 100 也就可以疊在所有的元素之上囉~

 

課堂練習

練習範例連結

 

Reference

1. z-index 和 position 屬性的複合影響

2. z-index 和 position 屬性的複合影-詳細描述 stacking context 的元素排序

 

陳建融 Randy Chen