TIL no.10 - CSS - 쌓임 맥락(stacking context)

codeamor·2020년 6월 25일
1

CSS

목록 보기
3/4

매일 CSS 를 쓰고는 있지만 정작 그 중요성을 자주 잊는 것 같다.
중요성은 알지만 JavaScript와 Python이 너무 깡패라서 금방 잊는다..

프로그래밍(JavaScript)을 공부하면 할 수록 마크업(HTML + CSS)의 중요성은 천정부지다.
JavaScript 도 결국 문서 내의 DOM을 건드리는 언어이기 때문..
그래도 스스로 마크업은 어느 정도 한다고 생각했었는데 요즘 마크업 때문에 엄청 고생한다.
내가 알던 그 마크업이 맞나 싶다.
마크업이 엉성한데 열심히 프로그램 짜고 있는 건 말그대로 사상누각이다.

✔ JavaScript 를 처음 배울 때
→ CSS.. 다시 보니 선녀! 😭

✔ CSS 를 다시 공부할 때
→ JavaScript.. 다시 보니 선녀(..??) 😭

그냥 둘 다 깡패..


쌓임 맥락

  • 가상의 Z축을 사용한 HTML 요소의 3차원 개념화
  • 각각의 HTML 요소는 자신의 속성에 따른 우선순위를 사용해 3차원 공간을 차지한다.
  • z축 상의 쌓임 순서에서, 같은 쌓임 맥락 안의 자식 요소들의 z축 위치를 이동 시킬 수 있는 개념.

CSS 의 'C' 는 cascading(폭포)을 의미한다.

CSS 의 상속과 우선순위를 표현하기 위해 폭포라는 단어를 썼다고 한다.

개인적으로 CSS 상속에 대해서는 경험상
인라인 계열 = 대부분 상속 됨, 블록 계열 = 대부분 상속 안 됨
이런 식으로 느껴졌다.
그리고 레퍼런스에 inherit 특성이 있는지 없는지만 보면 바로 알 수 있다.

그런데 우선순위의 문제는 은근히 복잡하다.

나는 CSS의 우선순위 라고 하면

  • 뒤에 나오는 스타일이 우선순위가 높다.
  • idclass 보다 우선순위가 높다.
  • z-index 를 줘서 눈에 보이는 우선순위를 정할 수 있다.
  • 요소에 직접 style 지정하거나 JavaScript 의 스타일 조작을 통해 요소의 최우선 스타일을 지정할 수 있다.

딱 이 정도만 생각했던 것 같다.

그런데 최근에 요소를 겹쳐보이게 한다거나
opacity 를 주는 경우가 잦아서
z-index 를 자주 쓰게 됐는데
이럴 때마다 내가 정한 순서대로 되지 않을 때가 종종 있었다.

개발자 도구를 봐도 잘 모르겠어서 어떤 게 잘못됐나 찾아보다가
'stacking context' 라는 개념을 접하게 되었다.
읽기만 했을 때는 이해가 잘 안되서 정리해본다.


1.1. 쌓임 맥락 특성

  • z-index 값은 부모에게만 의미가 있다.
    하나의 쌓임 맥락은 부모 쌓임 맥락 안에서 통째로 하나의 단위로 간주된다.

  • 쌓임 맥락이 다른 쌓임 맥락을 포함할 수 있고, 함께 계층 구조를 이룬다.

  • 쌓임 맥락은 형제 쌓임 맥락과 완전히 분리된다. 쌓임을 처리할 땐 자손 요소만 고려한다.

  • 각각의 쌓임 맥락은 독립적이다. 어느 요소의 콘텐츠를 쌓은 후에는 그 요소를 통째 부모 쌓임 맥락 안에 배치한다.


1.2. 쌓임 맥락 조건

  • html 요소 (문서의 루트 요소)

  • position: static 이 아니고 z-index: auto 가 아닌 요소

  • opacity < 1 인 요소

이후에 자잘한 조건들이 더 있지만 위 세 조건이 핵심이다.

