[CSS] Grid 톺아보기

PinkTopaz·2023년 4월 2일
2
post-thumbnail
post-custom-banner

css를 어느 정도 다룰 줄 알게 되어 React에서 Styled-component까지 이용해 프로젝트를 진행했지만, 레이아웃을 잡을 때는 항상 flex를 이용해왔다.
하지만 프론트엔드 면접 질문을 보면 종종 grid와 관련된 질문이 나오는 것을 볼 수 있었고 Grid에 대한 공부를 더 이상은 미룰 수 없다고 생각해 이번에 제대로 정리해보려고 한다.


Grid는 Flex와 어떻게 다른가?

Flex : 한 방향 레이아웃 시스템 (1차원)
grid : 두 방향 (가로 - 세로) 레이아웃 시스템 (2차원)
출처 : https://studiomeal.com/archives/533

따라서 Grid를 사용하면 Flex보다 조금 더 복잡한 레이아웃도 손쉽게 만들 수 있다.
그리고 상황에 따라 Grid와 Flex를 혼합하여 사용하면 더 편리하게 복잡한 레이아웃을 만들어낼 수 있다.

기본적인 Grid 속성

부모 컨테이너에 이제부터 Grid라고 선언을 해주면, 자식 요소들은 Grid cell로 변환이 된다

display : grid
grid-template-columns
grid-template-rows
grid-template-areas
grid-gap 
grid-column-start
grid-column-end
grid-row-start
grid-row-end
grid-area

실습으로 익혀보기

 <div class="container">
   <div class="item color1">Item1</div>
   <div class="item color2">Item2</div>
   <div class="item color3">Item3</div>
   <div class="item color4">Item4</div>
   <div class="item color5">Item5</div>
   <div class="item color1">Item6</div>
   <div class="item color2">Item7</div>
   <div class="item color3">Item8</div>
   <div class="item color4">Item9</div>
   <div class="item color5">Item10</div>
 </div>
.container {
  display: grid;
  grid-template-columns: 100px 100px 100px;
  grid-template-rows: 100px 200px 100px;
}

다음과 같이 3개의 column이 생기고 cell들이 각자 100px씩 차지하게 된다. 또한 1~3번째 row에 대해서는 각각 100px 200px 100px이 지정이 된다.

같은 값을 여러번 써주는 것이 귀찮다면 다음과 같이 repeat을 이용할 수도 있다.

.container {
  display: grid;
  //✅ 100px짜리 column을 5개 만든다
  grid-template-columns: repeat(5,100px);
  //✅ 100px 200px짜리 row를 만들고 
  //✅ 100px짜리 row를 2개 만든다.
  grid-template-rows: 100px 200px repeat(2,100px);
}

반응형

하지만 우리가 grid를 사용할 때에는 반응형으로 만들 경우가 많기 때문에 px보다는 비율을 사용하는 편이다.
비율은 %와 fr을 이용해 지정할 수 있다.

1. % 이용하기

.container {
  display: grid;
  /* ✅ 가로에서 사용 가능한 범위를 10%씩 나눈 5개의 column을 만든다 */
  grid-template-columns: repeat(5, 10%);
  /* ✅ 세로에서 사용 가능한 범위를 10%씩 나눈 2개의 row를 만든다 */
  grid-template-rows: repeat(2, 50%);
}

2. fr 이용하기

.container {
  display: grid;
  /* ✅ 가로에서 사용 가능한 범위를 10%씩 나눈 5개의 column을 만든다 */
  grid-template-columns: 1fr 1fr 1fr;
  grid-template-rows: 1fr 2fr repeat(2, 3fr);
}

자동으로 열과 행의 크기 통일하기

그런데 다음과 같이 지정된 column이 5개라서 row는 2개뿐인데 row를 이렇게 많이 지정해줄 필요가 있을까?

.container {
  display: grid;
  /* ✅ 가로에서 사용 가능한 범위를 10%씩 나눈 5개의 column을 만든다 */
  grid-template-columns: repeat(5,1fr);
  grid-template-rows: 1fr 2fr repeat(2, 3fr);
}

