그리드

웹 페이지의 레이아웃을 구성할 때 float플렉스박스를 사용하는데, 그리드가 새로운 기능으로 추가됨으로써 가로축과 세로축을 동시에 다루는 2차원적 레이아웃을 만들 수 있게 되었다. 대부분의 최신 웹 브라우저들은 그리드를 지원하고 있다.

플렉스박스의 경우와 마찬가지로, 그리드 역시 그리드 컨테이너와 그리드 요소로 나누어 생각해볼 수 있다. 그리드를 적용하려면 컨테이너에 display: grid 혹은 display: inline-grid 스타일을 적용한다.

행과 열 만들기

기본적으로 그리드는 1개의 열로 되어 있다. 따라서 그리드 컨테이너의 하위에 그리드 요소가 여러 개일 경우 그리드는 n행 1열이 된다. 그리드의 행과 열을 정의하려면 그리드 컨테이너에 속성을 정의한다.

.grid {
  display: grid;
  width: 720px;
  grid-template-columns: 240px 240px 240px;
}

grid-template-columns 속성으로 그리드에 240px만큼의 폭을 갖는 열 3개를 갖게 했다. 그리드 컨테이너의 하위 요소로 그리드 요소가 추가되면 3개까지는 첫 행에 배치될 것이고, 네번째로 추가되는 그리드 요소는 다음 행에 배치될 것이다.

행을 추가할 때도 열을 추가하는 것과 마찬가지로 그리드 컨테이너에 속성을 정의한다.

.grid {
  display: grid;
  width: 720px;
  height: 500px;
  grid-template-columns: 240px 240px 240px;
  grid-template-rows: 10% 80% 10%;
}

grid-template-rows 속성을 추가하여 3행 3열의 그리드를 만들었다. 상대 단위를 사용하여 그리드 요소의 크기를 지정하면 각각의 그리드는 그리드 컨테이너에 정의된 크기에 따라 분할되는데, 위 코드에서 그리드의 각 행은 그리드 컨테이너 높이로 정의한 값을 10%, 80%, 10%만큼 나누어 갖게 된다.

그리드의 크기를 지정할 때 한 속성의 값으로 다양한 단위를 섞어 쓸 수 있다.

.grid {
  display: grid;
  width: 720px;
  height: 500px;
  grid-template-columns: 33% 15rem 240px;
  grid-template-rows: 10% 400px 10%;
}

grid-template-columnsgrid-template-rowsgrid-template 속성으로 같이 묶어 사용할 수 있다. 이때에는 행과 관련된 값(grid-template-rows)을 먼저 적고 슬래시(/)로 구분한 다음 열과 관련된 값(grid-template-columns)을 적는다. 위의 코드를 grid-template로 묶을 때는 다음과 같이 쓴다.

.grid {
  /* ... */
  grid-template: 10% 400px 10% / 33% 15rem 240px;
}

프랙션

프랙션(fraction, fr)은 그리드의 크기를 일정 비율에 따라 나눌 수 있도록 새로 도입된 단위이다.

앞에서 만든 그리드는 그리드 컨테이너 높이의 10%, 80%, 10%를 행의 크기로 갖고, 그리드 컨테이너 너비의 3분의 1씩을 열의 크기로 가졌다. 이러한 그리드의 크기를 프랙션을 이용해 코드를 다시 작성하면 다음과 같다.

.grid {
  display: grid;
  width: 720px;
  height: 500px;
  grid-template: 1fr 8fr 1fr / 1fr 1fr 1fr;
}

이제 그리드의 행은 그리드 컨테이너의 높이인 500px을 1:8:1로 나눈 크기를 가지며, 그리드의 열은 그리드 컨테이너의 너비인 720px을 1:1:1로 나눈 크기를 갖는다.

물론 기존에 사용하는 단위인 픽셀이나 퍼센티지 등을 프랙션과 섞어 사용할 수도 있다.

.grid {
  display: grid;
  width: 720px;
  grid-template-columns: 1fr 1fr 50px;
}

이 그리드의 경우 세번째 열에 50px의 너비가 정해져 있으므로 그리드 컨테이너의 너비에서 세번째 열의 너비를 뺀 만큼의 값을 나머지 열들이 나눠 갖는다. 따라서 첫번째 열과 두번째 열의 너비는 335px이 된다.

