Display 속성에 대해 자세히 알아보기: 아래로 그리드

게시 됨: 2022-03-10
빠른 요약 ↬ CSS의 display 속성에 대한 시리즈를 계속하면서, 이번에는 Rachel Andrew가 표시 값으로 grid를 사용할 때 어떤 일이 발생하는지 살펴보고 subgrid가 해당 동작을 변경하는 방법에 대한 정보를 추가했습니다.

오늘은 display: grid 를 사용할 때 어떤 일이 발생하는지 살펴보고 grid-template-columnsgrid-template-rows 의 새로운 하위 그리드 값을 사용하여 마크업을 통해 그리드를 끝까지 허용하는 방법을 살펴보겠습니다. , 서로 관련이 있습니다.

이 기사는 CSS display 속성의 다양한 측면을 살펴보는 시리즈의 일부이며 처음 두 기사의 후속 기사입니다.

  1. display 의 두 가지 가치
  2. 박스 제너레이션
  3. 모든 방법 아래로 그리드

그리드 컨테이너를 생성하면 어떻게 됩니까?

CSS 그리드 레이아웃은 display: grid 를 사용하여 켜집니다. 이 시리즈의 첫 번째 기사를 읽었다면 이 단일 값 속성이 실제로 의미하는 바가 display: block grid 라는 것을 알게 될 것입니다. 그리드 항목이고 그리드 레이아웃에 참여하는 직계 자식이 있는 그리드 컨테이너 로 정의된 블록 수준 상자를 얻습니다.

디스플레이 사양을 살펴보면 display 에 대한 모든 다른 값을 정의하는 표를 볼 수 있습니다. 그리드 컨테이너 라는 단어는 그리드 사양의 그리드 컨테이너 정의에 연결됩니다. 그러므로 이것이 실제로 무엇을 의미하는지 알아내기 위해서는 그곳으로 가야 합니다. 그렇게 하면 그리드 컨테이너의 동작에 대한 유용한 설명을 얻을 수 있습니다.

점프 후 더! 아래에서 계속 읽기 ↓

그리드 컨테이너는 BFC(블록 서식 컨텍스트)와 유사한 그리드 서식 컨텍스트를 설정한다고 합니다. 나는 Block Formatting Context에 대한 광범위한 가이드를 작성했습니다. 이 기사에서는 그리드 서식 컨텍스트에 대해 동일한 BFC에 대해 두 가지를 발견할 것입니다. 플로트는 그리드 컨테이너에 침입하지 않으며 컨테이너의 여백은 콘텐츠의 여백과 함께 축소되지 않습니다.

그러나 그리드 컨테이너 내부로 들어갈 때만 차이점이 있습니다. 블록 및 인라인 레이아웃에 참여하지 않는 그리드 컨테이너의 자식은 그리드 항목이므로 그리드 레이아웃에 참여합니다. 이것은 우리가 블록 및 인라인 레이아웃에서 사용하는 몇 가지 사항이 사실이 아님을 의미합니다.

레이아웃의 항목이 떠 있거나 지워진 경우 항목이 그리드 항목이 되면 floatclear 속성이 영향을 주지 않습니다. vertical-align 속성은 효과가 없으며 ::first-letter::first-line 의사 요소를 사용할 수 없습니다.

항목 이 플로팅될 수 없고 그리드 항목이 둘 다 될 수 없다는 사실은 폴백 생성 측면에서 도움이 됩니다. 부동 소수점을 사용하여 그리드를 지원하지 않는 브라우저에 대한 대체를 만들 때(그리드가 지원되는 경우) 특별한 작업을 수행할 필요가 없습니다. 부동 소수점을 덮어씁니다.

그리드 없는 브라우저 지원에 대한 기사에서 이 접근 방식을 간략하게 설명합니다. 동작이 문제가 있는 것으로 판명된 상황이 있습니다. 이러한 문제는 그리드 및 부동 소수점 문제 풀기, "편집 레이아웃, 제외 및 CSS 그리드"에서 설명한 대로 CSS의 다른 부분을 사용하여 해결할 수 있습니다.