1.3. 쌓임 순서

  1. 쌓임 맥락의 뿌리 요소 (html 요소)

  2. position 값이 존재, z-index < 0
    : 이 경우는 자식이 부모보다 아래로 갈 수 있다.

  3. position을 따로 주지 않은 경우 (position: static)

  4. position 값이 존재, z-index = auto 혹은 0

  5. position 값이 존재, z-index > 0

1.4. 예제

  • 아래의 예제에서 쌓임 맥락의 루트 요소(뿌리)는 DIV #1과 DIV #3 이다.
  • 두 DIV는 모두 position: relative로 지정되었지만
    z-index 속성 값은 지정되지 않았다.
  • DIV #1 안에는 position: absolute로 지정된 DIV #2가 있고
  • DIV #3 안에는 position: absolute로 지정된 DIV #4가 있다.
  • DIV #2와 DIV #4 모두 z-index 속성 값은 지정되지 않았다.

1.4.1. 예제 1

유일한 쌓임 맥락은 html요소(뿌리 엘리먼트)다. z-index가 없는 엘리먼트들은 HTML 문서에서 등장 순서대로 쌓인다.


1.4.2. 예제 2

DIV #2의 z-index 속성 값을 0또는 auto가 아닌 양의 정수로 지정하면 다른 DIV들 보다 위에 올라온다.


1.4.3. 예제 3

DIV #4의 z-index 속성 값을 DIV #2의 z-index 속성 값보다 큰 값으로 지정하면 DIV #4는 DIV #2보다 위에 올라온다.



  • 마지막 예제에서 DIV #2와 DIV #4는 부모가 다르기 때문에 형제가 아니다.
    그럼에도 불구하고 DIV #2와 DIV #4의 쌓임 순서를 z-index 속성 값을 지정함으로써 바꿀 수 있었다.
    왜냐하면 DIV #1과 DIV #3은 z-index 속성 값이 지정되지 않았고 따라서 쌓임 맥락을 만들지 않았기 때문이다.
    따라서 DIV #2와 DIV #4는 둘 다 루트 요소의 쌓임 맥락에 속해있고, z-index 속성 값을 변경하여 쌓임 순서를 바꿀 수 있다.

  • 쌓임 맥락의 용어로 DIV #1과 DIV #3은 루트 요소에 동화되었다고 표현한다.
    이 예제의 DIV들은 다음과 같은 쌓임 맥락 계층 구조를 이룬다.

    • 루트 쌓임 맥락 (여기서는 DIV #1과 DIV #3)
      • DIV #2 (z-index 1)
      • DIV #4 (z-index 2)


정리하다 보니 쌓임 맥락이 반드시 명시해줘야 하는 개념이라는 게 느껴졌다.

어찌보면 당연한 게,
나는 요소들을 겹쳐 보이게 하기 위해 모든 요소에 position 을 주었는데
여기에 opacity 까지 줘버리면
요소들에 z-index 를 준다고 해서 z축 상의 순서가 구분이 될까?
모든 요소의 투명도가 동일하다는 가정이 없기 때문에 불가능하다.
위의 예제는 색상 차이가 뚜렷하고 border 가 있으니 구분이 쉽다지만
(가만보니 색상들이 RGB..)
비슷한 요소들이 겹쳐져 있을 때
뒤에 있는 요소의 투명도가 0.9, 앞에 있는 요소가 0.1이면
누가 봐도 뒤의 요소가 앞에 있다고 생각하게 될 것이다.
그래서 별도의 맥락이라는 개념이 필요했고 별도의 우선순위를 가질 수 있게끔 하지 않았을까..
요소들이 비슷해서 순서가 헷갈릴지라도 개발자가 쌓임 맥락을 알고 있으면 뭐가 위에 있는 건지 알 수 있으니 말이다..

이 개념은 position, opacityz-index 가 온전히 어울리게 만들어주는 중요한 역할을 해주는 것 같다.

0개의 댓글