함수

repeat

행이나 열에 같은 값을 계속해서 정의해야 한다면 repeat() 함수를 써볼 수도 있다.

.grid {
  display: grid;
  width: 960px;
  grid-template-columns: repeat(12, 80px);
}

repeat()에는 두 개의 인수를 전달하는데, 첫번째 인수는 만들 행이나 열의 갯수이며, 두번째 인수는 기준이 되는 행이나 열의 크기이다. 위 코드는 80px의 너비를 갖는 열을 12개 만든다. 위 repeat(12, 80px)는 프랙션을 단위로 사용하여 repeat(12, 1fr)로 쓸 수도 있다.

또한 repeat()의 두번째 인수로 전달하는 크기는 한 행이나 한 열의 크기만을 전달해야 하는 것은 아니다. grid-template-rows: repeat(3, 270px 30px);라는 코드를 작성할 경우, 270px 높이를 갖는 행과 30px 높이를 갖는 행을 만들기를 세번 반복하여 총 6개의 행을 만들게 된다.

minmax

minmax() 함수는 그리드를 만들 떄 크기의 최소값과 최대값을 설정할 수 있게 해준다.

.grid {
  display: grid;
  grid-template-columns: 100px minmax(100px, 500px) 100px;
}

이 그리드의 첫번째와 세번째 열은 항상 100px의 크기를 가지지만, 두번째 열에는 minmax() 함수를 사용했다. 두번째 열의 크기는 그리드 컨테이너의 너비가 변함에 따라 100px에서 500px 사이의 값을 갖게 된다.

그리드의 행과 행 사이, 열과 열 사이의 빈 공간을 갭(gap)이라 하며, 그리드 컨테이너에 grid-column-gap이나 grid-row-gap 속성을 사용하여 값을 정의할 수 있다.

.grid {
  display: grid;
  width: 720px;
  grid-template-columns: repeat(3, 1fr);
  grid-column-gap: 10px;
}

이 코드에서는 720px 너비의 그리드 컨테이너를 만들고 1:1:1의 비율로 3개의 열을 만들었다. 그리고 grid-column-gap 속성을 통해 10px의 갭을 각각의 열 사이에 부여했다.

grid-column-gapgrid-row-gap을 각각 쓰지 않고 grid-gap 속성으로 줄여 쓸 수도 있다. grid-template 속성과 마찬가지로 행 사이의 갭을 먼저 작성하고 열 사이의 갭을 작성하는데, 슬래시가 아닌 공백으로 구분한다. 따라서 행 사이에는 20px, 열 사이에는 10px의 갭을 주고 싶다면 grid-gap: 20px 10px;로 쓴다. grid-gap: 15px;처럼 값을 하나만 쓸 경우 행과 열 모두에 같은 값인 15px의 갭을 적용하게 된다.

여러 줄에 걸치기

앞에서 살펴본 방법으로 만든 그리드에는 그리드 요소가 한 칸만을 차지한다. 하지만 한 요소가 그리드의 여러 칸을 차지하게 해야 할 필요도 있다.

그리드 요소에 grid-row-start 속성과 grid-row-end 속성을 사용하면 그리드 요소를 여러 행에 걸치게 할 수 있다. 다음 코드에서 .element 요소는 그리드의 1행부터 4행까지를 차지하게 된다.

.element {
  grid-row-start: 1;
  grid-row-end: 5;
}

그리드 요소를 여러 열에 걸치게 하려면 grid-column-start 속성과 grid-column-end 속성을 사용하면 된다.

그리드의 행과 열은 1부터 시작하며, 음수 값을 가질 수도 있다. 음수 값은 그리드의 끝을 의미한다. 그리드 요소에 grid-row-start: 1; grid-row-end: -2;라는 스타일을 적용할 경우 그리드 요소는 첫번째 행부터 끝에서 두번째 행까지 걸치게 된다.

