지난 장에서 우리는 Flexbox를 사용하여 1차원(한 줄 또는 한 열) 방향으로 아이템들을 유연하게 배치하고 정렬하는 방법을 학습했습니다. Flexbox는 네비게이션 바나 카드 목록처럼 한 방향으로 흐르는 콘텐츠를 다룰 때 매우 강력한 도구입니다. 하지만 웹 페이지는 종종 여러 개의 행과 열로 구성된 복잡한 2차원 레이아웃을 필요로 합니다. 예를 들어, 신문 기사처럼 여러 열로 나뉜 텍스트, 복잡한 대시보드, 또는 갤러리 페이지 등이 그렇습니다.
이러한 2차원 레이아웃을 위해 탄생한 것이 바로 CSS Grid Layout입니다. Grid는 이름 그대로 격자(Grid) 형태의 레이아웃을 만들 수 있도록 설계된 CSS3의 새로운 레이아웃 모듈입니다. 부모 요소에 그리드 구조를 정의하고, 그 안에 있는 자식 요소들을 특정 그리드 셀에 배치함으로써 전체 페이지의 큰 틀을 잡거나 복잡한 그리드 형태의 UI를 쉽고 효율적으로 구현할 수 있습니다.
이 장에서는 Grid의 기본 개념과 주요 속성들을 상세하게 학습하고, 실습을 통해 Grid의 강력함을 직접 경험해 볼 것입니다. Flexbox와 Grid는 서로 보완적인 관계에 있으므로, 이 두 기술을 모두 능숙하게 다루는 것은 현대 웹 개발자에게 필수적인 역량입니다.
그리드의 열(Column) 트랙의 크기와 개수를 정의합니다. 공백으로 구분하여 각 열의 너비를 지정합니다.
단위:px, %, em, rem, vw, vh 등 다양한 CSS 단위 사용 가능.
fr (Fraction): 사용 가능한 공간에 대한 비율을 나타내는 단위. 남은 공간을 유연하게 나눌 때 매우 유용합니다. (예: 1fr 2fr 1fr은 남은 공간을 1:2:1 비율로 나눔)
repeat() 함수: 동일한 크기의 트랙을 반복할 때 사용합니다. repeat(반복 횟수, 트랙 크기). (예: repeat(3, 1fr)은 1fr 1fr 1fr과 동일)
minmax() 함수: 트랙의 최소 및 최대 크기를 지정합니다. minmax(최소 크기, 최대 크기). (예: minmax(100px, 1fr)은 최소 100px, 최대 남은 공간을 차지)
auto: 콘텐츠의 크기에 맞춰 자동으로 조절되거나, 남은 공간을 균등하게 분배합니다.
.container { display: grid; /* 3개의 열: 첫 번째 200px, 두 번째 남은 공간의 2배, 세 번째 남은 공간의 1배 */ grid-template-columns: 200px 2fr 1fr; /* 4개의 동일한 열 (각각 남은 공간의 1/4) */ grid-template-columns: repeat(4, 1fr); /* 최소 150px, 최대 남은 공간을 차지하는 열들을 자동으로 생성 */ grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); /* 반응형 그리드에 자주 사용 */}
.item-a { grid-column: 1 / 3; /* 첫 번째 세로 라인에서 시작하여 세 번째 세로 라인에서 끝남 (2칸 차지) */ grid-row: 1 / 2; /* 첫 번째 가로 라인에서 시작하여 두 번째 가로 라인에서 끝남 (1칸 차지) */}.item-b { grid-column: span 2; /* 두 칸 너비를 차지 */ grid-row: span 3; /* 세 칸 높이를 차지 */}
그리드 컨테이너에서 grid-template-areas로 정의된 영역 이름을 사용하여 아이템을 배치합니다. 훨씬 직관적이고 가독성이 높은 방법입니다.
컨테이너에 영역 정의:
.container { display: grid; grid-template-columns: 1fr 2fr 1fr; grid-template-rows: auto 1fr auto; grid-template-areas: "header header header" /* 첫 번째 행: 모두 header 영역 */ "nav main aside" /* 두 번째 행: nav, main, aside */ "footer footer footer"; /* 세 번째 행: 모두 footer 영역 */}
/* 기본 스타일 및 박스 사이징 */* { box-sizing: border-box; margin: 0; padding: 0;}body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background-color: #f0f2f5; color: #333; line-height: 1.6;}/* Grid 컨테이너 설정 */.grid-container { display: grid; /* Grid 활성화 */ gap: 20px; /* 그리드 셀 사이의 간격 */ min-height: 100vh; /* 최소 높이를 뷰포트 높이로 설정 */ max-width: 1200px; /* 최대 너비 제한 */ margin: 0 auto; /* 중앙 정렬 */ /* 그리드 영역 이름 정의 및 배치 */ grid-template-areas: "header header header" "navbar main sidebar" "footer footer footer"; /* 각 열의 너비 정의 */ grid-template-columns: 200px 1fr 250px; /* nav 200px, main 가변, sidebar 250px */ /* 각 행의 높이 정의 */ grid-template-rows: auto 1fr auto; /* header, footer는 콘텐츠만큼, main은 남은 공간 모두 */}/* 그리드 아이템 기본 스타일 */.grid-container > * { background-color: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 5px rgba(0,0,0,0.1);}/* Grid 아이템을 정의된 영역에 배치 */.header { grid-area: header; background-color: #2c3e50; color: white; text-align: center; padding: 30px;}.header h1 { font-size: 2.8em; margin-bottom: 10px;}.navbar { grid-area: navbar; background-color: #34495e; color: white;}.navbar ul { list-style: none; padding: 0;}.navbar li { margin-bottom: 10px;}.navbar a { display: block; /* 링크 영역 확장 */ color: white; text-decoration: none; padding: 10px; border-radius: 5px; transition: background-color 0.3s ease;}.navbar a:hover { background-color: #4a6581;}.main-content { grid-area: main;}.main-content h2 { color: #2980b9; margin-bottom: 15px; border-bottom: 2px solid #2980b9; padding-bottom: 5px;}.main-content h3 { color: #4a6581; margin-top: 25px; margin-bottom: 10px;}.main-content ul { list-style-type: disc; margin-left: 20px;}.main-content li { margin-bottom: 5px;}/* 이미지 갤러리 (Grid in Grid - Flexbox와 함께 사용) */.image-gallery { display: grid; /* 갤러리 내부를 다시 그리드로 */ grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); /* 최소 180px, 가변 열 */ gap: 15px; margin: 20px 0; padding: 15px; background-color: #f9f9f9; border-radius: 5px;}.image-gallery img { width: 100%; height: 150px; object-fit: cover; /* 비율 유지하며 채우기 */ border-radius: 5px; box-shadow: 0 1px 3px rgba(0,0,0,0.1);}.sidebar { grid-area: sidebar; background-color: #ecf0f1;}.sidebar h3 { color: #2c3e50; margin-bottom: 15px;}.sidebar button { background-color: #28a745; color: white; padding: 10px 20px; border: none; border-radius: 5px; cursor: pointer; margin-top: 15px; transition: background-color 0.3s ease;}.sidebar button:hover { background-color: #218838;}.footer { grid-area: footer; background-color: #34495e; color: white; text-align: center; padding: 20px; font-size: 0.9em;}/* 반응형 디자인: 화면 너비 768px 이하 */@media (max-width: 768px) { .grid-container { /* 모바일에서는 모든 영역을 하나의 열에 세로로 쌓음 */ grid-template-areas: "header" "navbar" "main" "sidebar" "footer"; grid-template-columns: 1fr; /* 하나의 열만 사용 */ grid-template-rows: auto auto 1fr auto auto; /* 각 영역 높이 조정 */ gap: 15px; /* 간격도 조금 줄임 */ } .header, .navbar, .main-content, .sidebar, .footer { padding: 15px; /* 패딩도 줄임 */ } .navbar ul { display: flex; /* 네비게이션 메뉴를 플렉스박스로 가로 정렬 */ flex-wrap: wrap; /* 공간 부족 시 줄바꿈 */ justify-content: center; gap: 10px; } .navbar li { margin-bottom: 0; } .navbar a { padding: 8px 12px; font-size: 0.9em; } .image-gallery { grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); /* 모바일 이미지 갤러리 조정 */ gap: 10px; }}
결과 확인
Live Server를 통해 grid_layout.html 파일을 열어보세요.
웹 페이지의 헤더, 네비게이션, 메인 콘텐츠, 사이드바, 푸터가 명확한 격자 형태로 배치된 것을 확인할 수 있습니다. grid-template-areas를 통해 코드에서 레이아웃 구조가 시각적으로 어떻게 보이는지 주목하세요.
브라우저 창의 너비를 조절해 보세요. 특히 768px 이하로 줄어들면, Grid 컨테이너의 grid-template-areas와 grid-template-columns 설정이 변경되어 모든 영역이 세로로 쌓이는 반응형 디자인이 적용되는 것을 확인할 수 있습니다. image-gallery와 같이 Grid 안에 Grid를 사용하여 복잡한 섹션을 만들 수도 있습니다.
이번 장에서는 2차원 레이아웃을 위한 강력한 CSS 모듈인 CSS Grid Layout에 대해 학습했습니다. Grid 컨테이너에 행과 열 트랙을 정의하고(grid-template-columns, grid-template-rows), 트랙 사이의 간격을 설정하며(gap), 아이템들을 라인 기반(grid-column, grid-row) 또는 영역 이름 기반(grid-area, grid-template-areas)으로 배치하는 방법을 배웠습니다. 또한, 그리드 셀 내부에서 아이템을 정렬하고(justify-items, align-items), 그리드 전체를 정렬하는(justify-content, align-content) 방법도 익혔습니다.
Flexbox가 1차원 배열에 강점을 가진다면, Grid는 전체 페이지 레이아웃이나 복잡한 갤러리처럼 2차원 구조를 만들 때 빛을 발합니다. 이 두 기술은 현대 웹 개발에서 거의 모든 레이아웃 문제를 해결할 수 있는 핵심 도구입니다.
이로써 3장 "CSS 기초와 레이아웃"의 모든 내용을 마쳤습니다. 여러분은 이제 HTML로 콘텐츠를 만들고, CSS로 스타일을 입히며, Flexbox와 Grid를 사용하여 복잡하고 반응형인 웹 레이아웃을 설계할 수 있는 기본기를 완벽하게 다지게 되었습니다.