2 ๋ถ„ ์†Œ์š”

๐Ÿ“ฑ[PHOBUM] ๊ฐœ์„ : Z-index ๋˜ํ•œ ์„ค๊ณ„๋‹ค

์˜ค๋Š˜์€ PHOBUM์—์„œ ๋ฐœ์ƒํ•˜๊ณ  ์žˆ๋Š” ๋ฌธ์ œ๋ฅผ ๊ณ ๋ฏผํ•˜๊ณ  ๋‹ค์‹œ ์„ค๊ณ„ํ•ด๋ณด๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

๋ฐ”๋กœ๋ฐ”๋กœ! z-index

z-index๋ž€?

z-index๋Š” ์š”์†Œ์˜ ์Œ“์ž„ ์ˆœ์„œ๋ฅผ ๊ฒฐ์ •ํ•˜๋Š” ์†์„ฑ์œผ๋กœ, UI ๊ตฌ์„ฑ ์š”์†Œ์˜ ๊ณ„์ธต ๊ด€๊ณ„๋ฅผ ๋ช…ํ™•ํžˆ ํ•˜๊ณ  ๊ฒน์นจ ๋ฌธ์ œ๋ฅผ ๋ฐฉ์ง€ํ•˜๋Š” ๋ฐ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.

โš ๏ธ๋ฌธ์ œ์ 

PHOBUM์„ ๋งŒ๋“ค ๋•Œ, ์›น๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋ชจ๋ฐ”์ผ ํ™˜๊ฒฝ์—์„œ๋„ ๋ณผ ์ˆ˜ ์žˆ๋„๋ก max-width์™€ min-width๋ฅผ ์„ค์ •ํ•ด์ฃผ๊ณ  dvw์™€ dvh๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์ œ์ž‘ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์ฒ˜์Œ ์„ค๊ณ„๋•Œ, z-index์— ๋Œ€ํ•ด์„œ ๊ณ ๋ คํ•˜์ง€ ์•Š๊ณ  ๋งŒ๋“ค๊ธฐ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ์Œ“์ผ ์š”์†Œ๊ฐ€ ์ ๋‹ค๊ณ  ํŒ๋‹จํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜! ๊ทธ๊ฒƒ์€ ์˜คํŒ์ด์—ˆ์Šต๋‹ˆ๋‹ค. overlay๋ถ€ํ„ฐ appbar, FAB, popup, modal๊นŒ์ง€ ์˜์™ธ๋กœ ์Œ“์ด๋Š” ์š”์†Œ๋“ค์ด ๋งŽ์•˜๋˜ ๊ฒƒ์ด์ฃ .

๊ทธ๋ž˜๋„ ์• ์ž์ผํ•˜๊ฒŒ ์ง„ํ–‰ํ–ˆ์ง€๋งŒ, ์›น์—์„œ๋Š” ์ •์ƒ์ ์œผ๋กœ ๋ณด์ž…๋‹ˆ๋‹ค. image-20250507230507312

๊ทธ๋Ÿฌ๋‚˜ ๋ฌธ์ œ๋Š” ๋ชจ๋ฐ”์ผ์ž…๋‹ˆ๋‹ค.

image-20250507230539934

image-20250507230552955

์œ„ ์‚ฌ์ง„๊ณผ ๊ฐ™์ด ๋ชจ๋ฐ”์ผ์—์„œ๋Š” appbar๊ฐ€ overlay์œ„๋กœ ์˜ฌ๋ผ์˜ต๋‹ˆ๋‹ค. ๋˜ overlay๋œ ๊ณณ์—์„œ popup์ด ์‹คํ–‰๋  ์ˆ˜ ์—†๋Š”๋ฐ ์‹คํ–‰๋˜๊ธฐ ๊นŒ์ง€ ํ•ฉ๋‹ˆ๋‹ค.

๐ŸŽฏ๋ฌธ์ œ๊ฐ€ ๋ญ˜๊นŒ?

์™œ ๊ฐ™์€ ์ฝ”๋“œ์—์„œ ๋‹ค๋ฅธ ๊ฒฐ๊ณผ๋ฅผ ๋‚ผ๊นŒ?