그리드를 여러 줄에 걸치고자 할 때 span이라는 값을 사용할 수도 있다. 그리드 요소에 grid-column-start: span 3;이라는 스타일을 적용하면 요소는 현재 자신의 위치를 시작으로 하여 오른쪽으로 두칸 더 크기를 확장하게 된다. span을 이용하여 요소를 그리드의 2열에서 4열에 걸치게 하려면 다음과 같이 스타일을 적용한다.

.element {
  grid-column-start: 2;
  grid-column-end: span 3;
}

grid-row-start 속성과 grid-row-end 속성은 grid-row 속성으로, grid-column-start 속성과 grid-column-end 속성은 grid-end 속성으로 줄여 쓸 수 있다. -start의 값을 먼저 쓰고 슬래시(/)로 구분한 다음 -end의 값을 쓴다. 앞서 작성한 두 코드는 다음과 같이 줄여 쓸 수 있다.

.element {
  grid-row: 1 / 5;
  grid-column: 2 / span 3;
}

grid-area 속성을 사용하면 이 값들을 한 줄의 코드로 쓸 수 있는데, grid-row-start, grid-column-start, grid-row-end, grid-column-end 순서로 값을 작성하며 각각의 값은 슬래시로 구분한다. 위의 코드를 grid-area를 사용해 쓰면 다음과 같다.

.element {
  grid-area: 1 / 2 / 5 / span 3;
}

그리드의 이름표

그리드 컨테이너의 grid-template-areas 속성과 그리드 요소의 grid-area 속성으로 그리드에 이름을 붙여 사용할 수도 있다.

<div class="container">
  <header>사이트 로고</header>
  <nav>글로벌 내비게이션</nav>
  <section class="submenu">서브메뉴</section>
  <section class="contents">콘텐츠</section>
  </footer>푸터</footer>
</div>
.container {
  display: grid;
  max-width: 960px;
  margin: 0 auto;
  grid-template-areas: "header header"
                       "nav nav" 
                       "submenu article"
                       "footer footer";
  grid-template-rows: 220px 80px minmax(400px, 1000px) 150px;
  grid-template-columns: 1fr 3fr; 
}

header {
  grid-area: header;
} 

nav {
  grid-area: nav;
} 

.submenu {
  grid-area: submenu;
} 

.article {
  grid-area: article;
}

footer {
  grid-area: footer;
}

그리드 요소로 사용하는 요소에는 grid-area 속성으로 요소의 이름을 붙였다. 그리고 그리드 컨테이너에 grid-template-areas 속성을 사용하여 이름을 그리드에 배치하여 어떤 위치에 어떤 요소가 자리할 지를 정했다.

따라서 위 코드는 4행 2열의 그리드를 만들지만, HTML은 다섯 부분으로 나뉘어져 있다. header 요소가 첫번째 행의 두 열을 모두 차지하고, nav 요소가 두번째 행의 두 열을 모두 차지하며, 세번째 행은 div.submenudiv.article 요소가 각각 한 열씩 차지하고 있다. 그리고 네번째 행은 footer 요소가 두 열을 모두 차지하고 있다.

요소 겹치기

그리드 요소에 z-index 속성을 적용하면 요소들을 서로 겹치게 할 수 있다.

<div class="image">
  <h1 class="title">제목</h1>
  <img src="#">
  <p class="description">이미지 설명</p>
</div>
.image {
  display: grid;
  grid-template: repeat(6, 1fr) / repeat(4, 1fr);
}

.title {
  grid-area: 3 / 1 / 5 / 5;
  z-index: 10;
}

.description {
  grid-area: 5 / 1 / 7 / 4;
}

img {
  grid-area: 1 / 3 / 4 / 5;
}

위 코드의 6행 4열 그리드에서 img 요소는 1행 3열부터 3행 4열까지를 차지하고, p.description 요소는 5행 1열부터 6행 3열까지를 차지한다. 그리고 h1.title 요소는 3행 1열부터 4행 4열까지를 차지한다. 여기에서 3행 3열과 4열은 img 요소와 h1.title 요소가 서로 겹치는데, 기본적으로는 HTML 코드에서 나중 요소인 img가 이전 요소인 h1.title보다 위에 나타나도록 렌더링된다. 따라서 h1.titlez-index 속성을 주어 h1.title 요소가 img 요소를 덮을 수 있도록 했다.

