안녕하세요! 프론트엔드 강사입니다. CSS Grid를 공부하며 여기까지 오셨군요, 정말 고생 많으셨어요! 👏
지금까지 배운 그리드의 파편적인 개념들을 조합해서, "그럼 대체 실무에서는 이걸 어떻게 쓰는데?" 라는 궁금증을 싹 해결해 줄 아주 훌륭한 문서를 가져오셨네요. 공식 문서의 딱딱한 영어 문장들을 제가 현업 경험과 꿀팁들을 팍팍 섞어서 아주 편안하고 이해하기 쉽게 번역해 드리겠습니다. 준비되셨죠? 시작해 봅시다!
이 CSS 그리드 레이아웃 가이드 시리즈를 마무리하며, 그리드 레이아웃으로 디자인할 때 사용할 수 있는 여러 가지 기법을 보여주는 몇 가지 다른 레이아웃들을 함께 만들어 볼 거예요.
우리는 grid-template-areas를 사용하는 예제, 12-컬럼(12-column) 유연한 그리드 시스템, 그리고 자동 배치(auto-placement)를 활용한 제품 리스트(product listing)를 살펴볼 것입니다. 이번 예제 모음에서 알 수 있듯이, CSS 그리드 레이아웃으로 여러분이 원하는 결과를 얻는 방법은 대개 한 가지만 있는 것이 아닙니다. 여러분이 해결해야 할 문제와 구현해야 할 디자인에 가장 도움이 된다고 생각하는 방법을 선택하시면 된답니다.
👨🏫 강사의 팁: > CSS Grid에는 정답이 없습니다. 똑같은 디자인이어도 어떤 사람은
grid-template-areas로 그림 그리듯 짜고, 어떤 사람은 라인 번호나 12-컬럼 시스템으로 수학적으로 짭니다. 오늘 세 가지 대표적인 방법을 모두 배우게 되니, "내 스타일은 이거다!" 하는 걸 찾아보세요.
grid-template-areas를 사용해 1~3개의 유연한 단(column)을 가지는 반응형 레이아웃 만들기수많은 웹사이트들이 콘텐츠, 사이드바, 헤더, 그리고 푸터(footer)를 가지는 이런 형태의 레이아웃에서 조금씩 변형된 구조를 띕니다. 반응형 디자인에서는 기본적으로 레이아웃을 1단(single column)으로 보여주다가, 특정 브레이크포인트(breakpoint, 화면 크기가 변하는 기준점)에서 사이드바를 추가하고, 화면이 더 넓어지면 3단 레이아웃으로 나타나게 하고 싶을 거예요.