์ด๋Ÿฐ ํ˜„์ƒ์€ ๊ฝค ์ž์ฃผ ๋ฐœ์ƒํ•œ๋‹ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ๋‹จ์ˆœํžˆ z-index์˜ ์ˆซ์ž๋งŒ์˜ ๋ฌธ์ œ๊ฐ€ ์•„๋‹ˆ๋ผ, position, overflow, fixed์œ„์น˜ ๋ฌธ์ œ ๋“ฑ๊ณผ ๋ธŒ๋ผ์šฐ์ €์˜ ๋ Œ๋”๋ง ์ฐจ์ด๊ฐ€ ๊ฒฐํ•ฉ๋œ ๊ฒฐ๊ณผ์ผ ๊ฐ€๋Šฅ์„ฑ์ด ๋†’๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๐Ÿ” ๋ฌธ์ œ ์›์ธ ๊ฐ€๋Šฅ์„ฑ

  1. ๋ถ€๋ชจ ์š”์†Œ์˜ stacking context ์ƒ์„ฑ

    • z-index๋Š” ๊ฐ™์€ stacking context ๋‚ด์—์„œ๋งŒ ๋น„๊ต
    • ๋ถ€๋ชจ์— transform, filter, perspective, opacity < 1, will-change, position: fixed ๋“ฑ์ด ์žˆ์œผ๋ฉด ์ƒˆ stacking context๊ฐ€ ์ƒ๊น€
    • ๋ชจ๋ฐ”์ผ์—์„œ layout์ด ๋ฐ”๋€Œ๋ฉด์„œ ๋‹ค๋ฅธ ๋ถ€๋ชจ๊ฐ€ stacking context๋ฅผ ๋งŒ๋“ค์—ˆ์„ ๊ฐ€๋Šฅ์„ฑ ์žˆ์Œ

    โžก๏ธ overlay๋Š” ์œ„์— ์žˆ์–ด๋„, appbar๊ฐ€ ๋‹ค๋ฅธ stacking context์—์„œ ๋” ๋†’์€ ์šฐ์„ ์ˆœ์œ„๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Œ

  2. position ์†์„ฑ ๋ˆ„๋ฝ ๋˜๋Š” ์ถฉ๋Œ

    • z-index๋Š” position: relative, absolute, fixed, sticky ๋“ฑ์˜ ์š”์†Œ์—๋งŒ ์ ์šฉ
    • ๋ชจ๋ฐ”์ผ์—์„œ position์ด ๋‹ฌ๋ผ์กŒ๊ฑฐ๋‚˜ media query์—์„œ ๋ˆ„๋ฝ๋˜์—ˆ์„ ์ˆ˜ ์žˆ์Œ
  3. AppBar๊ฐ€ fixed์ด๊ณ , viewport ๊ธฐ์ค€์œผ๋กœ ๋ Œ๋”๋ง๋จ

    • ๋ชจ๋ฐ”์ผ์—์„œ๋Š” fixed ์š”์†Œ๊ฐ€ ์˜ค๋ฒ„๋ ˆ์ด๋ณด๋‹ค ์œ„์— ๋‚˜ํƒ€๋‚˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Œ (ํŠนํžˆ iOS์—์„œ)
    • overlay๋Š” ๋ถ€๋ชจ ๊ธฐ์ค€ absolute, AppBar๋Š” fixed๋กœ ์ธํ•ด body ๊ธฐ์ค€์ด ๋˜์–ด z-index๋ณด๋‹ค ์šฐ์„ ๋  ์ˆ˜ ์žˆ์Œ
  4. ๋ธŒ๋ผ์šฐ์ € ์—”์ง„ ์ฐจ์ด

    • ๋ชจ๋ฐ”์ผ Safari(iOS), Chrome(Android)์˜ ๋ Œ๋”๋ง ๋ฐฉ์‹์ด ๋‹ค๋ฅด๋‹ค ๋ณด๋‹ˆ, ๊ฐ™์€ DOM ๊ตฌ์กฐ์—ฌ๋„ z-index ์ฒ˜๋ฆฌ ์ˆœ์„œ๊ฐ€ ๋‹ฌ๋ผ์ง
    • ํŠนํžˆ iOS๋Š” ์Šคํฌ๋กค ๊ด€๋ จ ๋ฒ„๊ทธ๊ฐ€ ๋งŽ๊ณ , fixed ์š”์†Œ์— ๋ฏผ๊ฐํ•จ