그리드 요소의 정렬

그리드 컨테이너에 justify-items 속성을 적용하면 그리드 요소들을 가로축에서 적절한 위치에 배치시킬 수 있다.

  • start: 그리드 요소가 열의 왼쪽을 기준으로 배치된다(요소의 크기가 열의 크기보다 작을 경우 오른쪽에 빈 공간을 남긴다).
  • end: 그리드 요소가 열의 오른쪽을 기준으로 배치된다(요소의 크기가 열의 크기보다 작을 경우 왼쪽에 빈 공간을 남긴다).
  • center: 그리드 요소가 열의 가운데를 기준으로 배치된다(요소의 크기가 열의 크기보다 작을 경우 좌우에 빈 공간을 남긴다).
  • stretch: 그리드 요소의 크기가 열의 너비를 채우기 위해 변한다.

어느 한 그리드 요소에만 속성을 적용하고 싶다면 justify-self 속성을 적용한다. justify-items의 값을 동일하게 사용할 수 있으며 여기에 상위 요소의 값을 상속받는 auto 값을 추가로 사용할 수 있다.

그리드 컨테이너에 justify-content 속성을 적용하면 전체 그리드 요소를 가로로 정렬할 수 있다.

  • start: 그리드 요소들이 그리드 컨테이너 안에서 왼쪽 정렬된다.
  • end: 그리드 요소들이 그리드 컨테이너 안에서 오른쪽 정렬된다.
  • center: 그리드 요소들이 그리드 컨테이너 안에서 가운데 정렬된다.
  • stretch: 그리드 요소들의 크기가 그리드 컨테이너의 너비를 채우도록 변한다.
  • space-around: 그리드 요소들이 좌우로 같은 크기의 빈 공간을 갖는다. 따라서 그리드 요소들 사이의 빈 공간 크기는 그리드 컨테이너의 왼쪽 끝부터 행의 첫번째 그리드 요소가 나타나기까지의 사이 또는 행의 마지막 그리드 요소가 끝나고부터 그리드 컨테이너의 오른쪽 끝 사이의 공간 크기의 2배이다.
  • space-between: 그리드 요소들이 같은 크기의 빈 공간을 사이에 두고 배치된다. 이 속성을 사용할 경우 행의 첫번째 그리드 요소는 그리드 컨테이너의 왼쪽 끝에, 행의 마지막 그리드 요소는 그리드 컨테이너의 오른쪽 끝에 빈 공간 없이 배치된다.
  • space-evenly: 그리드 요소들이 끝에서부터 일정한 간격을 두고 배치된다. 그리드 컨테이너의 끝과 그리드 요소의 사이, 그리드 요소들간의 사이의 빈 공간 크기가 같다.

그리드 컨테이너에 align-items 속성을 적용하면 그리드 요소들을 세로축에서 적절한 위치에 배치시킬 수 있다.

  • start: 그리드 요소가 행의 위쪽을 기준으로 배치된다(요소의 크기가 행의 크기보다 작을 경우 아래쪽에 빈 공간을 남긴다).
  • end: 그리드 요소가 행의 아래쪽을 기준으로 배치된다(요소의 크기가 행의 크기보다 작을 경우 위쪽에 빈 공간을 남긴다).
  • center: 그리드 요소가 행의 가운데를 기준으로 배치된다(요소의 크기가 행의 크기보다 작을 경우 위아래로 빈 공간을 남긴다).
  • stretch: 그리드 요소의 크기가 행의 높이를 채우기 위해 변한다.

어느 한 그리드 요소에만 속성을 적용하고 싶다면 align-self 속성을 적용한다. align-items의 값을 동일하게 사용할 수 있으며 여기에 상위 요소의 값을 상속받는 auto 값을 추가로 사용할 수 있다.

