그리드 레이아웃이란 웹 사이트를 여러 개의 column으로 나눈 후 메뉴나 본문, 이미지 등의 웹 요소를 화면에 맞게 배치하는 것을 말한다.
그리드 레이아웃을 사용하기 위해서는 float
속성을 사용하거나 플렉서블 박스 레이아웃
이나 CSS 그리드 레이아웃
으로 적용할 수도 있다.
플렉서블 박스 레이아웃은 그리드 레이아웃을 기본으로 하고 각 박스를 원하는 위치에 따라 배치하는 것이다. 플렉서블 박스 레이아웃은 흔히 플렉스 박스 레이아웃
, 플렉스 박스
이라고도 한다.
플렉서블 박스 레이아웃은 그림과 같이 수평 방향이나 수직 방향을 한쪽을 주축으로 정하고 순서대로 배치하다 화면 너비를 넘어갈 경우 한 줄을 이동하여 다시 주축으로 순서대로 배치한다.
CSS 그리드 레이아웃은 주축이라는 개념없이 수평과 수직 어느 방향이든 배치할 수 있다. 마치 레고 블록을 끼워 맞추듯 요소 를 배치한다고 생각하면 된다.
종류 | 설명 |
---|---|
justify-content | 주축 방향의 정렬 방법 지정 |
align-items | 전체 플렉스 항목의 정렬 방법 |
align-self | 개별적인 플렉스 항목의 정렬 방법 |
align-content | 플렉스 항목들간의 항목 사이 및 주변의 공간 분포를 설정합니다. |
display 속성은 요소를 어떻게 보여줄지를 결정한다.
display 속성은 이전에 설명했듯 block
박스나 inline
박스를 지정할 때도 사용했던 속성이다.
플렉스 박스 레이아웃을 만들려면 요소를 감싸는 부모 요소를 만들고, 그 부모 요소를 display를 통해 플렉스 컨테이너로 만들어주어야 한다.
종류 | 설명 |
---|---|
flex | 컨테이너 안의 플렉스 항목을 블록 레벨 요소로 배치한다. |
inline-flex | 컨테이너 안의 플렉스 항목을 인라인 레벨 요소로 배치한다. |
flex-direction 속성은 플렉스 컨테이너 안에서 플렉스 항목을 배치하는 주축과 방향을 지정하는 속성이다.
종류 | 설명 |
---|---|
row (기본값) | 주축을 가로로 지정하고 왼쪽에서 오른쪽으로 배치한다. |
row-reverse | 주축을 가로로 지정하고 반대로 오른쪽에서 왼쪽으로 배치한다. |
column | 주축을 세로로 지정하고 위쪽에서 아래쪽으로 배치한다. |
column-reverse | 주축을 세로로 지정하고 반대로 아래쪽에서 위쪽으로 배치한다. |
flex-wrap 속성은 플렉스 컨테이너 너비보다 많은 플렉스 항목이 있는 경우 줄을 바꿀지 여부를 지정한다. 속성값으로 wrap나 wrap-reverse를 지정하고 웹 브라우저 화면의 너비를 늘리거나 줄여보면 줄바꿈이 되는 것을 볼 수 있다.
종류 | 설명 |
---|---|
nowrap (기본값) | 플렉스 항목을 한 줄에 표시한다. |
wrap | 플렉스 항목을 여러 줄에 표시한다. |
wrap-reverse | 플렉스 항목을 여러 줄에 표시하되, 여러 줄에 표시될 경우 아래부터 위로 배치된다. |
flex-flow 속성은 flex-direction 속성과 flex-wrap 속성을 한꺼번에 지정해주는 속성이다. 기본값은 row nowrap
이다.
예시
.div1 {flex-flow: row wrap;} .div2 {flex-flow: row-reverse wrap-reverse;}
justify-content 속성은 주축에서 플렉스 항목 간의 정렬 방법을 지정한다.
종류 | 설명 |
---|---|
flex-start | 주축의 시작점에 맞춰 배치한다. |
flex-end | 주축의 끝점에 맞춰 배치한다. |
center | 주축의 중앙에 맞춰 배치한다. |
space-between | 첫 번째 항목과 끝 항목을 주축의 시작점과 끝점에 배치한 후 나머지 항목은 그 사이에 같은 간격으로 배치한다. |
space-around | 모든 항목을 주축에 같은 간격으로 배치한다. |
align-items 속성은 justify-content
가 주축에서 항목을 정렬하는 방법이라면 align-items
는 교차축을 기준으로 항목을 정렬하는 방법이다.
종류 | 설명 |
---|---|
flex-start | 교차축의 시작점에 맞춰 배치한다. |
flex-end | 교차축의 끝점에 맞춰 배치한다. |
center | 교차축의 중앙에 맞춰 배치한다. |
baseline | 교차축의 문자 기준선에 맞춰 배치한다. |
stretch | 플렉스 항목을 늘려 교차축에 가득 차게 배치한다. |
align-self 속성은 align-items
가 플렉스 컨테이너에 있는 플렉스 항목 전체의 정렬 방법을 지정했던 반면 플렉스 컨테이너에 있는 특정 플렉스"만"의 정렬 방식을 지정한다.
정리
align-items
- 플렉스 컨테이너의 교차축 기준 정렬 방식 (플렉스 컨테이너의 선택자에 사용)
align-self
- 플렉스 항목의 교차축 기준 정렬 방식 (플렉스 항목의 선택자에 사용)
align-content 속성은 주축에서 줄바꿈이 생겨서 플렉스 항목을 여러 줄로 표시할 때
align-content를 통해 플렉스 항목 간의 간격을 지정한다.
종류 | 설명 |
---|---|
flex-start | 교차축의 시작점에 맞춰 배치한다. |
flex-end | 교차축의 끝점에 맞춰 배치한다. |
space-betweent | 첫 번째 항목과 끝 항목을 교차축의 시작점과 끝점에 배치한 후 나머지 항목은 그 사이에 같은 간격으로 배치한다. |
space-around | 모든 항목을 교차축에 같은 간격으로 배치한다. |
stretch | 플렉스 항목을 늘려 교차축에 가득 차게 배치한다. |
활용
위에서 설명한 플렉스 박스 레이아웃을 활용하면 화면 요소를 항상 화면 중앙에 위치하도록 할 수 있다.<!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>세로로 중앙에 배치하기</title> <style> * { margin:0; box-sizing: border-box; } body { background:url('images/bg5.jpg') no-repeat left top fixed; background-size:cover; display: flex; justify-content: center; align-items: center; min-height:100vh; } button { background-color:#ccc; font-size: 1.2em; padding:1em 2em; border:none; border-radius:5px; box-shadow:1px 1px 2px #fff; } </style> </head> <body> <button>클릭!</button> </body> </html>
CSS 그리드 레이아웃은 플렉스 박스 레이아웃과 달리 주축이라는 개념없이 수평과 수직 어느 방향이든 배치할 수 있다.
display 속성은 요소를 어떻게 보여줄지를 결정한다.
display 속성은 이전에 설명했듯 block
박스나 inline
박스를 지정할 때도 사용했던 속성이다.
그리드 레이아웃을 만들려면 요소를 감싸는 부모 요소를 만들고, 그 부모 요소를 display를 통해 그리드 컨테이너로 만들어주어야 한다.
종류 | 설명 |
---|---|
grid | 컨테이너 안의 항목을 블록 레벨 요소로 배치한다. |
inline-grid | 컨테이너 안의 항목을 인라인 레벨 요소로 배치한다. |
grid-template-columns, grid-template-rows 속성은 column과 row의 크기와 개수를 지정한다.
아래 예제는 너비가 100px이고 높이가 100px인 column 3개씩 두 줄로 배치한 grid template이다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title></title>
<style>
.container {
display: grid;
grid-template-columns: 100px 100px 100px;
grid-template-rows: 50px 50px;
grid-gap: 20px;
}
.items {
background-color: black;
padding: 10px;
color: white;
}
</style>
</head>
<body>
<div class="container">
<div class="items">1</div>
<div class="items">2</div>
<div class="items">3</div>
<div class="items">4</div>
<div class="items">5</div>
<div class="items">6</div>
</div>
</body>
</html>
px
단위는 항상 크기가 고정되므로 반응형 웹 디자인에는 적합하지 않다. 그래서 그리드 레이아웃에서는 상대적인 크기를 지정할 수 있도록 fr
단위를 사용한다.
fr
단위 사용법
1:1:1 (너비가 같은 column 3개 배치)grid-template-columns: 1fr 1fr 1fr;
2:1:2 (칼럼 크기가 2:1:2로 배치)
grid-template-columns: 2fr 1fr 2fr;
repeat () 함수는 값이 반복될 때 줄여서 표현해준다.
예를 들어 1fr 1fr 1fr
은 repeat(3, 1fr)
로 대체할 수 있다.
또한 1fr 2fr 1fr 2fr 1fr 2fr
은 repeat(3, 1fr 2fr)
로 대체한다.
repeat(<repetitions>, <track-list>)
minmax() 함수는 최솟값과 최댓값을 지정해주는 함수이다.
minmax() 함수를 이용하면 높이나 너비를 고정하지 않고 최솟값과 최댓값을 사용해 유연하게 지정할 수 있다.
grid-template-columns: 2fr 1fr 2fr;
grid-template-columns: repeat(3,1fr);
grid-template-rows: minmax(100px, auto);
이 예제는 너비가 같은 column 3개를 반복하는데, 너비는 그리드 컨테이너 너비에 맞추어 달라진다.
높이는 최소 100px로 지정하고 내용이 많아도 다 표시할 수 있도록 높이가 늘어난다.
auto-fill이나 auto-fit을 사용하면 화면 너비에 따라 자동으로 칼럼 개수를 조절해준다.
auto-fit
과 auto-fill
의 차이는 남는 공간을 채울지 여부이다.
auto-fit
은 화면이 넓을 때에 남는 공간 없이 꽉 채워서 column을 표시한다.
auto-fill
은 칼럼의 최소 너비만 표시하고 남는 공간은 그대로 둔다.
예를 들어 repeat(auto-fit, 150px)
는 150px로 화면에 가득 찰 때까지 배치한다.
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
컨테이너 너비가 넓어지면
auto-fit
- 그리드 컨테이너 내부에 공간이 남을 경우, 그 공간을 각 셀들이 나눠 갖는다.
auto-fill
- 칼럼의 최소 너비만 표시하고 남는 공간은 그대로 둔다.
grid-column-gap, grid-row-gap, grid-gap 속성은 그리드 항목의 간격을 지정한다.
종류 | 설명 |
---|---|
grid-column-gap | 칼럼과 칼럼 사이의 간격 지정 |
grid-row-gap | 줄과 줄 사이의 간격 지정 |
grid-gap (단축 속성) | 칼럼과 줄 사이의 간격을 한꺼번에 지정 |
grid-row-gap: 20px;
grid-column-gap: 30px;
grid-gap: 20px 30px;
위 두 스타일은 같은 스타일이다.
그리드 레이아웃은 눈에 보이지 않는 그리드 라인이 포함되어있다. 이 그리드 라인을 이용해서 그리드 항목을 배치할 수 있다.
종류 | 설명 |
---|---|
grid-column-start | column 시작의 라인 번호 지정 |
grid-column-end | column 마지막의 라인 번호 지정 |
grid-column | column 시작 번호와 column 끝 번호 사이에 슬래시(/)를 넣어 사용 |
grid-row-start | row 시작의 라인 번호 지정 |
grid-row-end | row 마지막의 라인 번호 지정 |
grid-row | row 시작 번호와 row 끝 번호 사이에 슬래시(/)를 넣어 사용 |
<!-- 생략 -->
<style>
#wrapper{
width:700px;
display:grid;
grid-template-columns:repeat(3, 1fr);
grid-template-rows:repeat(3, 100px);
}
</style>
</head>
<body>
<div id="wrapper">
<div class="box box1">box1</div>
<div class="box box2">box2</div>
<div class="box box3">box3</div>
<div class="box box4">box4</div>
</div>
</body>
.box1 {
background-color:#3689ff;
grid-column:1/4;
}
.box2 {
background-color:#00cf12;
grid-row:2/4;
/* grid-column:1/2; */
grid-column-start:1;
}
.box3 {
background-color:#ff9019;
grid-column:2/4;
/* grid-row:2/3; */
grid-row-start:2;
}
.box4 {
background-color:#ffd000;
grid-column-start:3;
grid-row-start:3;
}
<!-- 생략 -->
<style>
#wrapper{
width:700px;
display:grid;
grid-template-columns:repeat(3, 1fr);
grid-template-rows:repeat(3, 100px);
grid-template-areas:
"box1 box1 box1"
"box2 box3 box3"
"box2 . box4";
}
</style>
</head>
<body>
<div id="wrapper">
<div class="box box1">box1</div>
<div class="box box2">box2</div>
<div class="box box3">box3</div>
<div class="box box4">box4</div>
</div>
</body>
.box{
padding:15px;
color:#fff;
font-weight:bold;
text-align:center;
}
.box1 {
background-color:#3689ff;
grid-area:box1;
}
.box2 {
background-color:#00cf12;
grid-area:box2;
}
.box3 {
background-color:#ff9019;
grid-area:box3;
}
.box4 {
background-color:#ffd000;
grid-area:box4;
}
출처
고경희(2021), "베스트셀러Do it! HTML+CSS+자바스크립트 웹 표준의 정석", 이지스 퍼블리싱
Andrew, Rachel, (jan 10, 2020), Understanding CSS Grid: Grid Lines, Smashing Magazine, https://www.smashingmagazine.com/2020/01/understanding-css-grid-lines/