본문 바로가기
📁Web Developing/CSS 기초

VII. 반응형 웹과 미디어 쿼리 - 5. CSS 그리드 레이아웃 사용하기

by Hush 2022. 6. 14.

웹 디자인 레이아웃을 만들 때 그리드 레이아웃은 아주 중요하다.

웹 사이트를 제작할 때 고려해야 할 기기가 나날이 늘어나고 있기 때문이다.

소스를 최대한 간단하게 유지하면서 대부분의 기기에 대응할 수 있는 그리드 레이아웃 기법이 바로 CSS 그리드 레이아웃이다.

 

CSS 그리드 레이아웃에서 사용하는 용어

플렉스 박스 레이아웃에서는 플렉스 항목을 배치할 때 가로나 세로 중에서 하나를 주축으로 정해 놓고 배치했다.

반면에 CSS 그리드 레이아웃에서는 그리드 항목을 배치할 때 가로와 세로를 모두 사용한다.

그래서 플렉스 항목은 1차원이고 CSS 그리드 레이아웃은 2차원이라고 말한다.

 

CSS그리드 레이아웃은 가로 방향을 가리키는 줄(row)과 세로 방향을 가리키는 칼럼(column)으로 웹 화면을 구성한다.

그리고 칼럼과 칼럼 사이, 줄과 줄 사이의 간격을 지정해서 원하는 형태의 레이아웃을 만든다.

 

CSS 그리드 레이아웃 항목을 배치하는 속성

CSS그리드 레이아웃은 가장 최근에 제안된 그리드 레이아웃 제작 방법이다.

CSS그리드 레이아웃을 만들 때 사용하는 속성을 하나하나 살펴보겠다.

 

그리드 컨테이너를 지정하는 display 속성

그리드 레이아웃을 지정할 떄에는 가장 먼저 그리드를 적용할 요소의 바깥 부분을 그리드 컨테이너로 만들어야 한다.

그리드 컨테이너를 만들 때에는 display 속성을 grid나 inline-gird로 지정한다.

종류 설명
grid 컨테이너 안의 항목을 블록 레벨 요소로 배치한다.
inline-grid 컨테이너 안의 항목을 인라인 레벨 요소로 배치한다.

 

칼럼과 줄을 지정하는 grid-template-columns, grid-template-rows 속성

그리드 컨테이너 안에 항목을 배치할 때 카럼과 줄의 크기와 개수를 지정하려면 이 두 속성을 사용한다.

grid-template-columns 속성은 그리드 컨테이너 안의 항목을 몇 개의 칼럼으로 배치할지, 각 칼럼의 너비를 얼마로 할지 지정한다.

다음은 .items 요소를 그리드 레이아웃으로 배치하기 위해 그 바깥을 감싸는 #wrapper 요소를 그리드 컨테이너로 지정한 예제이다.

그리고 너비를 200px인 칼럼 3개로 배치했다.

여러 줄이 될 경우 줄 높이는 100px로 지정했다.

<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>CSS Grid Layout</title>
  <style>
    #wrapper{
      display:grid;
      grid-template-columns: 200px 200px 200px;
      grid-template-rows:100px;
    }
  .items{
    padding:10px;
    background-color:#eee;
  }   
  .items:nth-child(odd){
    background-color:#bbb;
  }
  </style>

</head>
<body>
  <div id="wrapper">
    <div class="items">Lorem ipsum dolor sit amet consectetur adipisicing elit. Amet, reprehenderit.Lorem ipsum dolor, sit amet consectetur adipisicing elit. </div>
    <div class="items">Lorem ipsum dolor, sit amet consectetur adipisicing elit.Lorem ipsum dolor, sit amet consectetur adipisicing elit</div>
    <div class="items">Lorem ipsum dolor sit amet.Lorem ipsum dolor, sit amet consectetur adipisicing elit</div>
    <div class="items">Lorem ipsum dolor sit.Lorem ipsum dolor, sit amet consectetur adipisicing elit</div>
    <div class="items">Lorem, ipsum dolor.</div>
  </div>
</body>
</html>

 

상대적인 크기를 지정하는 fr단위

그리드 레이아웃에서 칼럼이나 줄의 크기를 지정할 때 픽셀(px)을 이용하면 항상 크기가 고정되므로 반응형 웹 디자인에는 적합하지 않다.

그래서 그리드 레이아웃에서는 상대적인 크기를 지정할 수 있도록 fr(fraction) 단위를 사용한다.

예를 들어 너비가 같은 칼럼을 3개 배치한다면 fr 단위를 사용해 다음과 같이 지정한다.

grid-template-columns: 1fr 1fr 1fr;

또는 칼럼을 2:1:2 로 배치하고 싶다면 다음과 같이 지정한다.

grid-template-columns: 2fr 1fr 2fr;

 

값이 반복될 때 줄여서 표현할 수 있는 repeat()함수

px이나 fr 단위를 사용하면 똑같은 값을 여러번 반복해야 한다.