โœ…ํ•ด๊ฒฐ

์šฐ์„  themeํŒŒ์ผ์— z-index๋ฅผ ์ผ๊ด€์„ฑ ์žˆ๊ฒŒ ์ •๋ฆฌํ•ด ์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋•Œ ๊ทธ๋•Œ ํ•œ ํŽ˜์ด์ง€ ๋งŒ๋“ค๋ฉด์„œ ์กฐ๊ธˆ์”ฉ ์กฐ์ •ํ•œ ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š” ๊ฒƒ ๊ฐ™์•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

overlay๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์žก๊ณ  ์šฐ์„  ์ˆœ์œ„๋ฅผ ์ •ํ•ด๋ดค์Šต๋‹ˆ๋‹ค.

Modal, Popup, BottomSheet
--- [overlay] ---๊ธฐ์ค€
	AppBar, FAB

์ด ๊ตฌ์กฐ๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ z-index๋ฅผ ์„ค์ •ํ•ด์ค๋‹ˆ๋‹ค.

๊ทธ ์™€์ค‘์— overlay ์ ์šฉํ•œ z-index์™€ fixed๋ฐœ๊ฒฌ!

image-20250507232810538 ๋ฐ”๋กœ ์ง€์›Œ์ค๋‹ˆ๋‹ค. ์•„๋งˆ ์ด๊ฒƒ ๋•Œ๋ฌธ์ผ๊ฑฐ๋ผ๋Š” ๋А๋‚Œ์ด ๊ฐ•ํ•˜๊ฒŒ ์˜ต๋‹ˆ๋‹คโ€ฆ

๊ทธ๋ฆฌ๊ณ  ์ž„์‹œ๋กœ ์ง€์ •ํ•ด๋‘” z-index๋ฅผ ์ด์ œ ์ „๋ถ€ ์ˆ˜์ •ํ•ด์ค๋‹ˆ๋‹ค.

image-20250507232936412

์ด๋ ‡๊ฒŒ ์„ค์ •ํ•ด์ฃผ์—ˆ๋Š”๋ฐ๋„ ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค..

stacking context๊ฐ™์œผ๋‹ˆ ๋ถ€๋ชจ-์ž์‹ ๊ด€๊ณ„์™€ ํฌ์ง€์…”๋‹์„ ์žฌ์„ค์ •ํ•ด์ฃผ๊ฒ ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ์ถ”๊ฐ€๋กœ ์ˆ˜์ •ํ•œ ๊ฒƒ์ด, ๋ชจ๋ฐ”์ผ ํ™”๋ฉด์„ ๋ณด๋ฉด ํ•˜๋‹จ๊ณผ ์ƒ๋‹จ padding์ด ์•ž์— ์žˆ๋Š” ๋А๋‚Œ์ธ๋ฐ, ์ด๊ฒƒ์€ Layout์— ์ ์šฉํ•œ ๊ฒƒ ์ž…๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ Layout๋˜ํ•œ ์กฐ์ ˆํ•ด์คฌ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ๋„ ์•ˆ๋ผ์„œ ์ด๋ฒˆ์—๋Š” github commit์„ ๋’ค์ง€๊ธฐ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค.

overscroll-behavior-y: contain;
    -webkit-overflow-scrolling: touch

InteractiveCard๋ฅผ ์ข€๋” ๋ถ€๋“œ๋Ÿฝ๊ฒŒ ์‚ฌ์šฉํ•˜๋ ค๊ณ  ์ถ”๊ฐ€ํ–ˆ๋˜ ๊ฒƒ์ธ๋ฐ ์ด๊ฒƒ์„ ์ง€์› ์Šต๋‹ˆ๋‹ค.

!!!!

๋๋‹ค!!! ๋ฌธ์ œ๋Š” ์ด ์ฝ”๋“œ์˜€์Šต๋‹ˆ๋‹ค.

โœ… ์›์ธ ์ •๋ฆฌ

๐Ÿ”ธ-webkit-overflow-scrolling: touch