그리드 컨테이너에 align-content 속성을 적용하면 전체 그리드 요소를 세로로 정렬할 수 있다.

  • start: 그리드 요소들이 그리드 컨테이너 안에서 위쪽 정렬된다.
  • end: 그리드 요소들이 그리드 컨테이너 안에서 아래쪽 정렬된다.
  • center: 그리드 요소들이 그리드 컨테이너 안에서 가운데 정렬된다.
  • stretch: 그리드 요소들의 크기가 그리드 컨테이너의 높이를 채우도록 변한다.
  • space-around: 그리드 요소들이 위아래로 같은 크기의 빈 공간을 갖는다. 따라서 그리드 요소들 사이의 빈 공간 크기는 그리드 컨테이너의 위쪽 끝부터 열의 첫번째 그리드 요소가 나타나기까지의 사이 또는 열의 마지막 그리드 요소가 끝나고부터 그리드 컨테이너의 아래쪽 끝 사이의 공간 크기의 2배이다.
  • space-between: 그리드 요소들이 같은 크기의 빈 공간을 사이에 두고 배치된다. 이 속성을 사용할 경우 열의 첫번째 그리드 요소는 그리드 컨테이너의 위쪽 끝에, 열의 마지막 그리드 요소는 그리드 컨테이너의 아래쪽 끝에 빈 공간 없이 배치된다.
  • space-evenly: 그리드 요소들이 끝에서부터 일정한 간격을 두고 배치된다. 그리드 컨테이너의 끝과 그리드 요소의 사이, 그리드 요소들간의 사이의 빈 공간 크기가 같다.

자동으로 행과 열 만들기

지금까지의 그리드 관련 속성들은 그리드를 명시적으로 정의하는 것이었다. 명시적인 방법은 항상 보여줄 것이 정해져 있는 페이지를 만들 때에는 유용하지만, 보여줄 것의 양이 일정하지 않은, 특히 정해놓은 그리드의 갯수보다 더 많은 것을 보여줘야 하는 페이지는 만들 수 없다. 따라서 정해진 그리드보다 더 많은 요소를 보여줘야 할 경우의 동작 방식을 정할 수 있는 알고리즘이 그리드의 스펙에 포함되어 있는데, 이를 암시적 그리드라고 한다.

암시적 그리드의 동작 방법은 이렇다. 먼저 그리드 요소들이 행을 채우고, 새로운 행은 필요에 따라 추가되며, 추가된 행은 요소들의 크기만큼만 커진다.

암시적 그리드를 만드는 데 사용되는 속성은 grid-auto-rowsgrid-auto-columns이며, 그리드 컨테이너에 선언한다. 두 속성은 암시적으로 추가될 새로운 행 또는 열의 크기를 정의하는 속성으로, grid-template-rowsgrid-template-columns처럼 값과 단위를 지정하여 사용한다.

<div class="grid">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5</div>
</div>
.grid {
  display: grid;
  grid-template: repeat(2, 100px) / repeat(2, 100px);
  grid-auto-rows: 50px;
}

위 코드에서 그리드 컨테이너의 하위 요소는 5개이지만 grid-template 속성으로 정의된 그리드는 2행 2열이다. 다섯번째 요소는 grid-auto-rows 속성에 따라 새롭게 만들어지는 세번째 행의 첫번째 요소로 추가되는데, 이 요소의 크기는 첫번째와 두번째 행의 높이인 100px이 아닌 grid-auto-rows 속성에 정의된 50px이다. 속성을 선언하지 않는 경우, 새로 추가되는 행은 그리드 요소의 내용에 따라 높이가 조정된다.

행이 아닌 새로운 열을 만들어 요소를 추가하고자 할 때는 grid-auto-rows 대신 grid-auto-columns를 사용한다.

암시적으로 추가되는 행 또는 열의 크기를 설정하는 것 이외에도 렌더링되는 순서를 설정할 수도 있는데, 이때 사용하는 속성이 grid-auto-flow이다. 이 속성 또한 그리드 컨테이너에 선언한다.

  • row: 그리드 요소가 너무 많을 경우 새 행을 만들고 왼쪽에서 오른쪽으로 채워 나간다. 속성의 기본값이다.
  • column: 그리드 요소가 너무 많을 경우 새 열을 만들고 위에서 아래로 채워 나간다.
  • dense: 그리드 요소가 렌더링되고 남은 공간이 있을 때 새 요소가 그 자리를 채울 수 있는 크기일 경우 새 요소는 그 자리에 렌더링된다. rowcolumn과 함께 사용할 수 있다.

results matching ""

    No results matching ""