CSS 그리드 – 표 레이아웃이 다시 제공됩니다. 시청자와 친근하게 소통하세요.

Surma
Surma

요약

Flexbox에 익숙하다면 Grid도 익숙할 것입니다. 레이첼 앤드류는 시작하는 데 도움이 되는 멋진 CSS 그리드 전용 웹사이트를 운영하고 있습니다. 이제 Google Chrome에서 그리드를 사용할 수 있습니다.

Flexbox? 그리드?

지난 몇 년 동안 CSS Flexbox가 널리 사용되고 있으며 브라우저 지원도 매우 양호합니다(IE9 이하를 지원해야 하는 불쌍한 사람이 아니라면). Flexbox를 사용하면 요소 간의 등간격, 위에서 아래로의 레이아웃, CSS 마법의 핵심인 세로 중앙 정렬과 같은 많은 복잡한 레이아웃 작업을 더 쉽게 할 수 있습니다.

여러 Flexbox 컨테이너에서 요소를 정렬할 수 있는 방법은 없습니다.

하지만 화면에는 일반적으로 우리가 신경 써야 할 두 번째 측정기준이 있습니다. 요소의 크기를 직접 조정하지 않는 한, 불행히도 flexbox만 사용하여 세로 리듬과 가로 리듬을 모두 가질 수는 없습니다. 여기에서 CSS 그리드가 유용합니다.

CSS 그리드는 5년 넘게 대부분의 브라우저에서 플래그 뒤에 숨겨져 개발 중이며, Flexbox와 같이 버그가 있는 출시를 방지하기 위해 상호 운용성에 추가 시간을 할애했습니다. 따라서 Chrome에서 그리드를 사용하여 레이아웃을 구현하면 Firefox와 Safari에서도 동일한 결과를 얻을 수 있습니다. 이 글을 작성하는 시점에서 Microsoft의 Edge 구현은 Grid가 오래되었으며 (IE11에 이미 있던 것과 동일) 업데이트는 '검토 중'입니다.

개념과 문법은 비슷하지만 Flexbox와 Grid를 경쟁하는 레이아웃 기법으로 생각해서는 안 됩니다. 그리드는 두 가지 크기로 정렬되지만 Flexbox는 하나의 크기로 레이아웃됩니다. 두 가지를 함께 사용하면 시너지 효과가 있습니다.

그리드 정의

그리드의 개별 속성을 숙지하려면 레이첼 앤드류의 Grid By Example 또는 CSS Tricks의 요약본을 참고하시기 바랍니다. Flexbox를 잘 알고 있다면 많은 속성과 속성의 의미에 익숙할 것입니다.

표준 12열 그리드 레이아웃을 살펴보겠습니다. 기본적인 12열 레이아웃은 숫자 12를 2, 3, 4, 6으로 나눌 수 있어 많은 디자인에 유용합니다. 이 레이아웃을 구현해 보겠습니다.

여러 Flexbox 컨테이너에서 요소를 정렬할 방법은 없습니다.

마크업 코드부터 시작해 보겠습니다.

<!DOCTYPE html>
<body>
    <header></header>
    <nav></nav>
    <main></main>
    <footer></footer>
</body>

스타일시트에서 먼저 body를 확장하여 전체 표시 영역을 포괄하도록 하고 그리드 컨테이너로 변환합니다.

html, body {
    width: 100vw;
    min-height: 100vh;
    margin: 0;
    padding: 0;
}
body {
    display: grid;
}

이제 CSS 그리드를 사용합니다. 축하합니다.

다음 단계는 그리드의 행과 열을 구현하는 것입니다. 모의 제작물에 12개의 열을 모두 구현할 수 있지만 모든 열을 사용하지 않으므로 이렇게 하면 CSS가 불필요하게 지저분해집니다. 편의상 레이아웃을 다음과 같이 구현합니다.

간소화된 레이아웃 예시

머리글과 바닥글의 너비는 가변적이며 콘텐츠는 두 측정기준 모두에서 가변적입니다. 탐색 메뉴도 두 측정기준에서 가변적이지만 최소 너비는 200픽셀로 설정됩니다. (이유가 무엇인가요? CSS 그리드의 기능을 보여주기 위함입니다.)

CSS 그리드에서 열과 행의 집합을 트랙이라고 합니다. 먼저 첫 번째 트랙 세트인 행을 정의해 보겠습니다.

body {
    display: grid;
    grid-template-rows: 150px auto 100px;
}

grid-template-rows는 개별 행을 정의하는 크기 시퀀스를 사용합니다. 이 경우 첫 번째 행의 높이는 150px이고 마지막 행의 높이는 100px입니다. 가운데 행은 auto로 설정되어 있습니다. 즉, 이 행의 그리드 항목 (그리드 컨테이너의 하위 요소)을 수용할 수 있는 필요한 높이로 조정됩니다. 본문은 전체 뷰포트에 걸쳐 늘어나므로 콘텐츠가 포함된 트랙(위 사진에서는 노란색)은 최소한 사용 가능한 모든 공간을 채우지만 필요한 경우 늘어나고 문서가 스크롤됩니다.