우리는 그리드 템플릿 영역(Grid template areas) 가이드에서 배웠던 이름이 지정된 템플릿 영역(named template areas) 기능을 사용해서 이 레이아웃을 만들어 볼 겁니다.
HTML 마크업은 하나의 컨테이너(wrapper) 안에 헤더, 푸터, 메인 콘텐츠, 내비게이션, 사이드바, 그리고 광고를 넣을 블록 요소들이 들어있는 형태입니다.
* {
box-sizing: border-box;
}
.wrapper {
max-width: 1024px;
margin: 0 auto;
font:
1.2em "Helvetica",
"Arial",
sans-serif;
}
.wrapper > * {
border: 2px solid #f08c00;
background-color: #ffec99;
border-radius: 5px;
padding: 10px;
}
nav ul {
list-style: none;
margin: 0;
padding: 0;
}
<div class="wrapper">
<header class="main-head">The header</header>
<nav class="main-nav">
<ul>
<li><a href="">Nav 1</a></li>
<li><a href="">Nav 2</a></li>
<li><a href="">Nav 3</a></li>
</ul>
</nav>
<article class="content">
<h1>Main article area</h1>
<p>
In this layout, we display the areas in source order for any screen less
that 500 pixels wide. We go to a two column layout, and then to a three
column layout by redefining the grid, and the placement of items on the
grid.
</p>
</article>
<aside class="side">Sidebar</aside>
<div class="ad">Advertising</div>
<footer class="main-footer">The footer</footer>
</div>
레이아웃을 만들기 위해 grid-template-areas를 사용할 것이므로, 미디어 쿼리(media queries) 바깥쪽에서 (모든 화면 크기에 공통으로 적용되도록) 각 영역의 이름을 먼저 지어주어야 합니다. 이름을 지을 때는 grid-area 속성을 사용합니다.
.main-head {
grid-area: header;
}
.content {
grid-area: content;
}
.main-nav {
grid-area: nav;
}
.side {
grid-area: sidebar;
}
.ad {
grid-area: ad;
}
.main-footer {
grid-area: footer;
}
지금 코드를 작성했다고 해서 바로 레이아웃이 만들어지는 것은 아닙니다. 대신, 레이아웃을 짤 때 가져다 쓸 수 있는 '이름표'를 아이템들에게 달아준 셈이죠.
이제 미디어 쿼리 밖에서 모바일(좁은 화면) 너비를 위한 기본 레이아웃을 설정할 차례입니다. 그리드 레이아웃과 접근성(Grid layout and accessibility) 가이드에서 설명했듯, HTML 소스의 논리적인 순서와 화면에 보이는 순서가 서로 엇갈리지(disconnect) 않도록 여기서는 HTML에 적힌 순서 그대로 유지할 거예요.
우리는 열(column)이나 행(row) 트랙을 명시적으로(직접) 정의하지 않았습니다. 왜냐하면 이 모바일 레이아웃은 기본적으로 단일 열(1단) 형태이며, 암시적 그리드(implicit grid) 안에서 각 아이템이 들어갈 행이 필요할 때마다 알아서 생성되기 때문입니다.
.wrapper {
display: grid;
gap: 20px;
grid-template-areas:
"header"
"nav"
"content"
"sidebar"
"ad"
"footer";
}
이제 모바일 레이아웃이 준비되었으니, @media 쿼리를 추가하여 두 개의 열(column)을 보여줄 만큼 화면 공간이 넉넉한 더 큰 화면에 맞춰 레이아웃을 변형해 보겠습니다.
@media (width >= 500px) {
.wrapper {
grid-template-columns: 1fr 3fr;
grid-template-areas:
"header header"
"nav nav"
"sidebar content"
"ad footer";
}
nav ul {
display: flex;
justify-content: space-between;
}
}
grid-template-areas의 값 부분에 마치 텍스트 아트로 그림을 그린 것처럼 레이아웃 형태가 잡히는 게 보이시죠?
header는 nav와 마찬가지로 두 개의 열 트랙을 모두 덮도록(span) 배치되었습니다. 세 번째 행 트랙에는 sidebar를 content 옆에 나란히 배치했습니다. 광고(ad) 콘텐츠는 네 번째 행 트랙에 두어 사이드바 바로 아래에 오도록 했고, 그 옆(content 아래)에는 footer를 두었습니다. 또한 내비게이션 아이템들을 한 줄에 고르게 배치하기 위해 CSS 플렉스박스 레이아웃(CSS flexible box layout)을 함께 사용했습니다.
이제 세 개의 열(3단) 레이아웃을 보여줄 수 있는 더 넓은 화면을 위한 마지막 브레이크포인트를 추가할 수 있습니다.
@media (width >= 700px) {
.wrapper {
grid-template-columns: 1fr 4fr 1fr;
grid-template-areas:
"header header header"
"nav content sidebar"
"nav content ad"
"footer footer footer";
}
nav ul {
flex-direction: column;
}
}
이 3단 레이아웃은 양옆에 1fr 비율을 가진 두 개의 사이드 열을 두고, 가운데에 4fr 크기를 가진 메인 열을 배치했습니다. 즉, 컨테이너의 사용 가능한 전체 공간을 총 6등분(1+4+1)하여, 양옆 열에 각각 1씩, 중앙에 4만큼의 비율로 공간을 할당한 것입니다.
이 레이아웃에서는 nav를 왼쪽 열에, content의 바로 옆에 배치했습니다. 오른쪽 열에는 sidebar를 두고 그 바로 밑에 광고(ad)를 배치했죠. footer는 이제 레이아웃의 가장 밑바닥 전체를 가로지르게(span) 됩니다. 이번에도 내비게이션을 정렬하기 위해 flexbox를 사용했지만, 가로가 아닌 세로 방향(column)으로 설정했습니다.
👨🏫 강사의 팁: >
grid-template-areas의 진짜 엄청난 장점이 바로 이거예요! 미디어 쿼리 안에서 아이템 하나하나에grid-column,grid-row를 다시 적어줄 필요 없이, 큰 도화지에 글자로 영역 이름만 재배치하면 전체 레이아웃이 마법처럼 바뀝니다. 시각적으로 너무 직관적이라 유지보수할 때 최고죠.
이 기본 예제는 브레이크포인트(화면 크기)에 따라 그리드 레이아웃을 어떻게 재배치할 수 있는지 보여줍니다. 특히, 여러 컬럼 환경에 맞게 ad 블록의 위치를 적절하게 바꾸는 부분에 주목해 보세요. 이처럼 '이름이 지정된 영역(named areas)'을 사용하는 방식은 특히 프로토타입(시안)을 잡는 단계에서 엄청나게 유용합니다. 그리드 위에서 요소들의 위치를 이것저것 바꿔보며 실험할 때 숫자보다 이름(문자열)을 사용하는 게 훨씬 쉽기 때문입니다.
수많은 CSS 프레임워크와 그리드 시스템들(Bootstrap 등)은 보통 12-컬럼이나 16-컬럼 유연한 그리드를 사용합니다. 우리는 CSS 그리드 레이아웃으로 이와 완벽하게 똑같은 시스템을 직접 만들 수 있습니다.
예를 들어, 12개의 1fr 크기 열 트랙을 가지고, 각 트랙의 시작 선 이름을 col-start로 지정한 12-컬럼 유연한 그리드를 만들어 보겠습니다. 이렇게 하면 col-start라는 이름이 붙은 12개의 그리드 라인이 생기게 됩니다.
👨🏫 강사의 팁:
"왜 하필 12인가요?" 라고 많이들 물어보시는데요. 12는 1, 2, 3, 4, 6으로 나누어 떨어지기 때문이에요! 절반(6칸), 3등분(4칸씩), 4등분(3칸씩) 등 화면을 다양한 비율로 쪼개기 가장 좋은 숫자라서 12-컬럼 시스템은 웹 디자인의 '국룰'로 자리 잡았습니다.
.wrapper {
max-width: 1024px;
margin: 0 auto;
font:
1.2em "Helvetica",
"Arial",
sans-serif;
}
.wrapper > * {
border: 2px solid #f08c00;
background-color: #ffec99;
border-radius: 5px;
padding: 10px;
}
.wrapper {
display: grid;
grid-template-columns: repeat(12, [col-start] 1fr);
gap: 20px;
}
이 그리드 시스템이 어떻게 작동하는지 보여드리기 위해, 래퍼(wrapper) 안에 4개의 자식 요소(child elements)를 넣어 두었습니다.
<div class="wrapper">
<div class="item1">Start column line 1, span 3 column tracks.</div>
<div class="item2">
Start column line 6, span 4 column tracks. 2 row tracks.
</div>
<div class="item3">Start row 2 column line 2, span 2 column tracks.</div>
<div class="item4">
Start at column line 3, span to the end of the grid (-1).
</div>
</div>
이제 이름이 지정된 라인(named lines)과 span 키워드를 사용해 이 요소들을 그리드 위에 배치할 수 있습니다.
.item1 {
grid-column: col-start / span 3;
}
.item2 {
grid-column: col-start 6 / span 4;
grid-row: 1 / 3;
}
.item3 {
grid-column: col-start 2 / span 2;
grid-row: 2;
}
.item4 {
grid-column: col-start 3 / -1;
grid-row: 3;
}
이름이 지정된 그리드 라인 사용하기 가이드에서 설명했듯, 우리는 라인의 '이름'을 이용해서 아이템을 배치하고 있습니다. 우리는 똑같은 이름을 가진 12개의 라인이 있기 때문에, 그 이름 뒤에 인덱스(번호)를 붙여서 특정 라인을 가리킬 수 있습니다(col-start 6 처럼요). 만약 이게 번거롭다면 굳이 이름을 짓지 않고 그냥 라인 숫자(인덱스)만 사용하셔도 무방합니다.
끝나는 라인의 번호를 직접 적어주는 대신, 이 요소가 몇 개의 트랙을 덮어야(span) 하는지 정의하기 위해 span 키워드를 사용했습니다. 다단 레이아웃 시스템(multiple-column layout system)으로 작업할 때, 블록을 "그리드의 몇 칸을 차지하게 할 것인가?"의 관점에서 생각하고 화면 크기에 맞춰 조정하는 사람들에게는 이 방식이 훨씬 더 직관적일 수 있습니다.
블록들이 트랙에 어떻게 정렬되어 있는지 시각적으로 확인하고 싶다면, 브라우저 개발자 도구의 그리드 인스펙터(Grid inspector)를 켜보세요. 아이템들이 어떻게 배치되었는지 아주 명확하게 보여줄 것입니다.