CSS 그리드 레이아웃에는 내장된 repeat()이라는 함수를 사용하면 반복하지 않고 간단하게 표현할 수 있다.

예를 들어 너비가 같은 칼럼을 3개 배치하려면 1fr을 3번 사용하는데, repeat() 함수를 사용하면 다음과 같이 간단하게 작성할 수 있다.

grid-template-columns: 1fr 1fr 1fr;
grid-template-columns: repeat(3,1fr);

 

최솟값과 최댓값을 지정하는 minmax() 함수

앞에서 살펴본 예제에서는 줄 높이를 100px로 지정했다.

그래서 줄 높이보다 내용이 더 많으면 보이지 않았다.

이럴때 minmax() 함수를 사용하면 줄 높이를 고정하지 않고 최솟값과 최댓값을 사용해서 유연하게 지정할 수 있다.

다음 예제는 너비가 같은 칼럼 3개를 반복하는데, 칼럼의 너비는 그리드 컨테이너의 너비에 따라 달라진다.

그리고 줄 높이는 최소 100px로 지정하고, 내용이 많아도 다 표시할 수 있을 만큼 높이가 늘어난다.

<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>CSS Grid Layout</title>
  <style>
    #wrapper{
        width:600px;
      display:grid;
      grid-template-columns: repeat(3,1fr);
      grid-template-rows:minmax(100px,auto);
    }
  .items{
    padding:10px;
    background-color:#eee;
  }   
  .items:nth-child(odd){
    background-color:#bbb;
  }
  </style>

</head>
<body>
  <div id="wrapper">
    <div class="items">Lorem ipsum dolor sit amet consectetur adipisicing elit. Amet, reprehenderit.Lorem ipsum dolor, sit amet consectetur adipisicing elit. </div>
    <div class="items">Lorem ipsum dolor, sit amet consectetur adipisicing elit.Lorem ipsum dolor, sit amet consectetur adipisicing elit</div>
    <div class="items">Lorem ipsum dolor sit amet.Lorem ipsum dolor, sit amet consectetur adipisicing elit</div>
    <div class="items">Lorem ipsum dolor sit.Lorem ipsum dolor, sit amet consectetur adipisicing elit</div>
    <div class="items">Lorem, ipsum dolor.</div>
  </div>
</body>
</html>

 

자동으로 칼럼 개수를 조절하는 auto-fill, auto-fit 값

앞에서 repeat() 함수를 사용해서 크기가 같은 칼럼을 반복할 때는 다음과 같이 칼럼의 개수를 지정했다.

grid-template-columns: repeat(3, 1fr);

이때 칼럼의 너빗값과 함께 auto-fit이나 auto-fill을 지정하면 화면 너비에 따라 칼럼 개수를 조절할 수 있다.

예를 들어 다음과 같이 너비가 200px인 칼럼을 화면 너비에 가득 찰때까지 배치한다.

grid-template-columns: repeat(auto-fit, 200px);

auto-fit이나 auto-fill 모두 칼럼 개수를 자동으로 조절해 주므로 화면이 넓어지면 칼럼 개수가 많아지고 반대로 화면이 좁아지면 칼럼 개수가 줄어든다.

두 값의 차이점은 남는 공간을 채울지 말지여부에 달려있다.

auto-fit은 화면이 최소너비 이상으로 남더라도 column을 더 넣지 않고 기존 컨텐츠를 넓혀 화면을 꽉 채우지만

auto-fill을 사용하면 최소 너비 이상의 공간이 남으면 빈 column을 생성한다.

 

그리드 항목의 간격을 지정하는 column-gap, row-gap, gap 속성

지금까지 살펴본 예제처럼 기본으로 만들어지는 그리드 레이아웃은 항목이 서로 붙어 있다.

이때 항목과 항목 사이의 간격을 조절하려면 다음 표와 같은 속성을 사용한다.

종류 설명
column-gap 칼럼과 칼럼 사이의 간격을 지정한다.
row-gap 즐과 줄 사이의 간격을 지정한다.
gap 칼럼과 줄 사이의 간격을 한꺼번에 지정한다.

예를 들어 줄과 줄 사이의 간격을 20px로 하고, 칼럼과 칼럼 사이의 간격을 30px로 하려면 다음과 같이 지정할 수 있다.

row-gap: 20px;
column-gap: 30px;

gap 속성을 이용해 칼럼과 줄의 간격을 한꺼번에 지정할 수도 있는데, 이때 첫 번째 값은 grid-row-gap에 해당하고 두 번째 값은 column-gap에 해당한다.

즉 다음과 같이 작성할 수 있다.

<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>CSS Grid Layout</title>
  <style>
    #wrapper{
      display:grid;
      grid-template-columns: repeat(3,200px);
      gap: 20px;
    }
  .items{
    padding:10px;
    background-color:#eee;
  }   
  .items:nth-child(odd){
    background-color:#bbb;
  }
  </style>