그렇긴 해도 display 의 값을 grid 로 변경하는 것 외에는 아무것도 하지 않으면 레이아웃에 큰 차이가 없습니다. 직계 자식은 그리드 항목이지만 기본적으로 1열 그리드로 끝납니다. 그리드에는 항상 하나의 열과 하나의 행이 있습니다. 이 작업을 수행한 후 볼 수 있는 나머지 행은 암시적 행, 즉 콘텐츠를 보유하기 위해 생성된 행입니다.

한 열에서 다른 카드 아래에 배치된 카드 세트입니다.
열이 없는 그리드 컨테이너를 생성하면 1열 그리드가 생성됩니다. (큰 미리보기)

grid-template-columns 속성에 값을 지정하여 그리드처럼 보이는 것을 형성하기 시작할 수 있습니다. 속성은 트랙 목록을 값으로 사용합니다. 3개의 1fr 트랙을 제공하면 이제 3열 그리드가 표시되고 gap 속성을 사용하면 해당 카드 사이에 간격이 생깁니다.

이제 그리드처럼 보이는 것이 있습니다.

세 개의 열과 두 개의 행으로 배치된 카드
명확한 그리드 레이아웃을 얻기 위해 일부 열 트랙과 간격을 정의합니다(큰 미리보기).

이 예제의 각 그리드 항목에는 자체 자식이 있습니다. 카드에는 머리글과 바닥글과 카드의 주요 내용을 위한 영역이 있습니다. 이 자식은 그리드 항목이지만 자식이 블록 및 인라인 레이아웃으로 돌아갔습니다. 머리글, 콘텐츠 영역 및 바닥글은 그리드와 같은 작업을 수행하지 않습니다. display 의 값을 grid 로 변경하면 상속하지 않고 대신 자식만 그리드 항목이 되기 때문입니다. 그들의 자식은 블록 레이아웃으로 돌아갑니다.

중첩 그리드

카드에 다른 카드보다 더 많은 콘텐츠가 있으면 해당 행의 카드가 더 높아집니다. 그리드 항목에 대한 align-items 의 초기 값은 stretch 입니다. 우리 카드는 전체 높이로 늘어납니다. 그러나 내부의 항목은 일반 블록 및 인라인 흐름이므로 카드를 채우기 위해 마법처럼 늘어나지 않습니다. (위 이미지에서 내용이 적은 카드의 하단에 틈이 있는 것을 볼 수 있는 이유입니다.)

바닥글이 항상 맨 아래에 오도록 하려면 그리드 항목도 그리드로 만들 수 있습니다. 이 경우 단일 열 그리드만 있으면 됩니다. 그런 다음 콘텐츠 클래스가 있는 div 가 있는 영역에 1fr 의 트랙 크기를 제공하여 행 트랙을 정의할 수 있습니다. 이렇게 하면 컨테이너에서 사용 가능한 모든 공간을 차지하게 되며 바닥글을 카드 맨 아래로 밀어냅니다.