행(row)을 만들기 위해 HTML에 추가적인 래퍼나 마크업을 넣을 필요가 없다는 점을 기억하세요! 과거의 CSS 프레임워크(ex: 과거의 Bootstrap)들은 CSS Grid를 지원하지 않는 구형 브라우저에서 요소가 위쪽 줄로 엉뚱하게 튀어 올라가는 것을 막기 위해 강제로 빈 row 태그를 만들곤 했습니다.
하지만 이젠 논의할 필요조차 없죠 — 모든 최신 브라우저가 CSS 그리드 레이아웃을 오랫동안 완벽하게 지원하고 있으니까요. CSS 그리드를 사용하면 요소를 원하는 행에 마음대로 꽂아 넣을 수 있고, 윗부분이 텅 비어있다고 해서 아이템이 위로 끌려 올라갈 위험이 없습니다.
이렇게 엄격한(strict) 행렬 배치 시스템 덕분에 레이아웃에 여백(white space)을 남기는 것도 아주 쉬워졌습니다. 아이템을 들여쓰기 하기 위해 특별한 여백용 클래스를 만들 필요도 없습니다. 그저 아이템이 시작하고 끝날 라인만 딱 지정해주면 됩니다.
이 방법이 실무에서 어떻게 쓰이는지 보기 위해, 아까 grid-template-areas로 만들었던 것과 똑같은 레이아웃을 이번에는 12-컬럼 그리드 시스템을 사용해서 만들어 보겠습니다. 마크업은 첫 번째 예제에서 썼던 것과 똑같이 시작할게요.
* {
box-sizing: border-box;
}
.wrapper {
max-width: 1024px;
margin: 0 auto;
font:
1.2em "Helvetica",
"Arial",
sans-serif;
}
.wrapper > * {
border: 2px solid #f08c00;
background-color: #ffec99;
border-radius: 5px;
padding: 10px;
}
nav ul {
list-style: none;
margin: 0;
padding: 0;
}
<div class="wrapper">
<header class="main-head">The header</header>
<nav class="main-nav">
<ul>
<li><a href="">Nav 1</a></li>
<li><a href="">Nav 2</a></li>
<li><a href="">Nav 3</a></li>
</ul>
</nav>
<article class="content">
<h1>Main article area</h1>
<p>
In this layout, we display the areas in source order for any screen less
that 500 pixels wide. We go to a two column layout, and then to a three
column layout by redefining the grid, and the placement of items on the
grid.
</p>
</article>
<aside class="side">Sidebar</aside>
<div class="ad">Advertising</div>
<footer class="main-footer">The footer</footer>
</div>
가장 먼저 위에서 했던 것처럼 12-컬럼 그리드의 뼈대를 세팅해 줍니다.
.wrapper {
display: grid;
grid-template-columns: repeat(12, [col-start] 1fr);
gap: 20px;
}
이번에도 이름이 지정된 라인을 사용해서 이 레이아웃을 반응형으로 만들어 보겠습니다. 모든 브레이크포인트에서 동일하게 12-컬럼 그리드를 사용하지만, 화면 크기에 따라 아이템이 덮는(span) 트랙의 칸 수만 바꿀 겁니다.
모바일 퍼스트(Mobile First) 전략으로 시작해 볼게요. 가장 좁은 화면에서는 아이템들이 소스(HTML) 순서대로 배치되고, 모든 아이템이 12칸 전체를 다 덮도록 만들겠습니다.
.wrapper > * {
grid-column: col-start / span 12;
}
그다음 화면이 약간 커진 브레이크포인트에서는 2단(two-column) 레이아웃을 원합니다. 헤더와 내비게이션은 여전히 그리드 12칸을 꽉 채워야 하므로 위치 값을 굳이 건드릴 필요가 없습니다.
사이드바(side)는 첫 번째 컬럼 라인인 col-start(혹은 col-start 1)에서 시작하여 3칸(span 3)을 덮습니다. 헤더와 내비게이션이 이미 1행과 2행에 자리를 차지하고 있으므로, 사이드바는 자연스럽게 3번째 행(grid-row: 3)으로 가도록 지정합니다.
광고(ad) 패널은 사이드바 바로 아래인 4번째 행(grid-row: 4)에서 시작합니다. 그리고 메인 콘텐츠(content)와 푸터(footer)는 col-start 4부터 시작해 9칸을 덮도록(span 9) 설정하여, 둘 다 화면 오른쪽 끝까지 가득 차게 만듭니다.
@media (width >= 500px) {
.side {
grid-column: col-start / span 3;
grid-row: 3;
}
.ad {
grid-column: col-start / span 3;
grid-row: 4;
}
.content,
.main-footer {
grid-column: col-start 4 / span 9;
}
nav ul {
display: flex;
justify-content: space-between;
}
}
마지막으로, 우리가 설정한 가장 넓은 브레이크포인트 이상의 화면에서는 3단 레이아웃을 적용합니다. 헤더는 변함없이 전체를 덮지만, 이제 내비게이션(nav)이 아래로 내려와 첫 번째 사이드바 역할을 하고, 메인 콘텐츠(content), 두 번째 사이드바(side)가 그 옆에 차례대로 놓입니다. 푸터(footer) 역시 가장 밑바닥 전체를 덮도록 수정합니다.
@media (width >= 700px) {
.main-nav {
grid-column: col-start / span 2;
grid-row: 2 / 4;
}
.content {
grid-column: col-start 3 / span 8;
grid-row: 2 / 4;
}
.side {
grid-column: col-start 11 / span 2;
grid-row: 2;
}
.ad {
grid-column: col-start 11 / span 2;
grid-row: 3;
}
.main-footer {
grid-column: col-start / span 12;
}
nav ul {
flex-direction: column;
}
}
이번에도 브라우저 개발자 도구의 그리드 인스펙터를 확인해서 레이아웃이 어떻게 형태를 갖추었는지 꼭 확인해 보세요.