</head>
<body>
  <div id="wrapper">
    <div class="items">Lorem ipsum dolor sit amet consectetur adipisicing elit. Amet, reprehenderit.Lorem ipsum dolor, sit amet consectetur adipisicing elit. </div>
    <div class="items">Lorem ipsum dolor, sit amet consectetur adipisicing elit.Lorem ipsum dolor, sit amet consectetur adipisicing elit</div>
    <div class="items">Lorem ipsum dolor, sit amet consectetur adipisicing elit.Lorem ipsum dolor, sit amet consectetur adipisicing elit</div>
    <div class="items">Lorem ipsum dolor sit amet.Lorem ipsum dolor, sit amet consectetur adipisicing elit</div>
    <div class="items">Lorem ipsum dolor sit.Lorem ipsum dolor, sit amet consectetur adipisicing elit</div>
    <div class="items">Lorem, ipsum dolor.</div>
  </div>
</body>
</html>

 

그리드 라인을 이용해 배치하기

그리드 레이아웃은 눈에 보이지 않는 그리드 라인이 포함되어 있다.

예를 들어 column 3개와 row 3개로 이루어진 그리드 레이아웃을 생각해 보자.

칼럼을 구분하는 세로줄 네개, 그리고 row를 구분하는 가로줄 네개가 존재한다.

이 그리드 라인을 이용해서 그리드 항목을 배치할 수 있는데, 이때 사용하는 속성은 다음과 같다.

종류 설명 예시
grid-column-start 칼럼 시작의 라인 번호를 지정한다. grid-column-start: 1
grid-column-end 칼럼 마지막의 라인 번호를 지정한다. grid-column-end: 1
grid-column 칼럼 시작 번호와 칼럼 끝 번호 사이에 슬래시(/)를 넣어 사용한다. grid-column: 1/4
grid-row-start 줄 시작의 라인 번호를 지정한다. grid-row-start: 2
grid-row-end 줄 마지막의 라인 번호이다. grid-row-end:4
grid-row 줄 시작과 줄 끝 번호 사이에 슬래시(/)를 넣어 사용한다 grid-row: 2/4

예를 들어 다음과 같은 그리드 레이아웃을 만든다고 가정해 보자.

우선 box1부터 box4 영역까지 감싸고 있는 #wrapper 요소를 그리드 레이아웃 컨테이너로 지정하고, 칼럼은 1fr씩 3개로, 줄 높이는 repeat(3,100px)로 지정한다.

<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>CSS Grid Layout</title>
  <style>
    div{
      text-align: center;
    }
    #wrapper{
      width: 700px;
      display: grid;
      grid-template-rows: repeat(3,100px);
      grid-template-columns: repeat(3,1fr);
    }
    .box1{
      background-color: blue;
      grid-column: 1/4;
    }    
    .box2{
      background-color: green;
      grid-row:2/4;
    }
    .box3{
      background-color: red;
      grid-column:2/4;
    }
    .box4{
      background-color: purple;
      grid-row:3/4;
      grid-column:3/4;
    }
    
  </style>

</head>
<body>
  <div id="wrapper">
    <div class="box1">1</div>
    <div class="box2">2</div>
    <div class="box3">3</div>
    <div class="box4">4</div>
  </div>
</body>
</html>

 

 

템플릿 영역을 만들어 배치하기

앞에서 살펴본 그리드 라인은 시작 번호와 끝 번호를 일일이 지정해서 레이아웃을 만들어야 했다.

템플릿 영역으로 항목을 배치하면 그리드 레이아웃을 만드는 것보다 더 쉽다.

지금부터 템플릿 영역을 사용해서 앞에서 배치한 항목과 똑같은 레이아웃을 만들어 보겠다.

방법은 다음과 같다.

1. 항목에 적용할 스타일에 grid-area: 영역명; 속성을 추가한다.

2. 레이아웃 컨테이너의 스타일에 grid-template-areas: 배치구조; 속성을 추가한다.

배치구조를 입력하는 방법은 예제를 참고하자.

<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>CSS Grid Layout</title>
  <style>
    div{
      text-align: center;
    }
    #wrapper{
      width: 700px;
      display: grid;
      grid-template-rows: repeat(3,100px);
      grid-template-columns: repeat(3,1fr);
      grid-template-areas:
        "box1 box1 box1"
        "box2 box3 box3"
        "box2 . box4"
    }
    .box1{
      background-color: blue;
      grid-area: box1;
    }    
    .box2{
      background-color: green;
      grid-area: box2;
    }
    .box3{
      background-color: red;
      grid-area: box3;
    }
    .box4{
      background-color: purple;
      grid-area: box4;
    }
    
  </style>

</head>
<body>
  <div id="wrapper">
    <div class="box1">1</div>
    <div class="box2">2</div>
    <div class="box3">3</div>
    <div class="box4">4</div>
  </div>
</body>
</html>

 

+ span을 이용해 배치하기

여러 칸을 차지할 요소에 span 요소값을 부여하여 여러 칸을 차지하게 할 수도 있다.

.calculator form .clear{
    grid-column: span 3;
}

.calculator form .result{
    grid-column: span 2;
}

댓글