๐Ÿ‘จโ€๐Ÿ’ป

CSS ์Œ“์ž„ ๋งฅ๋ฝ๊ณผ ์ปจํ…Œ์ด๋‹ ๋ธ”๋ก

์ตœ๊ทผ ์‹ค๋ฌด์—์„œ position: fixed ์Šคํƒ€์ผ์ด ์ ์šฉ๋œ ํ—ค๋”(FIXED HEADER)๊ฐ€ ์‚ฌํŒŒ๋ฆฌ์™€ ๊ฐ™์€ ์ผ๋ถ€ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์•„๋ž˜ ์Šคํฌ๋ฆฐ์ƒท๊ณผ ๊ฐ™์ด ์ „์ฒด ์˜์—ญ์œผ๋กœ ๋ฒ—์–ด๋‚˜๋Š” ์ด์Šˆ๋ฅผ ๊ฒช์—ˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ๋Œ€ํ–ˆ๋˜ ๋™์ž‘์€ ํ—ค๋”๊ฐ€ ์™ผ์ชฝ ํŒจ๋„ ๋‚ด์— ๊ณ ์ •๋˜๋Š” ๊ฒƒ์ด์—ˆ์Šต๋‹ˆ๋‹ค.

๊ณ ์ • ํ—ค๋”๊ฐ€ ์ „์ฒด ์˜์—ญ์œผ๋กœ ๋ฒ—์–ด๋‚˜๋Š” ํ˜„์ƒ

position: relative๋กœ ์ •์˜๋œ ๋ถ€๋ชจ ์š”์†Œ(LEFT) ๋‚ด๋ถ€์— ๊ณ ์ •๋ ๊ฑฐ๋ž€ ์˜ˆ์ƒ์ด ๋น—๋‚˜๊ฐ€ ๊ฝค ๋‹นํ™ฉํ–ˆ๊ณ , ์›น ๊ฒ€์ƒ‰์œผ๋กœ transform: translateZ(0) ์Šคํƒ€์ผ์„ ์ ์šฉํ•ด ๊ธ‰ํžˆ ์ˆ˜์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.

๋‚˜๋ฆ„ CSS๋ฅผ ๋งŽ์ด ๋‹ค๋ค„์™”๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๋Š”๋ฐ ๋ ˆ์ด์•„์›ƒ ๊ธฐ์ดˆ ์ง€์‹์˜ ํ—ˆ์ ์ด ๋“œ๋Ÿฌ๋‚˜ ๋ฐ˜์„ฑํ•˜๋Š” ๊ณ„๊ธฐ๊ฐ€ ๋๊ณ , ๊ทผ๋ณธ์ ์ธ ์›์ธ๊ณผ ํ•ด๊ฒฐ์ฑ…์„ ์•Œ์•„๋ณธ ๊ณผ์ •์„ ์ •๋ฆฌํ–ˆ์Šต๋‹ˆ๋‹ค.

์Œ“์ž„ ๋งฅ๋ฝ (Stacking Content)

WebGL๊ณผ ๊ฐ™์€ 3D ๊ธฐ์ˆ ์„ ๋‹ค๋ฃจ๋Š” ์›น์‚ฌ์ดํŠธ๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ ์‚ฌ์šฉ์ž๋Š” 2์ฐจ์›์˜ ํŽ˜์ด์ง€๋ฅผ ๋ณด๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์ด ์ƒํƒœ๋กœ๋Š” ๊ฐ UI ์š”์†Œ๊ฐ€ ๊ฒน์ณ์งˆ ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— ๋ ˆ์ด์•„์›ƒ ๋ฐฐ์น˜๊ฐ€ ์ƒ๋‹นํžˆ ์ œํ•œ์ ์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด HTML์—์„œ๋Š” 3์ฐจ์›, ์ฆ‰ z์ถ•์œผ๋กœ ์š”์†Œ์˜ ๊ด€๊ณ„๋ฅผ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๋„๋ก ์Œ“์ž„ ๋งฅ๋ฝ์ด๋ผ๋Š” ๊ฐœ๋…์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๋Œ€ํ‘œ์ ์œผ๋กœ CSS z-index ์†์„ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

