현대 웹 개발에서 CSS Flexbox와 Grid는 필수적인 레이아웃 도구입니다. Float나 position 기반의 복잡한 레이아웃에서 벗어나 직관적이고 유연한 레이아웃을 구현할 수 있습니다.
CSS Box Model 이해하기
레이아웃을 배우기 전에 Box Model을 먼저 이해해야 합니다.
* {
box-sizing: border-box;
}
.element {
width: 300px;
padding: 20px;
border: 5px solid #333;
margin: 10px;
}
box-sizing: border-box를 전역으로 설정하면 width와 height 계산이 훨씬 직관적입니다. padding과 border가 지정된 크기에 포함됩니다.CSS Flexbox
Flexbox는 1차원 레이아웃을 위한 도구입니다. 행 또는 열 방향으로 아이템을 배치합니다.
Flex Container 속성
.container {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
align-items: center;
gap: 20px;
}
justify-content 옵션
.container {
justify-content: flex-start;
justify-content: flex-end;
justify-content: center;
justify-content: space-between;
justify-content: space-around;
justify-content: space-evenly;
}
align-items 옵션
.container {
align-items: stretch;
align-items: flex-start;
align-items: flex-end;
align-items: center;
align-items: baseline;
}
Flex Item 속성
.item {
flex-grow: 1;
flex-shrink: 0;
flex-basis: 200px;
flex: 1 0 200px;
align-self: flex-end;
order: 2;
}
Flexbox 실전 예제
네비게이션 바
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem 2rem;
}
.nav-links {
display: flex;
gap: 2rem;
list-style: none;
}
.nav-right {
display: flex;
gap: 1rem;
}
<nav class="navbar">
<div class="logo">Logo</div>
<ul class="nav-links">
<li><a href="#">Home</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Services</a></li>
</ul>
<div class="nav-right">
<button>Login</button>
<button>Sign Up</button>
</div>
</nav>
카드 레이아웃
.card-container {
display: flex;
flex-wrap: wrap;
gap: 1.5rem;
}
.card {
flex: 1 1 300px;
display: flex;
flex-direction: column;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.card-body {
flex: 1;
padding: 1rem;
}
.card-footer {
padding: 1rem;
margin-top: auto;
}
CSS Grid
Grid는 2차원 레이아웃을 위한 도구입니다. 행과 열을 동시에 제어할 수 있습니다.
Grid Container 속성
.grid-container {
display: grid;
grid-template-columns: 200px 1fr 200px;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: auto 1fr auto;
gap: 20px;
row-gap: 20px;
column-gap: 10px;
}
fr 단위와 repeat 함수
.grid {
grid-template-columns: 1fr 2fr 1fr;
grid-template-columns: repeat(4, 1fr);
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
}
auto-fill은 가능한 많은 열을 생성하고 빈 공간을 유지합니다. auto-fit은 아이템이 적을 때 빈 열을 축소하여 아이템을 늘립니다.Grid Item 배치
.header {
grid-column: 1 / -1;
}
.sidebar {
grid-column: 1 / 2;
grid-row: 2 / 4;
}
.main {
grid-column: 2 / -1;
grid-row: 2 / 3;
}
.footer {
grid-column: 1 / -1;
grid-row: 4;
}
Grid Template Areas
직관적인 레이아웃 정의 방법입니다.
.layout {
display: grid;
grid-template-areas:
"header header header"
"sidebar main main"
"sidebar main main"
"footer footer footer";
grid-template-columns: 200px 1fr 1fr;
grid-template-rows: auto 1fr 1fr auto;
min-height: 100vh;
gap: 1rem;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.footer { grid-area: footer; }
Grid 실전 예제
이미지 갤러리
.gallery {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 1rem;
}
.gallery-item {
aspect-ratio: 1;
overflow: hidden;
border-radius: 8px;
}
.gallery-item img {
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 0.3s ease;
}
.gallery-item:hover img {
transform: scale(1.1);
}
.gallery-item.featured {
grid-column: span 2;
grid-row: span 2;
}
대시보드 레이아웃
.dashboard {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: auto repeat(2, 1fr);
gap: 1.5rem;
padding: 1.5rem;
}
.stat-card {
background: white;
padding: 1.5rem;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.chart-large {
grid-column: span 2;
grid-row: span 2;
}
.chart-wide {
grid-column: span 3;
}
Flexbox vs Grid 선택 가이드
| 상황 | 추천 |
|---|---|
| 한 방향(행 또는 열) 정렬 | Flexbox |
| 2차원 레이아웃(행과 열) | Grid |
| 콘텐츠 크기 기반 레이아웃 | Flexbox |
| 명확한 그리드 구조 | Grid |
| 동적 아이템 배치 | Flexbox |
| 복잡한 페이지 레이아웃 | Grid |
Flexbox와 Grid는 서로 대체재가 아닙니다. 각각의 강점을 살려 함께 사용하세요. Grid 안에 Flexbox를 사용하거나 그 반대도 가능합니다.
반응형 디자인 구현
미디어 쿼리와 함께 사용
.container {
display: grid;
grid-template-columns: 1fr;
gap: 1rem;
}
@media (min-width: 768px) {
.container {
grid-template-columns: repeat(2, 1fr);
}
}
@media (min-width: 1024px) {
.container {
grid-template-columns: repeat(3, 1fr);
}
}
미디어 쿼리 없는 반응형
.responsive-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
gap: 1rem;
}
.responsive-flex {
display: flex;
flex-wrap: wrap;
}
.responsive-flex > * {
flex: 1 1 300px;
}
Container Queries
최신 CSS 기능으로 부모 컨테이너 크기에 따라 스타일을 변경합니다.
.card-wrapper {
container-type: inline-size;
}
@container (min-width: 400px) {
.card {
display: grid;
grid-template-columns: 150px 1fr;
}
}
@container (min-width: 600px) {
.card {
grid-template-columns: 200px 1fr;
}
.card-title {
font-size: 1.5rem;
}
}
실전 레이아웃 패턴
Holy Grail 레이아웃
.holy-grail {
display: grid;
grid-template:
"header header header" auto
"nav main aside" 1fr
"footer footer footer" auto
/ 200px 1fr 200px;
min-height: 100vh;
}
@media (max-width: 768px) {
.holy-grail {
grid-template:
"header" auto
"nav" auto
"main" 1fr
"aside" auto
"footer" auto
/ 1fr;
}
}
센터링
.center-flex {
display: flex;
justify-content: center;
align-items: center;
}
.center-grid {
display: grid;
place-items: center;
}
Sticky Footer
.page {
display: grid;
grid-template-rows: auto 1fr auto;
min-height: 100vh;
}
.header { }
.main { }
.footer { }
브라우저 지원 및 Fallback
.container {
display: flex;
flex-wrap: wrap;
}
.container > * {
flex: 1 1 300px;
}
@supports (display: grid) {
.container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
}
.container > * {
flex: unset;
}
}
마무리
Flexbox와 Grid는 현대 웹 레이아웃의 핵심입니다. 핵심 포인트를 정리하면 다음과 같습니다.
- Flexbox는 1차원 레이아웃, Grid는 2차원 레이아웃에 적합
box-sizing: border-box를 전역 설정auto-fit과minmax()로 반응형 그리드 구현- 두 기술을 조합하여 복잡한 레이아웃 구성
- Container Queries로 컴포넌트 단위 반응형 구현
다음 글에서는 CSS 애니메이션과 트랜지션에 대해 다루겠습니다.