열의 경우 더 동적인 접근 방식을 취하려고 합니다. 탐색 메뉴와 콘텐츠가 모두 커졌다가 작아지기를 원하지만 탐색 메뉴는 200px 아래로 줄어들지 않아야 하며 콘텐츠는 탐색 메뉴보다 커야 합니다. Flexbox에서는 flex-grow와flex-축소를 사용하지만 그리드에서는 약간 다릅니다.

body {
    display: grid;
    grid-template-rows: 150px auto 100px;
    grid-template-columns: minmax(200px, 3fr) 9fr;
}

2개의 열을 정의합니다. 첫 번째 열은 minmax() 함수를 사용하여 정의되며, 이 함수는 트랙의 최소 크기와 최대 크기라는 두 개의 값을 사용합니다. min-widthmax-width를 하나로 합친 것과 같습니다. 앞서 설명한 대로 최소 너비는 200픽셀입니다. 최대 너비는 3fr입니다. fr는 사용 가능한 공간을 그리드 요소에 배포할 수 있는 그리드별 단위입니다. fr은 '분수 단위'를 의미할 수도 있지만 곧 무료 단위를 의미할 수도 있습니다. 여기서 값은 두 열이 모두 화면을 채우도록 늘어나지만 콘텐츠 열은 항상 탐색 열의 3배 너비가 된다는 것을 의미합니다 (탐색 열이 200px보다 넓게 유지되는 경우).

그리드 항목의 위치는 아직 올바르지 않지만 행과 열의 크기는 올바르게 작동하여 의도한 동작을 생성합니다.

상품 배치

Grid의 가장 강력한 기능 중 하나는 DOM 순서와 관계없이 항목을 배치할 수 있다는 것입니다. 하지만 스크린 리더는 DOM을 탐색하므로 올바르게 액세스할 수 있도록 요소를 재정렬하는 방법에 유의해야 합니다. 수동으로 배치하지 않으면 요소가 DOM 순서대로 그리드에 배치되며 왼쪽에서 오른쪽, 위에서 아래로 정렬됩니다. 각 요소는 하나의 을 차지합니다. 그리드가 채워지는 순서는 grid-auto-flow를 사용하여 변경할 수 있습니다.

그렇다면 요소를 어떻게 배치할까요? 그리드 항목을 배치하는 가장 쉬운 방법은 그리드 항목이 포함되는 열과 행을 정의하는 것입니다. 그리드는 이를 위한 두 가지 문법을 제공합니다. 첫 번째 문법에서는 시작점과 끝점을 정의합니다. 두 번째에서는 시작점과 범위를 정의합니다.

header {
    grid-column: 1 / 3;
}
nav {
    grid-row: 2 / span 2;
}
게재 시점 직접 설정

헤더가 첫 번째 열에서 시작하여 세 번째 열 에서 끝나도록 하려고 합니다. 탐색 메뉴는 두 번째 행에서 시작하여 총 2개 행에 걸쳐야 합니다.

기술적으로는 레이아웃 구현을 완료했지만 배치를 더 쉽게 할 수 있도록 그리드에서 제공하는 몇 가지 편리한 기능을 보여드리겠습니다. 첫 번째 기능은 트랙 테두리의 이름을 지정하고 이 이름을 배치에 사용할 수 있다는 것입니다.

body {
    display: grid;
    grid-template-rows: 150px [nav-start] auto 100px [nav-end];
    grid-template-columns: [header-start] minmax(200px, 3fr) 9fr [header-end];
}
header {
    grid-column: header-start / header-end;
}
nav {
    grid-row: nav-start / nav-end;
}

위의 코드는 이전 코드와 동일한 레이아웃을 생성합니다.

그리드에서 전체 영역에 이름을 지정하는 기능은 훨씬 더 강력합니다.

body {
    display: grid;
    grid-template-rows: 150px auto 100px;
    grid-template-columns: minmax(200px, 3fr) 9fr;
    grid-template-areas: "header header"
                        "nav    content"
                        "nav    footer";
}
header {
    grid-area: header;
}
nav {
    grid-area: nav;
}

grid-template-areas는 공백으로 구분된 이름 문자열을 사용하여 개발자가 각 셀에 이름을 지정할 수 있습니다. 인접한 두 ���의 이름이 동일하면 동일한 영역으로 병합됩니다. 이렇게 하면 레이아웃 코드에 더 많은 시맨틱을 제공하고 미디어 쿼리를 더 직관적으로 만들 수 있습니다. 이 코드도 이전과 동일한 레이아웃을 생성합니다.

더 있으신가요?

예, 블로그 게시물 한 편으로는 다 설명할 수 없을 만큼 많습니다. GDE이기도 한 레이첼 앤드류는 CSS 작업 그룹의 초대 전문가이며 Grid를 통해 웹 디자인을 간소화하기 위해 초기부터 작업 그룹과 협력해 왔습니다. 심지어 도 출간하기도 했습니다. 웹사이트 Grid By Example은 그리드를 익히는 데 유용한 리소스입니다. 많은 사람들이 그리드를 웹 디자인의 혁명적인 단계라고 생각하며, 이제 Chrome에서 기본적으로 사용 설정되어 있으므로 지금 바로 사용할 수 있습니다.