์Œ“์ž„ ๋งฅ๋ฝ์€ ์•„๋ž˜ ํ•ญ๋ชฉ์— ํ•ด๋‹น๋  ๋•Œ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

  • ๋ฃจํŠธ ์š”์†Œ์ธ <html> (z์ถ• ์ƒ์—์„œ ๋ชจ๋“  ์š”์†Œ๋Š” html๋ณด๋‹ค ์•„๋ž˜์— ๋ฐฐ์น˜๋  ์ˆ˜ ์—†์Œ)
  • position ๊ฐ’์ด absolute ๋˜๋Š” relative์ด๊ณ , z-index ๊ฐ’์ด ์ •์˜๋œ ๊ฒฝ์šฐ
  • position ๊ฐ’์ด fixed ๋˜๋Š” sticky (๊ตฌํ˜• ๋ฐ์Šคํฌํƒ‘์—์„œ sticky๋Š” ํ•ด๋‹น๋˜์ง€ ์•Š์Œ)
  • display ๊ฐ’์ด flex ๋˜๋Š” grid์ธ ์š”์†Œ์˜ ์ž์‹ ์š”์†Œ์ด๊ณ , z-index ๊ฐ’์ด ์ •์˜๋œ ๊ฒฝ์šฐ
  • opacity๊ฐ€ 1๋ณด๋‹ค ์ž‘์€ ๊ฒฝ์šฐ
  • transform์˜ ๊ฐ’์ด none์ด ์•„๋‹Œ ๊ฒฝ์šฐ
  • will-change ์†์„ฑ์ด ์ •์˜๋œ ์š”์†Œ
  • ๋‚˜๋จธ์ง€ ํ•ญ๋ชฉ์€ MDN ๋ฌธ์„œ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์•ž์„œ ๊ณต์œ ๋“œ๋ฆฐ ์Šคํฌ๋ฆฐ์ƒท๊ณผ ๊ฐ™์€ ๋ ˆ์ด์•„์›ƒ์—์„œ 'FIXED HEADER' ์˜์—ญ์€ position: fixed๋กœ ์ •์˜๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์Œ“์ž„ ๋งฅ๋ฝ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด ๋ถ€๋ชจ ์š”์†Œ๋„ ์Œ“์ž„ ๋งฅ๋ฝ์ด ์ƒ์„ฑ๋˜๋„๋ก ํ•˜๋ฉด ๋‚ด๋ถ€์— ๊ณ ์ •๋˜๋„๋ก ๋ฐฐ์น˜ํ•  ์ˆ˜ ์žˆ์„๊นŒ์š”?

ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•ด ๋จผ์ € ์•„๋ž˜์™€ ๊ฐ™์€ HTML์„ ์ž‘์„ฑํ•œ ๋’ค ํฌ๋กฌ ๊ฐœ๋ฐœ์ž ๋„๊ตฌ์—์„œ ํ™•์ธํ•ด๋ดค์Šต๋‹ˆ๋‹ค. (ํฌ๋กฌ ๊ฐœ๋ฐœ์ž ๋„๊ตฌ์˜ '๋ ˆ์ด์–ด' ํƒญ์„ ํ™œ์šฉํ•˜๋ฉด ์‹œ๊ฐํ™”๋œ ์Œ“์ž„ ๋งฅ๋ฝ ์ •๋ณด๋ฅผ ์‚ดํŽด๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.)

<div className="container"> <div className="left"> <header className="left-header">FIXED HEADER</header> LEFT </div> <div className="right">RIGHT</div> </div> <style> .container { display: flex; } /* .left, .right ์Šคํƒ€์ผ์€ ์ƒ๋žต */ .left-header { position: fixed; } </style>

ํฌ๋กฌ ๊ฐœ๋ฐœ์ž ๋„๊ตฌ ๋ ˆ์ด์–ด ํƒญ์œผ๋กœ ํ™•์ธํ•ด๋ณธ ๊ฒฐ๊ณผ

'FIXED HEADER' ์˜์—ญ์ด ๋‹ค๋ฅธ ๋ ˆ์ด์–ด๋ณด๋‹ค ์œ„์— ์Œ“์—ฌ ์žˆ๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ถ€๋ชจ ์š”์†Œ์ธ 'LEFT'๋ฅผ ์Œ“์ž„ ๋งฅ๋ฝ์œผ๋กœ ์ƒ์„ฑํ•˜๋Š” ์Šคํƒ€์ผ์„ ์ ์šฉํ•ด ํ•ด๊ฒฐ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•ด๋ดค์Šต๋‹ˆ๋‹ค.

.left { /* ํ•ด๊ฒฐ๋จ (= FIXED HEADER๊ฐ€ LEFT ์˜์—ญ ๋‚ด์—์„œ ๊ณ ์ •๋จ) */ transform: translateZ(0); perspective: 0; filter: blur(0); will-change: transform; will-change: perspective; will-change: filter; /* ํ•ด๊ฒฐ๋˜์ง€ ์•Š์Œ */ position: relative; position: fixed; z-index: 1; opacity: .9; will-change: opacity; }

์Œ“์ž„ ๋งฅ๋ฝ์„ ์ƒ์„ฑํ•˜๋Š” ๋ชจ๋“  ์Šคํƒ€์ผ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜์ง€ ๋ชปํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ข€ ๋” ๊ทผ๋ณธ์ ์ธ ์›์ธ์„ ํŒŒ์•…ํ•ด๋ดค์Šต๋‹ˆ๋‹ค.