이와 같은 경우에는 grid-auto-rows를 이용해 column 개수에 상관없이 모든 열에 같은 사이즈를 크기를 줄 수도 있다.

.container {
  display: grid;
  /* ✅ 가로에서 사용 가능한 범위를 10%씩 나눈 5개의 column을 만든다 */
  grid-template-columns: repeat(5,1fr);
  grid-auto-rows : 100px;
}

하지만 컨테이너 안의 내용이 잘린다면?

컨테이너의 크기가 너무 작아서 보여주기를 원하는 내용이 잘린다면 minmax 속성을 이용할 수 있다.

.container {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
    /* ✅ 컨테이너 안의 내용이 잘린다면 내용에 맞게 크기를 auto로 지정하고, 그렇지 않다면 최소 150px을 row의 크기로 가진다. */
  grid-auto-rows: minmax(150px, 300px);
}

간격 지정하기

.container {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  grid-auto-rows: minmax(150px, auto);
    /* ✅ 세로 간격 20px, 가로 간격 10px */
  grid-column-gap: 20px;
  grid-row-gap: 10px;
  /* ✅ 전체 간격을 10px로 통일할 수도 있다*/
  /*grid-gap : 10px;*/
}

column과 row에 숫자를 매겨 영역을 지정해보자

grid에서 column과 row는 다음과 같이 번호를 매길 수 있다.

아이템 2에 대해 2칸을 차지하도록 하고 싶다면 grid-column-startgrid-column-end를 이용해 column 2번에서 4번까지 자리를 차지하도록 지정한다.

.item2 {
  grid-column-start: 2;
  grid-column-end: 4;
}

.item2 {
  grid-column-start: 2;
  grid-column-end: 4;
  grid-row-start: 1;
  grid-row-end: 3;
}

grid-row-startgrid-row-end에 대해서도 적용할 수 있다.

역시나 grid-columngrid-row로 간단하게 명시하는 방법도 있다.

.item2 {
  grid-column: 2 /4 ;
  //✅ 제일 끝까지 지정하기 
  /* grid-column: 2 / -1 */
  grid-row : 1 / 3;
}

line을 세기가 귀찮다면 시작점부터 몇개의 cell를 차지할 것인지 span으로 지정할 수 있다.

.item2 {
  grid-column: 2 / span 2 ;
  grid-row : 1 / span 2 ;
}

grid-template-areas 로 그리드 영역과 이름 지정하기

개인적으로 가장 편하고 놀라웠던 기능이다.
다음과 같이 html에서 첨부한 각각의 사진에 이름을 붙이고, 그 이름에 해당하는 곳에

자리를 잡아주고 싶다면 grid-template-areas를 이용하면 된다.

.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: 150px;
  grid-gap: 1rem;
  grid-template-areas:
    "a a a"
    "b c c"
    "b d g"
    "e f g";
}

다음과 같이 grid-template-areas로 영역을 잡아주고

.image1 {
  grid-area: a;
}

.image2 {
  grid-area: b;
}

.image3 {
  grid-area: c;
}

.image4 {
  grid-area: d;
}

.image5 {
  grid-area: e;
}

.image6 {
  grid-area: f;
}

.image7 {
  grid-area: g;
}

이렇게 각각의 사진에 grid-area를 주어 자리를 잡아주면 다음과 같은 결과가 나온다.


참고 자료
CSS Grid 완전 정리 끝판왕 😎

profile
🌱Connecting the dots🌱
post-custom-banner

1개의 댓글

comment-user-thumbnail
2023년 4월 3일

와.. 저도 flex만 사용하다 보니 grid 에 대한 공부를 미뤄서 꼭 조만간 공부해야겠다고 다짐했는데,, 너무너무너무 깔끔한 글을 보고 이해가 쏙쏙 됐어요!!!! 진짜 도움 많이 됐습니당 좋은 글 감사해요 :)
앗 그리고, 반응형 - fr 이용하기 쪽 코드들에 주석이 잘못 들어간 것 같아서 말씀드려요!ㅎㅎ

답글 달기