[CSS] Grid
CSS Grid?
flex의 경우, 1차원(행과 열)로만 아이템들을 배치할 수 있었습니다. 그러한 이유로 2차원으로 아이템을 배치할 때 여러 개의 flex를 조합해서 사용했었습니다. 이에 반해 CSS grid는 2차원으로 아이템을 배치할 수 있습니다. 그로인해 작성해야 하는 코드가 효율적이고, 단순하게 작성할 수 있는데 이에 대해서 알아보도록 하겠습니다.
Grid 만들기
<style>
.container {
display: grid;
}
</style>
<div class="container">
<div class="box">A</div>
<div class="box">B</div>
<div class="box">C</div>
<div class="box">D</div>
<div class="box">E</div>
<div class="box">F</div>
</div>
grid를 만드는 방식은 flex와 비슷합니다. flex와 마찬가지로 grid 내부에 들어갈 아이템들의 부모 요소에 display: grid 를 적용하면 자식 요소들이 grid에 영향을 받게 됩니다.
See the Pen Untitled by LUPIN-MOM (@lupin-mom) on CodePen.
코드를 실행하면 위와 각 자식 요소가 하나의 block을 차지하게 되는데, 이것은 grid의 기본 설정으로 column과 row를 아무것도 설정해주지 않아서 그렇습니다. 그럼 이제 본격적으로 2차원 layout을 설정해보도록 하겠습니다.
Column, Row 설정하기
grid-template-columns
column을 설정할 때에는 grid-template-columns 속성을 사용합니다.
.container {
display: grid;
grid-template-columns: 100px 200px 300px;
}
예를 들어, grid-template-columns: 100px 200px 300px 을 적용하면 하나의 row에서 100px 칼럼 하나, 200px 칼럼 하나, 300px 칼럼 하나를 만들고 grid 내부의 아이템을 아래와 같이 채우게 됩니다.
See the Pen Untitled by LUPIN-MOM (@lupin-mom) on CodePen.
만약 아이템이 column 갯수를 넘어가게 되면 위와 같이 다음 row 로 아이템을 넘기게 됩니다.
grid-template-columns 에는 %, rem, em 같은 모든 사이즈 단위를 사용할 수 있습니다. 뿐만 아니라 grid 내부에서만 사용할 수 있는 단위 fr이 있는데, fr에 대해서 간단히 알아보고 넘어 가도록 하겠습니다.
fr unit
fr은 fraction의 줄임말로 화면을 효과적으로 나눌 때 쓰는 단위입니다. grid-template-columns: 1fr 2fr 1fr; 을 적용해 보도록 하겠습니다.
See the Pen Untitled by LUPIN-MOM (@lupin-mom) on CodePen.
어떤가요? 느낌이 오시나요? 얼추보면 column 사이즈의 비중이 1:2:1이 된 것을 알 수 있습니다.
그렇습니다. fr은 grid 내에서 해당 비중만큼 사이즈를 나누어 구성합니다. 정확한 숫자를 넣어야 했던 %보다 훨씬 쉽게 사용할 수 있습니다. 예를 들어 화면을 3등분할 때, width: 33.333333% 이런식으로 입력하기 보단 grid-template-columns: 1fr 1fr 1fr; 처럼 쉽게 수치를 입력할 수 있습니다.
grid-template-rows
column을 설정할 때에는 grid-template-rows 속성을 사용합니다.
.container {
display: grid;
grid-template-columns: 100px 200px 300px;
grid-template-rows: 100px 200px;
}
See the Pen Untitled by LUPIN-MOM (@lupin-mom) on CodePen.
A, B, C가 포함된 첫번째 컬럼은 100px, D, E, F가 포함된 두번째 열은 200px로 영역을 차지한 것을 볼 수 있습니다. column과 마찬가지로 rem, em, %, fr 등의 다양한 단위를 사용할 수 있습니다.
grid 안에 아이템 배치하기
grid는 flex와 달리 아이템을 자기가 원하는 위치에 배치할 수 있습니다.
<style>
.container {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 100px 100px 100px;
}
</style>
<div class="container">
<div class="box a">A</div>
<div class="box b">B</div>
<div class="box c">C</div>
<div class="box d">D</div>
<div class="box e">E</div>
<div class="box f">F</div>
<div class="box g">G</div>
<div class="box h">H</div>
<div class="box i">I</div>
</div>
See the Pen Untitled by LUPIN-MOM (@lupin-mom) on CodePen.
그림과 같이 3개의 비율로 열을 나누고, 100px짜리 3개의 로우을 만들었습니다. 우선 A 박스로 1열 전체를 채우고, 나머지 아이템들을 두 번째 컬럼부터 배치되도록 해보겠습니다.
.a {
grid-column: 1 / 4;
}
See the Pen Untitled by LUPIN-MOM (@lupin-mom) on CodePen.
A 박스가 지니고 있는 클래스 a에 grid-column: 1 / 4; 를 주었더니 하나의 로우를 차지한 것을 알 수 있습니다. 이 코드의 의미는 첫번쨰 컬럼에서 4번째 컬럼까지 차지하라 것입니다. 그런데 컬럼 번호는 어떻게 나눌까요?
로우와 컬럼의 번호는 맨 안쪽부터 1번으로 하여 하나씩 커집니다. 그래서 아까 grid-column: 1 / 4; 에 의해 A 박스가 1번에서 4번까지 전체 열을 차지하게 됩니다.
.b {
grid-column: 1 / 3;
grid-row: 2 / 4;
}
See the Pen Untitled by LUPIN-MOM (@lupin-mom) on CodePen.
B는 grid-column과 grid-row를 같이 부여하였는데, 위와 같이 column과 row를 조합하면 grid layout 내에 원하는 위치 어디든 배치를 할 수 있게 됩니다.
실전 예제) 웹페이지 layout 구성하기
See the Pen Untitled by LUPIN-MOM (@lupin-mom) on CodePen.
이제 우리가 의도했던 대로 화면이 배치 되는 것을 볼 수 있습니다.
그런데 우리가 쓰지 않은 문법이 하나 있습니다. header와 footer의 경우 grid-column: 1 / -1; 의 표현을 사용했는데 이 것은 처음부터 끝까지 컬럼을 차지하겠다는 의미입니다. 여기서 -1은 마지막 컬럼을 뜻하며, 만약에 -2라고 하면 마지막에서 두번째 컬럼을 뜻합니다.
그런데 숫자를 컬럼과 로우의 숫자를 일일이 모든 내부 아이템마다 넣어주자니 조금 코드가 번잡한 느낌이 있습니다. 이번에는 grid-area를 통해서 조금 더 직관적인 코드로 바꿔보도록 하겠습니다.
grid-template-areas
grid는 각 영역에 이름을 부여할 수 있습니다. 그리고 부여된 이름을 각 아이템에서 배치에 사용할 수 있습니다.
.container {
display: grid;
grid-template-columns: 1fr 2fr;
grid-template-rows: 100px 500px 100px;
grid-template-areas:
"header header"
"side-bar main"
"footer footer";
}
위 코드를 보면 grid-template-columns, grid-template-rows로 인해 3X2의 레이아웃이 생겼습니다. 그리고 grid-template-areas에서 3X2 레이아웃에 맞추어 각 영역을 구분해 주었습니다. 이름 명명에는 규칙이 없고, 여기서 정의된 이름은 나중에 grid 내부 아이템에서 위치를 정할 때 사용됩니다. 이제 grid-area 속성을 통해 각 아이템의 위치를 정해보도록 하겠습니다.
.header {
grid-area: header;
}
.side-bar {
grid-area: side-bar;
}
.main {
grid-area: main;
}
.footer {
grid-area: footer;
}
grid-area: header 처럼 grid-templates-areas 에서 정의한 이름들을 사용할 수 있습니다. 이제 브라우저를 실행해보도록 하겠습니다.
grid-column 과 grid-row 가 빠졌음에도 정상적으로 우리가 의도한 대로 화면에 배치되는 것을 알 수 있습니다.
한 가지 더) 반응형 layout 만들기
모바일 기기에서 웹페이지를 보면 화면 폭이 좁기 때문에 Side-Bar를 두지 않고, 아래처럼 위로 Header 바로 밑에 위치 시키는 경우가 많습니다.
See the Pen Untitled by LUPIN-MOM (@lupin-mom) on CodePen.
위와 같이 하려면 어떻게 해야 할까요? media-query와 grid-template-column 과 grid-template-areas 을 활용하면 어렵지 않게 구현할 수 있습니다.
혹 media-query를 잘 모르신다면 이(링크)에서 간략하게 개념을 보고 오시는 것을 추천드립니다.
@media (max-width: 600px) {
.container {
grid-template-columns: 1fr;
grid-template-areas:
"header"
"side-bar"
"main"
"footer";
}}
화면의 폭이 600이하 일 때는 grid-template-columns: 1fr; 으로 column을 하나로 변경했습니다. 그리고 grid-template-areas 에서 위에서부터 각 아이템이 하나의 영역을 차지하도록 변경했습니다.
실행 해보면 작은 화면에서 그리고 큰 화면에서 정상적으로 잘 작동하는 것을 알 수 있습니다.
추가적으로 더 궁금하시다면 이 글(링크)에서 공부해보시는 것을 추천드립니다.
'HTML - CSS - 웹표준' 카테고리의 다른 글
[Visual Studio Code]의 html.json 수정하기 (0) | 2023.03.15 |
---|---|
[Visual Studio Code]의 Emmet (1) | 2023.03.15 |
[CSS] :nth-child :nth-of-type 가상 클래스(의사 클래스) (0) | 2023.03.02 |
[CSS] 가상 클래스 셀렉터 :nth-child와 :nth-of-type의 차이점 (0) | 2023.03.02 |
[CSS] 네이밍 규칙 (0) | 2023.02.24 |