👨🏫 강사의 팁: > 이 레이아웃을 만들면서 꼭 눈여겨봐야 할 점이 있습니다. 바로 브레이크포인트마다 모든 요소의 위치를 일일이 재설정하지 않았다는 거예요! "모바일 퍼스트" 접근법의 가장 큰 장점이죠. 좁은 화면의 속성을 넓은 화면이 그대로 상속(inherit)받고, 필요한 부분만 덮어쓰기 때문에 코드가 훨씬 깔끔해집니다. 게다가 요소들이 논리적인 순서대로 적혀있기 때문에 브라우저의 '그리드 자동 배치'가 알아서 빈 곳을 척척 찾아준 덕분에 우리가 코드를 덜 짤 수 있었던 거랍니다.
이 가이드의 마지막 예제에서는, 온전히 '자동 배치(auto-placement)'에 의존하는 레이아웃을 만들어 보겠습니다.
수많은 레이아웃들이 본질적으로 제품 목록, 이미지 갤러리 같은 여러 "카드(cards)" 들의 집합입니다. 그리드를 사용하면 미디어 쿼리(media queries)로 복잡한 브레이크포인트를 추가하지 않고도, 너무나 우아하고 유연하게 반응형 리스트를 만들 수 있습니다. 이 예제에서는 CSS 그리드와 플렉스박스(flexbox)를 환상적으로 결합하여 기본적인 제품 리스트 레이아웃을 짤 것입니다.
리스트의 HTML 마크업은 간단한 <ul> 태그 목록입니다. 각각의 카드 아이템(li) 안에는 제목(h2), 길이가 제각각인 텍스트 본문(p), 그리고 맨 아래에 CTA(Call to Action - 클릭 유도 버튼/링크)가 들어있습니다.
<ul class="listing">
<li>
<h2>Item One</h2>
<div class="body">
<p>The content of this listing item goes here.</p>
</div>
<div class="cta">
<a href="">Call to action!</a>
</div>
</li>
<li>
<h2>Item Two</h2>
<div class="body">
<p>The content of this listing item goes here.</p>
</div>
<div class="cta">
<a href="">Call to action!</a>
</div>
</li>
<li class="wide">
<h2>Item Three</h2>
<div class="body">
<p>The content of this listing item goes here.</p>
<p>This one has more text than the other items.</p>
<p>Quite a lot more</p>
<p>Perhaps we could do something different with it?</p>
</div>
<div class="cta">
<a href="">Call to action!</a>
</div>
</li>
<li>
<h2>Item Four</h2>
<div class="body">
<p>The content of this listing item goes here.</p>
</div>
<div class="cta">
<a href="">Call to action!</a>
</div>
</li>
<li>
<h2>Item Five</h2>
<div class="body">
<p>The content of this listing item goes here.</p>
</div>
<div class="cta">
<a href="">Call to action!</a>
</div>
</li>
</ul>
우리는 유연한 열(column) 개수와 너비를 가진 그리드를 생성할 것입니다. 각 열은 "최소 200px 이상이어야 하고, 화면에 남는 여백이 있다면 모두가 1:1로 공평하게 나눠 가져라"라고 설정할 거예요. 이렇게 하면 열 너비가 항상 완벽하게 일치하게 됩니다.
이를 구현하기 위해 트랙 크기를 정의하는 repeat() 문법 안에 마법의 함수, minmax()를 사용할 겁니다.
.listing {
list-style: none;
margin: 2em;
display: grid;
gap: 20px;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
}
👨🏫 강사의 팁:
이 코드는 가히 혁명적입니다.repeat(auto-fill, minmax(200px, 1fr))를 쓰면@media쿼리를 하나도 쓰지 않아도 화면이 넓어지면 카드가 4개, 5개로 늘어나고, 스마트폰처럼 좁아지면 1개로 착 접힙니다. 현업에서 카드 리스트 뷰를 짤 때 묻지도 따지지도 않고 가장 먼저 타이핑하는 코드랍니다!
이 CSS를 추가하면 아이템들이 그리드로 예쁘게 배치됩니다. 브라우저 창을 키우거나 줄여보세요. 미디어 쿼리를 쓰지 않았고 그리드를 재정의하지도 않았는데, 열의 개수가 유동적으로 변하는 것을 볼 수 있습니다.
이제 각각의 카드(박스) 안쪽의 내용물들을 플렉스박스(flexbox)로 살짝 다듬어 주겠습니다. 리스트 아이템(li)에 display: flex를 주고 flex-direction을 column으로 설정합니다. 이렇게 하면 카드 내부의 콘텐츠가 세로로 떨어지게 되죠.
그다음, 버튼 영역(.cta)에 margin-block-start: auto (위쪽 마진을 auto로 설정)를 줘서, 본문 내용이 얼마나 짧든 길든 상관없이 버튼이 무조건 카드 맨 밑바닥에 딱 붙게 밀어버립니다!
.listing li {
border: 1px solid #ffe066;
border-radius: 5px;
display: flex;
flex-direction: column;
}
.listing .cta {
margin-block-start: auto;
border-block-start: 1px solid #ffe066;
padding: 10px;
text-align: center;
}
.listing .body {
padding: 10px;
}
이것이 바로 CSS Grid 레이아웃만 고집하지 말고 Flexbox를 적재적소에 섞어 써야 하는 핵심적인 이유입니다! 2차원(가로/세로)으로 전체적인 틀을 잡을 때는 Grid가 최고지만, 1차원(단일 방향)으로 아이템 안의 콘텐츠들을 정렬하거나 여백을 밀어낼 때는 Flexbox가 훨씬 우월한 도구이기 때문입니다.
dense 키워드로 빈틈 막기 (Preventing gaps with the dense keyword)이제 꽤 그럴싸한 카드 리스트가 완성되었습니다. 하지만 3번째 카드처럼 특정 카드의 내용이 다른 것보다 유난히 길 때가 있습니다. 이럴 때 혼자서만 세로로 쭈욱 길어지면 좀 밉잖아요? 이 녀석에게 2칸의 너비를 주면 세로로 길어지는 대신 넓게 퍼져서 훨씬 예쁠 겁니다.
이를 위해 긴 아이템에 wide라는 클래스를 달고, grid-column-end 값을 span 2로 설정해 봅니다.
이렇게 하면, 브라우저가 이 아이템을 만났을 때 2칸의 공간을 내어줍니다. 하지만 문제가 하나 생깁니다! 화면 크기(브레이크포인트)에 따라 한 줄의 남은 칸이 1칸밖에 없을 경우, 2칸짜리 아이템이 들어갈 수 없으니 그 아이템은 다음 줄로 쫓겨나 버리고 기존 줄에는 휑한 빈칸(gap)이 발생하게 됩니다.