The element is removed from the normal document flow, and no space is created for the element in the page layout. It is positioned relative to the initial containing block established by the viewport, except when one of its ancestors has a transform, perspective, or filter property set to something other than none (see the CSS Transforms Spec), in which case that ancestor behaves as the containing block.

โ€” position: fixed, MDN

MDN ๋ฌธ์„œ์˜ fixed ๊ฐ’์— ๋Œ€ํ•œ ์„ค๋ช… ์ค‘ ์ปจํ…Œ์ด๋‹ ๋ธ”๋ก์ด๋ผ๋Š” ๊ฐœ๋…์— ๋‹ต์ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

์ปจํ…Œ์ด๋‹ ๋ธ”๋ก (Containing Block)

๊ฐ HTML ์š”์†Œ์˜ ํฌ๊ธฐ๋Š” ๋„ˆ๋น„, ๋†’์ด์™€ ์š”์†Œ๋ฅผ ๋‘˜๋Ÿฌ์‹ธ๋Š” ์—ฌ๋ฐฑ(padding, border)์œผ๋กœ ๊ณ„์‚ฐ๋˜๊ณ , ์œ„์น˜๋Š” margin๊ณผ offset ๊ฐ’์œผ๋กœ ๊ณ„์‚ฐ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์š”์†Œ์˜ ํฌ๊ธฐ์™€ ์œ„์น˜๋Š” ์ปจํ…Œ์ด๋‹ ๋ธ”๋ก์˜ ์˜ํ–ฅ์„ ๋ฐ›์Šต๋‹ˆ๋‹ค.

์ด ๊ธ€์—์„œ ๋‹ค๋ฃจ๊ณ  ์žˆ๋Š” fixed ์š”์†Œ์˜ ๋ฐฐ์น˜๋„ ์ปจํ…Œ์ด๋‹ ๋ธ”๋ก์„ ๊ฒฐ์ • ์ง“๋Š” ๊ธฐ์ค€์— ๋”ฐ๋ฅด๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. MDN ๋ฌธ์„œ์— ๋”ฐ๋ฅด๋ฉด position ์†์„ฑ์ด fixed์ธ ๊ฒฝ์šฐ ๊ธฐ๋ณธ์ ์œผ๋กœ ํ˜„์žฌ ๋ณด๊ณ  ์žˆ๋Š” ํ™”๋ฉด ์ „์ฒด ์˜์—ญ(viewport)์ด ์ปจํ…Œ์ด๋‹ ๋ธ”๋ก์ด ๋ฉ๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ์•„๋ž˜ ํ•ญ๋ชฉ์— ํ•ด๋‹น๋˜๋Š” ๋ถ€๋ชจ ์š”์†Œ ์ค‘ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ๊ฒƒ์„ ๊ธฐ์ค€์œผ๋กœ ์ปจํ…Œ์ด๋‹ ๋ธ”๋ก์ด ์ •ํ•ด์ง‘๋‹ˆ๋‹ค.

  • transform, perspective, filter ์ค‘ ํ•˜๋‚˜์˜ ๊ฐ’์ด none์ด ์•„๋‹Œ ๊ฒฝ์šฐ
  • will-change ๊ฐ’์ด transform, perspective, filter ์ค‘ ํ•˜๋‚˜์ธ ๊ฒฝ์šฐ
  • contain ๊ฐ’์ด paint์ธ ๊ฒฝ์šฐ

์ด ์ค‘ perspective์™€ filter ์†์„ฑ์— ๋Œ€ํ•œ ์ง€์›์€ ๋ธŒ๋ผ์šฐ์ €๋งˆ๋‹ค ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด์ œ ์Œ“์ž„ ๋งฅ๋ฝ์„ ์ƒ์„ฑํ•˜๋Š” ์Šคํƒ€์ผ ์ค‘ transform, perspective, filter ์†์„ฑ์— ๋Œ€ํ•ด์„œ๋งŒ ์›ํ•˜๋Š” ๋ ˆ์ด์•„์›ƒ ๋ฐฐ์น˜๊ฐ€ ๋œ ์›์ธ์„ ์•Œ๊ฒŒ ๋์Šต๋‹ˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ € ํ˜ธํ™˜์„ฑ์„ ๊ณ ๋ คํ•˜๋ฉด ์•„๋ž˜์˜ ์Šคํƒ€์ผ๋กœ ๋Œ€์‘ํ•˜๋Š” ๊ฒƒ์ด ์ ํ•ฉํ•ด ๋ณด์ž…๋‹ˆ๋‹ค.

  • transform: translateZ(0)
  • will-change: transform

์ปจํ…Œ์ด๋‹ ๋ธ”๋ก ์Šคํƒ€์ผ ์ ์šฉ์œผ๋กœ ํ•ด๊ฒฐ๋œ ๊ฒฐ๊ณผ