Rachel Andrew의 Pen[디스플레이: subgrid is not what we want](https://codepen.io/rachelandrew/pen/PvQzeG)을 참조하십시오.

펜 디스플레이를 참조하십시오. Rachel Andrew의 하위 그리드는 우리가 원하는 것이 아닙니다.

이 그리드 중첩은 필요한 만큼 수행할 수 있습니다. 여기서는 중첩 테이블을 생성하지 않고 일반적으로 이미 있는 구조적 HTML 요소를 사용하기 때문에 중첩으로 생각하지 않습니다. 한 번에 한 수준씩 display 값을 해당 요소의 자식에 가장 적합한 값으로 변경하고 있습니다. 그것은 플렉스 레이아웃이나 그리드 레이아웃일 수 있지만 대부분은 블록 및 인라인 레이아웃일 것입니다. 이 경우 기본적으로 발생하므로 아무 것도 할 필요가 없습니다.

머리글과 바닥글 정렬

지금 보았듯이 그리드에 카드 세트를 배치하고 가장 높은 카드만큼 높이를 표시하고 바닥글을 카드의 맨 아래로 밀어넣고 싶다면 CSS가 거의 필요하지 않습니다. . 위 예제의 레이아웃 CSS는 다음과 같습니다.

 .cards { display: grid; gap: 20px; grid-template-columns: 1fr 1fr 1fr; } article { display: grid; grid-template-rows: auto 1fr auto; row-gap: 20px; }

머리글과 바닥글의 배경색을 정렬하려면 어떻게 해야 할까요? 각 카드는 그리드 항목이지만 머리글과 바닥글은 항목의 그리드에 있습니다. 그들은 서로 관련이 없으므로 정렬할 수 없습니다. 여기서 자식을 통해 그리드를 어떻게든 상속할 수 있다면 좋을 것입니다.

3개의 행이 있는 부모에 그리드를 정의할 수 있다면 이 3개의 행에 카드를 배치하고 머리글, 콘텐츠 및 바닥글이 각각 행 중 하나에 놓이도록 합니다. 그렇게 하면 각 헤더가 같은 행에 있으므로 하나의 헤더가 더 커지면 전체 행이 커집니다.

오늘날 브라우저에는 이에 대한 좋은 솔루션이 없지만 현재 진행 중입니다. CSS 그리드 레이아웃 레벨 2의 서브 그리드 기능은 이 정확한 패턴을 가능하게 합니다. 부모에 그리드를 만든 다음 해당 그리드와 완전히 독립적인 child 요소에 새 그리드를 정의하는 대신 해당 그리드를 사용하도록 행 및/또는 열을 선택적으로 선택할 수 있습니다.

다음 예제는 Firefox Nightly에서 작성하는 시점에만 작동합니다. grid-template-columns grid-template-rows 의 하위 그리드 값은 CSS 그리드 사양 레벨 2의 새로운 기능이자 일부입니다. 이 기능을 사용하려면 Firefox Nightly 사본을 다운로드하십시오.

아래 이미지에서 이것이 어떻게 작동하는지 확인할 수 있습니다. 첫 번째 이미지에서 부모에 3개의 행 트랙을 만들고 카드를 가로질러 확장했습니다. Firefox Grid Inspector가 그리드를 강조 표시하면 부모의 행이 자식이 사용하는 행과 관련이 없음을 알 수 있습니다.

Firefox Grid Inspector 트랙이 오버레이된 3열 그리드 이미지.
Firefox Grid Inspector로 그리드를 검사하면 요소가 부모의 트랙에 표시되지 않는 것으로 나타납니다. (큰 미리보기)

자식에 대한 세 개의 행을 정의하는 대신 grid-template-rows 에 대한 하위 그리드 값을 사용하는 경우 카드는 이제 부모의 해당 행을 사용합니다. 이제 두 가지가 어떻게 정렬되어 머리글과 바닥글도 정렬되는지 확인할 수 있습니다.

카드 내부의 모든 요소가 정렬된 3열 그리드의 이미지입니다.
서브그리드를 사용하면 카드의 각 부분이 자체 트랙으로 이동합니다(큰 미리보기).

여기서 subgrid로 하는 것은 display 의 새로운 값이 아닙니다. 하위 그리드인 항목은 display: grid 를 설정한 대로 그리드 컨테이너 자체입니다. 그리드 항목은 일반적으로 그리드 항목처럼 작동합니다. 이것은 일반 격자 레이아웃입니다. 고유한 행 트랙 크기가 있는 항목 대신에 상위 항목의 트랙을 사용한다는 점을 제외하면 원래 중첩 격자와 다르지 않습니다.

 .cards { display: grid; gap: 20px; grid-template-columns: 1fr 1fr 1fr; grid-template-rows: repeat(2,auto 1fr auto); } article { grid-row-end: span 3; display: grid; grid-template-rows: subgrid; }

이것이 서브그리드의 좋은 점입니다. 그리드 레이아웃을 사용하는 방법을 이미 알고 있다면 배울 것이 많지 않습니다. 나머지 세부 사항은 Smashing Magazine의 "CSS Grid Level 2: Here Comes Subgrid"의 이전 게시물에서 읽을 수 있습니다.

어제(2019년 5월 23 ) 하위 그리드가 Firefox Nightly에 상륙하여 grid-template-columnsgrid-template-rows 의 하위 그리드 값에 대한 테스트 가능한 구현이 있습니다. Nightly를 구입하여 사용해 보십시오. Nightly 사본을 사용하면 이 CodePen에서 작동하는 최종 예제를 볼 수 있습니다.

펜 디스플레이를 참조하십시오. Rachel Andrew의 하위 그리드는 우리가 원하는 것이 아닙니다.

펜 디스플레이를 참조하십시오. Rachel Andrew의 하위 그리드는 우리가 원하는 것이 아닙니다.

서브그리드 기능을 사용하여 해결할 수 있는 다른 사용 사례나 누락되었다고 생각되는 사항을 생각할 수 있는지 확인하십시오. 기능은 Nightly 브라우저에서만 사용할 수 있지만 문제가 발견되면 사양을 변경할 수 있습니다. 따라서 미래의 웹 개발 자체에 호의를 베풀고 웹 플랫폼에 기여하고 상황을 개선하는 데 도움이 될 수 있도록 이와 같은 기능을 사용해 보십시오.

Firefox 구현에서 버그를 발견했다고 생각되면 종속 항목 섹션에서 관련 문제로 연결되는 Bugzilla의 주요 구현 버그를 살펴볼 수 있습니다. 문제가 보이지 않으면 가능한 한 간단한 축소 테스트 케이스를 만들고 버그를 제기하세요. 서브그리드가 유스 케이스를 해결하기 위해 무언가를 해야 한다고 생각하고 사양에 자세히 설명되어 있지 않은 경우 잠재적인 개선을 위해 CSS 작업 그룹 GitHub에 문제를 제기할 수 있습니다.

display: contents 어떻습니까?

따라오셨다면 display: contents ( display 에 대한 이전 기사에서 설명)가 subgrid가 해결하고자 하는 문제, 즉 간접 자식이 그리드 레이아웃에 참여할 수 있도록 하는 문제를 해결할 수 있다고 생각할 수 있습니다. 그것은 사실이 아니며 우리의 카드 예는 차이점을 보여주는 완벽한 방법입니다.

display: grid 를 사용하여 카드를 그리드 레이아웃으로 만드는 대신 display: contents 를 사용하여 상자를 제거하면 다음 CodePen에서 이 결과를 얻을 수 있습니다. (차이를 확인하려면 .card 규칙에서 display: contents 줄을 제거해 보세요.)

펜 디스플레이를 참조하십시오. Rachel Andrew의 하위 그리드는 우리가 원하는 것이 아닙니다.

펜 디스플레이를 참조하십시오. Rachel Andrew의 하위 그리드는 우리가 원하는 것이 아닙니다.

이 예에서는 카드 상자가 제거되어 머리글, 콘텐츠 및 바닥글이 그리드 레이아웃에 직접 참여하고 그리드 전체에 자동 배치됩니다. 이것은 우리가 전혀 원했던 것이 아닙니다! 지난 기사에서 언급한 브라우저의 접근성 문제가 해결되면 display의 contents 값은 정말 도움이 될 것이지만, 우리가 탐구하는 것과 다른 문제를 해결합니다.

더 많은 읽을거리와 예

저는 모든 사람들이 서브그리드를 이해하는 데 도움이 되도록 많은 예제와 데모를 만들고 있습니다. 아래 링크에서 시도해 볼 수 있습니다.

  • CSS 그리드 레벨 2 예제
  • CSS 그리드 레벨 2: 하위 그리드가 온다
  • Grids All The Way Down(프레젠테이션)
  • 서브그리드용 MDN 문서