css

display:none과 visibility:hidden의 차이를 아시나요?

냠냠맨 2023. 8. 24. 00:18

😖먼저 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

 

visibility - CSS: Cascading Style Sheets | MDN

The visibility CSS property shows or hides an element without changing the layout of a document. The property can also hide rows or columns in a <table>.

developer.mozilla.org

https://developer.mozilla.org/en-US/docs/Web/CSS/display

 

display - CSS: Cascading Style Sheets | MDN

The display CSS property sets whether an element is treated as a block or inline box and the layout used for its children, such as flow layout, grid or flex.

developer.mozilla.org

https://tailwindcss.com/docs/visibility

 

Visibility - Tailwind CSS

Utilities for controlling the visibility of an element.

tailwindcss.com

https://tailwindcss.com/docs/display

 

Display - Tailwind CSS

Utilities for controlling the display box type of an element.

tailwindcss.com

모던 자바스크립트 딥다이브 38장 전반

반응형