이때 빈 공간들을 뒤쪽의 아이템을 끌어와서 꽉꽉 채워 넣고 싶다면 어떻게 해야 할까요? 그리드 컨테이너에 grid-auto-flow: dense 속성을 설정하면 됩니다!
.listing {
list-style: none;
margin: 2em;
display: grid;
gap: 20px;
grid-auto-flow: dense;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
}
.listing .wide {
grid-column-end: span 2;
}
다만 주의하세요! 이 속성을 쓰면 아이템들이 화면에 보이는 순서와 실제 논리적인 소스(HTML) 순서가 달라질 수 있습니다. 사진 갤러리처럼 콘텐츠 순서가 전혀 중요하지 않을 때만 사용하는 것이 좋습니다.
또한 키보드 Tab 키를 눌러 포커스를 이동할 때는 화면에 보이는 대로 가지 않고 원본 HTML 순서를 따라가기 때문에 접근성 및 재정렬 문제(accessibility and re-ordering issues)가 발생할 수 있다는 점을 항상 숙지하셔야 합니다.
👨🏫 강사의 팁:
이 '자동 배치(auto-placement)'와span키워드의 조합은 워드프레스 같은 CMS(콘텐츠 관리 시스템)에서 뿜어져 나오는 동적인 데이터를 다룰 때 진짜 편합니다. HTML을 우리가 마음대로 수정할 수 없더라도, CSS의 구조적 가상 클래스(structural pseudo-classes) (예::nth-child(5))를 이용해 특정 아이템만 2칸으로 늘리는 등 손쉽게 변주를 줄 수 있거든요!
CSS 그리드 레이아웃의 가능성은 정말 무궁무진합니다! 그리드 레이아웃을 마스터하는 가장 빠른 방법은 오늘 배운 이런 실용적인 예제들을 계속해서 직접 만들어 보는 것입니다. 평소 즐겨 찾는 예쁜 반응형 웹사이트의 구조를 캡처해 놓고, "이걸 그리드로 짜려면 어떻게 해야 할까?" 하고 직접 코딩해 보세요. 심지어 잡지나 잡지, 포스터 같은 웹이 아닌 곳의 디자인에서 영감을 얻어 웹에 구현해 보는 것도 훌륭한 훈련이 됩니다.
더 깊게 파고들고 싶다면 아래 문서들을 참고해 보세요!
수고하셨습니다! 이제 실무에서 Grid를 활용할 때 "아~ 이래서 12-컬럼을 쓰는구나", "아~ 여기서 minmax를 쓰면 미디어 쿼리가 필요 없지!" 하고 바로 감이 오실 거예요. 오늘 배운 내용들을 바탕으로 멋진 레이아웃을 만들어보세요. 더 궁금한 점이 있다면 언제든 알려주시고요! 화이팅! 🚀