디스플레이 속성 파고들기: 상자 생성
게시 됨: 2022-03-10display
속성에 대한 시리즈를 계속해서, 이번에는 Rachel Andrew가 상자 생성을 제어하는 값을 살펴보겠습니다. 이것은 CSS의 display
속성에 대한 짧은 기사 시리즈 중 두 번째입니다. "디스플레이의 두 가지 가치" 시리즈의 첫 번째 기사를 읽을 수 있습니다. display
사양은 우리가 가지고 있는 모든 다양한 레이아웃 방법을 뒷받침하므로 이해하는 데 매우 유용한 사양입니다.
display
의 많은 값에는 고유한 사양이 있지만 많은 용어와 아이디어는 display
에 자세히 설명되어 있습니다. 이것은 이 사양을 이해하는 것이 본질적으로 display
값을 자세히 설명하는 사양을 이해하는 데 도움이 된다는 것을 의미합니다. 이 기사에서는 display
의 box generation 값( none
및 contents
)을 살펴보겠습니다.
모든 것은 상자다
CSS에서는 모든 것이 상자를 생성합니다. 웹 페이지는 기본적으로 블록 및 인라인 상자 세트이며, 즐겨 사용하는 브라우저에서 DevTools를 열고 페이지에서 요소 선택을 시작하면 매우 잘 이해할 수 있습니다. 레이아웃을 구성하는 상자와 여백, 패딩 및 테두리가 적용되는 방식을 볼 수 있습니다.
박스 생성 제어
display
의 none
및 contents
값은 상자가 전혀 표시되어야 하는지 여부를 처리합니다. 마크업에 요소가 있고 CSS에서 상자를 생성하지 않도록 하려면 어떻게든 상자 생성을 억제해야 합니다. 두 가지 가능한 작업을 수행할 수 있습니다. 다음은 다음과 같습니다.
- 상자와 모든 자식의 생성을 방지합니다.
- 상자의 생성을 방지하지만 여전히 자식을 표시합니다.
이러한 각 시나리오를 차례로 살펴볼 수 있습니다.
디스플레이: 없음
display
의 none
값은 상자와 해당 상자의 모든 자식 생성을 방지하는 방법입니다. 요소가 전혀 없는 것처럼 작동합니다. 따라서 해당 콘텐츠를 완전히 숨기려는 상황에서 유용합니다. 아마도 링크를 활성화한 후에 나중에 드러날 것이기 때문입니다.
단락, 정렬되지 않은 목록 및 다른 단락이 있는 예가 있는 경우 항목이 정상적인 흐름으로 표시되는 것을 볼 수 있습니다. ul
에는 배경과 테두리가 적용되고 약간의 패딩이 있습니다.
display: none
을 ul
에 추가하면 시각적 디스플레이에서 사라지고 ul
의 자식과 배경 및 테두리도 함께 가져옵니다.
display: none
을 사용하는 경우 웹사이트의 모든 사용자로부터 콘텐츠를 숨깁니다. 여기에는 스크린 리더 사용자가 포함됩니다. 따라서 상자와 그 안의 모든 것을 모든 사람에게 완전히 숨기려는 의도인 경우에만 이 옵션을 사용해야 합니다.
화면 판독기와 같은 보조 기술 사용자를 위해 추가 정보를 추가하고 다른 사용자를 위해 숨길 수 있는 상황이 있습니다. 이러한 경우에는 다른 기술을 사용해야 합니다. Scott O'Hara는 그의 기사 "Inclusively Hidden"에서 몇 가지 훌륭한 제안을 했습니다.
따라서 display: none
을 사용하는 것은 매우 간단합니다. 디스플레이, 상자 트리 및 접근성 트리에서 상자와 내용을 사라지게 하려는 상황에서 사용합니다(처음에는 없었던 것처럼).
디스플레이: 콘텐츠
두 번째 시나리오에서는 훨씬 더 새로운 디스플레이 가치를 살펴봐야 합니다. display: contents
값은 display: none
과 동일한 방식으로 상자 트리에서 적용된 상자를 제거하지만 자식은 그대로 둡니다. 이것은 우리가 레이아웃에서 할 수 있는 일의 관점에서 몇 가지 유용한 동작을 유발합니다. 간단한 예를 보고 더 자세히 살펴보겠습니다.
이전과 같은 예제를 사용하고 있지만 이번에는 display: contents
on ul
을 사용했습니다. 이제 목록 항목이 표시되지만 배경과 테두리가 없으며 둘러싸는 ul
없이 페이지에 li
요소를 추가한 것처럼 작동합니다.
상자를 제거하고 자식을 유지하는 것이 유용한 이유는 display
의 다른 값이 동작하는 방식 때문입니다. display
의 값을 변경할 때 지난 기사에서 설명한 대로 상자와 해당 상자의 직계 자식에 대해 변경합니다. 요소에 대한 CSS 규칙에 display: flex
를 추가하면 해당 요소는 블록 수준 상자가 되고 직계 자식은 플렉스 항목이 됩니다. 이러한 플렉스 항목의 자식은 일반 흐름으로 돌아갑니다(플렉스 레이아웃의 일부가 아님).
다음 예에서 이 동작을 볼 수 있습니다. 여기에 flex를 표시하도록 설정된 포함 요소가 있습니다. 여기에는 4개의 직계 자식, 3개의 div 요소 및 1개의 ul
이 있습니다. ul
에는 두 개의 목록 항목이 있습니다. 직계 자식은 모두 플렉스 레이아웃에 참여하고 플렉스 항목으로 레이아웃합니다. 목록 항목은 직계 자식이 아니므로 ul
상자 안에 목록 항목으로 표시됩니다.
이 예를 들어 display: contents
를 ul
에 추가하면 상자가 시각적 디스플레이에서 제거되고 이제 자식이 플렉스 레이아웃에 참여합니다. 직계 자녀가 되지 않음을 알 수 있습니다. div 및 ul
요소와 같은 방식으로 직접 자식 범용 선택기( .wrapper > *
)에 의해 선택되지 않으며 지정된 배경을 유지합니다. 일어난 모든 일은 ul
을 포함하는 상자가 제거되고 다른 모든 것은 정상적으로 수행된다는 것입니다.
접근성 및 의미 체계 데이터에 중요하지만 플렉스 또는 그리드 레이아웃으로 콘텐츠를 배치하는 것을 방지할 수 있는 추가 상자를 생성하는 HTML의 요소를 고려하는 경우 이는 잠재적으로 매우 유용한 의미를 갖습니다.
이것은 CSS "재설정"이 아닙니다.
display: contents
사용의 한 가지 부작용은 요소의 여백과 패딩이 제거된다는 것입니다. CSS Box Model의 일부인 box와 관련이 있기 때문입니다. 이것은 display: contents
가 요소의 패딩과 여백을 빠르게 제거하는 좋은 방법이라고 생각하게 할 수 있습니다.
이것은 Adrian Roselli가 야생에서 발견한 용도입니다. 그는 그렇게 하는 것의 문제를 설명하는 자세한 게시물을 작성할 만큼 충분히 우려했습니다. " display: contents
는 CSS 재설정이 아닙니다." 그가 제기한 문제 중 일부는 현재 display:contents가 있는 브라우저의 불행한 접근성 문제로 인한 것입니다. 이에 대해서는 아래에서 논의할 것입니다. 그러나 이러한 문제가 해결된 후에도 단순히 여백과 패딩을 제거하기 위해 상자 트리에서 요소를 제거하는 것은 다소 극단적입니다.
다른 것이 없다면 향후 사이트 유지 관리에 문제가 될 것입니다. 미래의 개발자는 왜 이 신비한 상자에 아무것도 적용할 수 없는 것 같았는지 궁금해할 것입니다. 제거되었다는 사실을 놓친 것입니다! 여백과 패딩이 0
이 되어야 하는 경우 미래의 자신에게 호의를 베풀고 유서 깊은 방식으로 0
으로 설정하십시오. display: contents
입니다.
display: contents
와 CSS Grid Layout subgrid의 차이점도 주목할 가치가 있습니다. 여기서 display: contents
는 디스플레이에서 상자, 배경 및 테두리를 완전히 제거하여 그리드 항목을 하위 그리드로 만들면 해당 항목의 상자 스타일을 유지하고 중첩된 항목이 동일한 그리드를 사용할 수 있도록 트랙 크기 조정을 통과합니다. 내 기사 "CSS Grid Level 2: Here Comes Subgrid"에서 자세히 알아보십시오.
접근성 문제 및 디스플레이: 콘텐츠
심각한 문제는 현재 display: contents
가 가장 유용할 바로 그 일에 유용하지 않은 콘텐츠를 만듭니다. display: contents
는 화면 판독기 또는 기타 보조 장치를 사용하는 사람들이 콘텐츠를 더 쉽게 이해할 수 있도록 하는 마크업을 추가하기 위해 추가 상자가 필요한 경우입니다.
첫 번째 디스플레이에 있는 목록의 ul
요소 display: contents
CodePen은 완벽한 예입니다. 목록을 전혀 사용하지 않고 마크업을 평면화하여 동일한 시각적 결과를 얻을 수 있습니다. 그러나 콘텐츠가 의미상 목록이고 스크린 리더가 목록으로 가장 잘 이해하고 읽을 수 있는 경우 목록으로 표시해야 합니다.
그런 다음 자식 요소가 플렉스 또는 그리드 레이아웃의 일부가 되도록 하려면 ul
상자가 없는 것처럼 display: contents
를 사용하여 상자를 마법처럼 제거하고 그렇게 만들 수 있어야 합니다. 의미가 제자리에 있습니다. 사양에 따르면 이렇게 해야 합니다.
“display
속성은 요소의 의미 체계에 영향을 미치지 않습니다. 이는 문서 언어에 의해 정의되며 CSS의 영향을 받지 않습니다. 요소 및 해당 하위 항목의 청각/음성 출력 및 상호 작용에도 영향을 주는 없음 값을 제외하고display
속성은 시각적 레이아웃에만 영향을 줍니다. 이 속성의 목적은 디자이너가 기본 요소에 영향을 주지 않고 요소의 레이아웃 동작을 자유롭게 변경할 수 있도록 하는 것입니다. 문서 의미론."
이미 논의한 바와 같이 none
값은 화면 판독기에서 요소를 숨깁니다. 그러나 display
의 다른 값은 순전히 사물이 시각적으로 표시되는 방식을 변경할 수 있도록 합니다. 문서의 의미를 건드리면 안 됩니다.
이러한 이유로 우리 중 많은 사람들이 display: contents
가 실제로 그것을 구현한 두 브라우저(Chrome 및 Firefox)의 접근성 트리에서 요소를 제거한다는 것을 깨닫는 데 놀랐습니다. 따라서 문서 의미를 변경하여 화면 판독기가 display: contents
를 사용하여 ul
을 제거한 후 목록이 목록임을 알지 못하도록 합니다. 이것은 브라우저 버그이며 심각한 문제입니다.
작년에 Hidde de Vries는 자신의 게시물인 " display:contents
를 통한 접근성 향상 마크업"에서 이 문제를 작성했으며 인식을 높이고 수정 작업을 수행할 수 있도록 다양한 브라우저에 대해 도움이 되는 문제를 제기했습니다. Firefox는 이 문제를 부분적으로 수정했지만 버튼과 같은 특정 요소에는 여전히 문제가 있습니다. 이 문제는 Chrome에서 적극적으로 해결 중입니다. WebKit에도 문제가 있습니다. 문제의 영향을 받는 콘텐츠 표시에 대한 사용 사례가 있는 경우 이 버그에 별표를 표시하는 것이 좋습니다.
이러한 문제가 해결되고 문제가 발생한 브라우저 버전이 중단될 때까지 의미 정보를 전달하고 보조 기술에 노출되어야 하는 모든 콘텐츠에 display:contents를 사용할 때 매우 주의해야 합니다. Adrian Roselli가 말했듯이,
"지금은 보조 기술로 테스트하고 결과가 사용자에게 제대로 작동하는지 확인할 수 있는 경우에만 display:contents를 사용하십시오."
이런 걱정 없이 안전하게 display: contents
를 사용할 수 있는 곳이 있습니다. 하나는 이전 브라우저에서 플렉스 레이아웃 그리드에 대한 폴백을 만들기 위해 추가 마크업을 추가해야 하는 경우입니다. display: contents
를 지원하는 브라우저는 그리드와 플렉스박스도 지원하므로 콘텐츠를 display: contents
할 수 있습니다. 중복된 div
요소가 추가되었습니다. 아래 예에서 행 래퍼로 완성된 부동 기반 그리드를 만들었습니다.
그런 다음 display: contents
를 사용하여 행 래퍼를 제거하여 모든 항목이 그리드 항목이 되어 그리드 레이아웃의 일부가 될 수 있도록 합니다. 이것은 추가 마크업을 추가해야 하는 경우 그리드 또는 플렉스 레이아웃을 수행할 때 콘텐츠를 사용하여 제거할 수 있다는 점에서 고급 레이아웃에 대한 대체를 생성할 때 추가 도구를 제공할 수 있습니다. 이 사용법이 문제를 일으킬 것이라고는 생각하지 않습니다. 누군가 나보다 더 나은 접근성 정보를 갖고 있고 문제를 지적할 수 있다면 의견에 그렇게 하십시오.
마무리
이 기사에서는 display
속성의 상자 생성 값을 살펴보았습니다. 이제 display: none
— 상자와 모든 자식을 완전히 제거하고 display: contents
는 상자 자체만 제거하는 다른 동작을 이해하시기 바랍니다. 또한 접근성과 관련하여 이러한 방법을 사용할 때 발생할 수 있는 잠재적인 문제를 이해해야 합니다.