๋งˆ๋ฌด๋ฆฌ

์Šคํƒ€์ผ ์ž‘์—… ์‹œ ๋นˆ๋ฒˆํ•˜๊ฒŒ ์‚ฌ์šฉ๋˜๋Š” position ์†์„ฑ์ด ์ž์‹ ๊ณผ ์ƒ์œ„ ์š”์†Œ์˜ ๋‹ค๋ฅธ ์Šคํƒ€์ผ์— ๋”ฐ๋ผ ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋Š”์ง€ ์ข€ ๋” ๊นŠ๊ฒŒ ์•Œ์•„๋ณด๋Š” ๊ณ„๊ธฐ๊ฐ€ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๊ฐ’์„ ๋ฐ”๊พธ๋ฉด ์›นํŽ˜์ด์ง€์—์„œ ๋ฐ”๋กœ ํ™•์ธ ๊ฐ€๋Šฅํ•œ CSS์˜ ํŠน์„ฑ์œผ๋กœ ์ธํ•ด ๋ฌธ์ œ๊ฐ€ ์ƒ๊ฒผ์„ ๋•Œ ๊ฐ’์„ ๋ผ์›Œ๋งž์ถ”๋Š” ์Šต๊ด€์ด ์ƒ๊ธธ ์ˆ˜ ์žˆ๋Š”๋ฐ ์ด๋Ÿฌํ•œ ๋ถ€๋ถ„์„ ๊ฒฝ๊ณ„ํ•˜๊ณ  ๋ช…์„ธ์™€ ์›๋ฆฌ๋ฅผ ํŒŒ์•…ํ•˜๋Š” ์‹œ๊ฐ„์„ ์ถฉ๋ถ„ํžˆ ๊ฐ€์ ธ์•ผ๊ฒ ์Šต๋‹ˆ๋‹ค.

๋ถ€๋ก: z-index ์ดํ•ดํ•˜๊ธฐ

MDN ๋ฌธ์„œ๋ฅผ ํƒ์ƒ‰ํ•˜๋Š” ๊ณผ์ •์—์„œ z-index ์šฐ์„  ์ˆœ์œ„๋ฅผ ์ดํ•ดํ•˜๋Š” ์ข‹์€ ํŒ์„ ๋ฐœ๊ฒฌํ•ด ํ•จ๊ป˜ ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค. z-index ๊ฐ’์— ๋”ฐ๋ฅธ ๋ ˆ์ด์–ด ๋ฐฐ์น˜๋ฅผ ํŒ๋‹จํ•  ๋•Œ ์‹œ๋งจํ‹ฑ ๋ฒ„์ „ ๊ทœ์น™์„ ๋Œ€์ž…ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค.

An easy way to figure out the rendering order of stacked elements along the Z axis is to think of it as a "version number" of sorts, where child elements are minor version numbers underneath their parent's major version numbers.

โ€” HTML ์š”์†Œ ๊ฐ„์˜ z-index ์šฐ์„  ์ˆœ์œ„๋ฅผ ํŒ๋‹จํ•˜๋Š” ๋ฐฉ๋ฒ•, MDN
z-index๋ฒ„์ „
z-index: 1์ธ ์š”์†Œ A1.0.0
A์˜ ์ž์‹ ์š”์†Œ์ด๊ณ , z-index: 10์ธ ์š”์†Œ B1.10.0
z-index: 2์ธ ์š”์†Œ C2.0.0
C์˜ ์ž์‹ ์š”์†Œ์ด๊ณ , z-index: 1์ธ ์š”์†Œ D2.1.0

๋ฒ„์ „ ๊ฐ„์˜ ๋น„๊ต์—์„œ ๋ฉ”์ด์ € ๋ฒ„์ „ ๊ฐ’์ด ๋‚ฎ์€ ๊ฒฝ์šฐ ๋งˆ์ด๋„ˆ ๋ฒ„์ „ ๊ฐ’์ด ์•„๋ฌด๋ฆฌ ๋†’์•„๋„ ๋ฒ„์ „์˜ ํฌ๊ธฐ๋Š” ์—ญ์ „๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ z-index์—์„œ๋„ ๋™์ผํ•œ ๊ธฐ์ค€์ด ์ ์šฉ๋˜์–ด ๋ถ€๋ชจ ์š”์†Œ์˜ ๊ฐ’์— ๋”ฐ๋ผ ๊ฒฐ์ •๋˜๊ธฐ ๋•Œ๋ฌธ์— ์œ„์˜ ํ…Œ์ด๋ธ”์—์„œ B ์š”์†Œ๋Š” D ์š”์†Œ๋ณด๋‹ค ์œ„์— ๋ฐฐ์น˜๋  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

References