😖먼저 display none과 hidden의 차이점은?
맨 하단의 레퍼런스 칸에서 mdn이 제공하는 예제를 직접 보는것도 이해에 도움이 됩니다.
우선 둘의 공통점은 다음과 같습니다.
두 속성 모두 특정 엘리먼트를 시야에서 보이지 않도록 처리하는 데에 사용하게 되는 속성입니다.
바닐라 css 에서의 사용례는 다음과 같습니다.
.hidden-visible {
visibility: hidden
}
.hidden-display {
display: none
}
두 속성 모두 내 시야에서 dom 요소를 보이지 않게 처리해줍니다.
둘의 차이점은?
display:none
레이아웃에서 요소를 완전히 제거하고 공간을 차지하지 않습니다.
주변 요소에 영향을 주지 않습니다.
visibility: hidden
이 경우 요소는 레이아웃에 남아 공간을 차지합니다.
주변 요소에 영향을 주게 됩니다.
알 수 있듯이 제법 큰 차이가 존재합니다.
따라서 이 둘은 용도에 따라 완전히 다르게 사용됩니다.
reflow와 repaint
위에서 살펴보았듯 두 속성은 요소를 보이지 않게하는 것은 같지만
세부적인 동작에서 큰 차이를 가지고 있습니다.
그리고 이는 브라우저의 reflow, repaint 작업과도 큰 연관을 가집니다.
브라우저가 가지고 있는 렌더링 엔진은 서버로부터 응답 받은 html, css 파일을 파싱하여
HTML은 DOM 트리를 CSS 는 CSSOM 을 생성합니다.
그리고 DOM , CSSOM 을 결합하여 렌더링을 위한 렌더트리를 생성합니다.
여담으로 이 과정에서 만약 display:none 속성을 가진 DOM Node가 있다면
그 노드는 렌더트리에 포함되지 않습니다.
렌더트리에는 브라우저 화면에 렌더링되는 노드만 들어갈 수 있기 때문이에요!
그리고 이 렌더트리는 각 HTML 요소의 레이아웃(위치와 크기)를 계산하는 데 사용되며
브라우저 화면에 픽셀을 렌더링 하는 페인팅 처리에 입력되게 됩니다.
그런데 최초 한번만 페인팅이 이루어지면 우리 화면은 항상 정적으로 보이게되겠지요?
그래서 브라우저는 javascript로 인한 상호작용 / viewport의 변화 등의 이벤트가 발생하면
다시 화면을 적절하게 그려주기 위해 레이아웃을 계산하고 페인팅을 수행합니다.
이렇듯 다시 레이아웃을 계산하는 것과 다시 페인팅을 하는 것이 바로 reflow와 repaint 입니다!
그리고 이 둘을 하나로 합쳐서 우리는 주로 "리렌더링"이라고 이름을 붙여주곤 합니다.
좀 더 자세하게 리플로우와 리페인트를 알아볼까요?
만약 자바스크립트 코드에 DOM, CSSOM을 변경하는 DOM API가 사용된 경우
DOM이나 CSSOM 은 자바스크립트 코드에 의해 변경됩니다.
변경된 DOM, CSSOM은 다시 렌더트리로 결합되고 다시 레이아웃 계산, 페인트를 거치게됩니다.
그 과정에서 리플로우와 리페인트가 발생하는 것이지요
그러나 주의할 점은 리플로우가 일어나야지만 리페인트가 발생하는 것은 아니라는 것입니다.
레이아웃에 영향이 없는 변경은 리플로우 없이 리페인트만 실행되거든요!
그럼 둘 중에 뭘 쓰는게 좋을까요?
visibility: hidden 쓰세요
요소가 화면에서 아예 사라져야만 하는 요구사항이 있을 때에는 display:none이 효과적입니다.
예컨대 z-index 등의 문제로 요소가 남아있으면 다른 요소와의 상호작용을 방해하게되는 경우라든지
화면에서 공간 차지 없이 아예 사라진것처럼 보여야하는 경우가 있을 수 있겠네요
그러나 대부분 그러한 요구사항이 있으면 아예 해당 Element를 삭제하는 방법을 사용하곤 할 것입니다.
따라서 대부분의 경우에는 요소가 눈에 보이지만 않고
언제든지 재사용될 수 있는 경우 등이 주를 이룰 것입니다.
그리고 그런 요구사항에서는 visibility : hidden을 사용하는 것이 좋습니다.
왜냐하면 visibility: hidden을 사용했을 때에는 요소가 레이아웃의 흐름에 남아 있기 때문에
레이아웃이 변경되지 않으며 레이아웃이 변경되지 않았기 때문에
reflow 작업을 생략할 수 있기 때문입니다.
그리고 조금 의외라고 생각할 수 있지만
일반적으로 repaint 보다 reflow가 더 비용이 큰 작업입니다!
따라서 특수한 목적이나 요구사항이 있는게 아니라면
visibility: hidden을 사용하시는 것을 더 추천드립니다.
그래서.. tailwindcss는 왜?
제가 이 글을 쓰게 된 것은 tailwindcss를 통해
hidden 속성을 사용해야하는 경우가 있었기 때문입니다.
아래 표를 보면..
in tailwindcss | in vanila css |
hidden | display: none |
invisibile | visibility: hidden |
visibility : hidden이니까 tailwind에서는 대충 hidden 이겠거니 하고 클래스를 작성하면
display none이 적용되어 버린답니다.. ㅎㅎ;;;
혹시 사용할일이 있다면 조심하세요..
마치며
사실 가장 글을 쓰게 된 동기는 tailwindcss의 클래스 hidden으로 인해
렌더트리에서 아예 요소가 삭제되는 바람에
intersectionObserver가 요소를 찾지 못하는 상황이 발생했기 때문입니다.
처음에는 visiblity:hidden 속성에 문제가 있는건가 했는데
알고보니 display: none이 적용되어 있었던 상황인것이지요
여러분은 조심하세요
레퍼런스
https://developer.mozilla.org/en-US/docs/Web/CSS/visibility
https://developer.mozilla.org/en-US/docs/Web/CSS/display
https://tailwindcss.com/docs/visibility
https://tailwindcss.com/docs/display
모던 자바스크립트 딥다이브 38장 전반
'css' 카테고리의 다른 글
tailwind merge 커스텀 클래스 오버라이딩 문제 해결 (3) | 2023.10.30 |
---|---|
특정한 영역에서만 스크롤바를 다르게 하고싶다면 (0) | 2023.09.18 |
shadcn/ui 사용법 익히기 (0) | 2023.08.21 |
요즘 핫한 panda css next.js app 라우터에서 시작하기 (0) | 2023.08.02 |
빌드타임 css-in-js 이해하기 pandacss와 vanila extract (0) | 2023.08.02 |