์ด ์„ค์ •์€ iOS Safari์—์„œ ๋ถ€๋“œ๋Ÿฌ์šด ์Šคํฌ๋กค(๋ชจ๋ฉ˜ํ…€ ์Šคํฌ๋กค)์„ ํ™œ์„ฑํ™”ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด ์†์„ฑ์„ ๊ฐ€์ง„ ์š”์†Œ๋Š” ๋…๋ฆฝ์ ์ธ GPU layer๋กœ ๋ Œ๋”๋ง๋ฉ๋‹ˆ๋‹ค.

โžก๏ธ๋‚ด๋ถ€์— ์žˆ๋Š” ์š”์†Œ๋“ค์ด ์ƒˆ๋กœ์šด stacking context๋ฅผ ๋งŒ๋“ค์–ด ๋‚ด๋Š”๊ฒƒ ์ž…๋‹ˆ๋‹ค.

์ด๋กœ ์ธํ•ด z-index๊ฐ€ ์˜ˆ์ƒ๋Œ€๋กœ ์ž‘๋™ํ•˜์ง€ ์•Š๊ณ , AppBar๊ฐ€ ์˜ค๋ฒ„๋ ˆ์ด๋ณด๋‹ค ์œ„์— ํ‘œ์‹œ๋˜๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ”ธ overscroll-behavior-y: contain

์ด ์„ค์ •์€ ์Šคํฌ๋กค ๋ฒ„๋ธ”๋ง์„ ๋ง‰์•„์„œ ์ƒ์œ„๋กœ ์Šคํฌ๋กค ์ด๋ฒคํŠธ ์ „๋‹ฌ์„ ์ฐจ๋‹จํ•ฉ๋‹ˆ๋‹ค.

์ด ์ž์ฒด๊ฐ€ stacking context์— ์˜ํ–ฅ์„ ์ฃผ์ง„ ์•Š์ง€๋งŒ, overflow์™€ ํ•จ๊ป˜ ์‚ฌ์šฉ๋  ๋•Œ ์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ๋ฅผ ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ ์ฃผ์„์ฒ˜๋ฆฌํ•˜์—ฌ ์™„์ „ ์—†์• ๊ธฐ๋ณด๋‹ค๋Š” , ํ•„์š”ํ•œ ๊ฒฝ์šฐ์—๋งŒ ์ œํ•œ์ ์œผ๋กœ ์ ์šฉํ•˜๋„๋ก ํ•˜๋Š”๊ฒƒ์ด ์ข‹๋‹ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

ex) ๋ฏธ๋””์–ด ์ฟผ๋ฆฌ

๐Ÿค”๋А๋‚€์ 

iOS์—์„œ -webkit-overflow-scrolling:touch๋Š” ๋ฒ„๊ทธ๋ฅผ ๋งŽ์ด ์ผ์œผํ‚ค๋‹ˆ ์‹ ์ค‘ํ•˜๊ฒŒ ์‚ฌ์šฉํ•ด์•ผ๊ฒ ์Šต๋‹ˆ๋‹ค.

stacking context์— ๋Œ€ํ•œ ๊ณต๋ถ€๋ฅผ ํ•ด์•ผ๊ฒ ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ƒฅ ๋ฌด์กฐ๊ฑด ์ข‹์•„๋ณด์ด๋‹ˆ๊นŒ ์‚ฌ์šฉ์€ ์—ญ์‹œ ์ง€์–‘ํ•ด์•ผ๊ฒ ์Šต๋‹ˆ๋‹ค. ์ €๋•Œ๋„ ๋ชจ๋ฐ”์ผ ์›น์—์„œ๋Š” ํ„ฐ์น˜๋กœ ๋ถ€๋“œ๋Ÿฝ๊ฒŒ ์นด๋“œ ํšŒ์ „์ด ์•ˆ๋˜์„œ scroll๊ด€๋ จ css๋ฅผ ๋‹ค ํ™œ์šฉํ–ˆ๋˜ ๊ธฐ์–ต์ด ์žˆ๋Š”๋ฐ, ์•Œ๊ณ  ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๊ณผ ๋ชจ๋ฅด๊ณ  ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ํฝ๋‹ˆ๋‹ค.

์นดํ…Œ๊ณ ๋ฆฌ:

์—…๋ฐ์ดํŠธ:

๋Œ“๊ธ€๋‚จ๊ธฐ๊ธฐ