0%

Angular Custom Modal -共用元件實作 - 彈窗 - 2

學習目標

  1. 製作彈窗效果的 css style

預期彈窗效果

  1. 當點擊開啟 modal 的按鈕,會有黑色的遮罩出現,然後,彈窗從畫面上方降下來

CSS Style

下面就是 modal.component.html 內容,包含了 modal 和 modal-backdrop

1
2
3
4
5
6
7
8
9
10
11
// --- modal.component.html --- //
<div class="modal" [class.show]="show | async">
<div class="modal-body>
<ng-content></ng-content>
<p>
<button type="button">關閉</button>
</p>
</div>
</div>

<div class="modal-backdrop" [class.show]="show | async"></div>

整體概念就是,modal-backdrop 會在 modal 的下方,並呈現半透明的黑色。
那 modal 就是會是一張透明填滿整個畫面的區塊,而 modal-body 就會疊在 modal 的上面。

Here is modal-backdrop css style.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// --- modal.component.scss --- //
.modal-backdrop {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
background-color: black;
z-index: -1;
opacity: 0;

&.show {
z-index: 900;
opacity: 0.6;
transform: opacity 1s;
}
}

先利用 position, top 等相關 css style 設定讓 modal-backdrop 撐滿整個畫面。
z-index: -1opacity: 0 是讓 modal-backdrop 一開始看不見,且不會擋到別人。
最後,當 modal-backdrop 的 class 加入 show 之後,會利用 transform: opacity 1s 的效果,讓 modal-backdrop 漸漸地出現。

Here is modal css style.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
// --- modal.component.scss --- //
.modal {
position: fixed:
top: 0;
bottom: 0;
left: 0;
right: 0;
z-index: -1;
opacity: 0;

.modal-body {
max-width: 500px;
background-color: white;
margin: 0 auto;
}
}

.modal.show {
z-index: 1000;
animation: opacityShow 1s;
animation-fill-mode: forwards;

.modal-body {
animation: modalShow 1s;
animation-fill-mode: forwards;
}
}

@keyframe opacityShow {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}

@keyframe modalShow {
0% {
transform: translateY(-50%);
}
100% {
transform: translateY(20%);
}
}

.modal 就是一個撐滿整個畫面的透明薄膜,上面疊著 .modal-body。 .modal-body 就是主要呈現彈窗內容的區塊。
當 .modal 加入 show 這個 class 的時候,.modal 會吃到 opacityShow 的動畫效果,從透明 (opacity: 0) 變成完整呈現 (opacity: 1)。
而 .modal-body 也會同時吃到另一個 modalShow 特效,呈現漸入的效果。

以上的內容,就是製作彈窗漸入和彈窗遮罩的 css style 內容


The following content is the css problems that I faced while I was trying to fulfilled the pop-up effect of modal.

CSS style problem

z-index not working

如果,今天沒有在 .modal 中加入 position:fixed 的設定的話,那當其被加入 z-index: 1000 的時候,是沒有效果的,會直接墊在 .modal-backdrop 後方,導致我們點擊不到 .modal-body 的內容。
這種狀況的解決辦法,在這一篇文章中有提到,若 A 區塊有加上 position 的設定且它的 z-index 是 900,而 B 區塊沒有 position 的設定但它的 z-index 是 1000。這樣子就算 B 的 z-index 比 A 大,它還是會墊在 A 的下面,因為,有 position 設定的區塊優先序會比較高。那其解決辦法就是在 B 區塊也加上 position 的設定,這樣一來 A 和 B 就在同一個高度基準上,接著,再判斷誰的 z-index 值大囉。
而 .modal 和 .modal-backdrop 之間就是一樣的道理囉~

animation-fill-modal: forwards

可以發現在 scss 中有特別加入以上的 animation-fill-modal: forwards 的設定。這一行的效果為,讓被加入這個 css style 設定的元素,會保留 animation 最終的效果。
什麼意思呢? 以本篇的 modalShow 這個特效為例:

1
2
3
4
5
6
7
8
@keyframe modalShow {
0% {
transform: translateY(-50%);
}
100% {
transform: translateY(20%);
}
}

最終的特效效果為 transform: translateY(20%),所以,該區塊最後會保留這個 css style 囉。
如果,不加入 animation-fill-modal: forwards 的話,彈窗的位置會被重製喔,像下面這張動畫一樣。
dialog position reset

Conclusion

  1. Understand how to write modal css style to realize pop-up effect of modal.
  2. Resolve the z-index problem between .modal and .modal-backdrop.
  3. Resolve the problem that .modal-body position will be reset after the animation is finished.

Reference

  1. the reason why z-index is not working
  2. animation-fill-mode usage