[CSS] 2차원 레이아웃 시스템 Grid

손규성·2022년 10월 16일
0

html & css

목록 보기
1/2

Grid vs Flex


그리드는 수평선과 수직선으로 이루어진 웹페이지 레이아웃 시스템으로, 여러 요소들을 편리하게 정렬할 수 있게 해주는 도구이다. 자주 사용되는 flex와 비교했을 때 flex는 1차원적인 레이아웃 시스템, grid는 웹페이지의 행과 열을 모두 관여할 수 있는 2차원 레이아웃 시스템이라는 점이 가장 큰 차별점이다.

이미지 출처: 1분 코딩

  • flex는 한 방향 레이아웃 시스템 (1차원)
    - 즉 정렬하는 자식요소 묶음마다 container 요소가 있어야 한다
  • grid는 행-열 동시 설정 가능한 2차원 레이아웃 시스템
    - 정렬하는 행열을 하나의 container요소만 사용하면 된다

Grid 시작하기


컨테이너(container) 요소를 만들고 3개의 <div>를 안에 넣어준다. (잘 보이게 하기 위해서 가벼운 css 스타일링 포함). 이후 별도의 레이아웃 시스템을 사용하지 않으면 default 값으로 아래 이미지처럼 배치된다.

HTML:

<div class="container">
  <div class="one">item 1</div>
  <div class="two">item 2</div>
  <div class="three">item 3</div>
</div>

결과:

이때 flex 레이아웃 시스템을 사용할 때와 같이, container 요소에 display: grid를 주게 되면 아무 일도 일어나지 않는다. grid를 사용할 때는 행과 열의 기준을 잡아줘야 한다.

CSS:

.container { 
	display: grid; 
    
	border: 5px solid black;
    width: 600px;
}

grid-template-rows & grid-template-columns

그리드 형태는 grid-template-rows를 통해 행(rows)의 크기와 배치를 정의하고, grid-template-columns을 통해 columns(열)의 크기와 배치를 정의한다. 크기를 표현하기 위해 여러가지 단위를 사용할 수 있다.

Example:

  1. 컨테이너를 3열로 나누고, 순서대로 400px, 100px, 100px의 크기 지정
.container {
	display: grid;
    grid-template-columns: 400px 100px 100px; 
}

  1. 컨테이너를 2열로 나누고, 각 열의 크기를 1fr로 지정
    • fr은 fraction의 약자로 숫자 비율대로 트랙을 나눈다
    • 1fr 1fr 은 트랙을 균일하게 1:1 비율인 두 개의 열로 나누겠다는 뜻이다
    • 마찬가지로 1fr 2fr 1fr 은 트랙을 1:2:1 비율로 나눔
.container {
	display: grid;
    grid-template-columns: 1fr 1fr; 
}

  1. 컨테이너의 총 3열로 나누고, 첫번째 열을 100px으로, 나머지 열들을 2:1 비율로 지정
.container {
	display: grid;
    grid-template-columns: 100px 2fr 1fr;
}

  1. repeat 함수를 사용해서 작성한 케이스. 1fr 1fr 1fr과 똑같이 컨테이너를 3개의 열로 나누고 각 열의 크기를 1fr로 지정한다.
    • repeat(3, 1fr) = 1fr 1fr 1fr
.container {
	display: grid;
    grid-template-columns: repeat(3, 1fr);
}

  1. 컨테이너를 3개의 행으로 나누고, 제일 상단부터 각 행의 크기를 50px, 100px, 50px로 지정한다.
.container {
	display: grid;
    grid-template-rows: 50px 100px 50px;
}

  1. 컨테이너를 3 x 2 행열로 만들고 각 열의 크기는 1fr, 각 해의 크기는 50px로 지정한다.
.container {
	display: grid;
    grid-template-rows: 50px 50px 50px;
}

  • 행열의 칸 수가 item 요소 수보다 많은 경우, 행-열 순으로 item을 배치하고 남은 칸은 비워둔다.
  • item요소를 더 만들면 남은 칸을 다 채운다.

grid-template-areas


  • 각 칸 grid area에 이름을 붙이고, 그 이름을 이용해서 레이아웃을 잡을 수 있는 아주 직관적인 방법이다.
  • 우선 각 item요소에 grid-area값을 선언해주어야 한다.

Example:

.one { grid-area: one; }
.two { grid-area: two; }
.three { grid-area: three; }
.four { grid-area: four; }

.container {
	display: grid;
    grid-template-columns: 1fr 1fr;
    grid-template-rows: 50px 50px 50px;
    grid-template-areas:
    "one one"
    "two three"
    "four four";
}

  • 3 x 2 행열인 컨테이너에 각 grid-area를 사용해서 자유롭게 배치 가능하다
  • 첫 번째 행에 두 개의 열 모두 item 1이 차지하게 하기 위해 "one" 을 두 번 작성한다. 두 번째 행은 item 2item 3가 나눠서 들어가게 하기 위해서 "two"와 "three"를 원하는 순서대로 작성해준다.
  • 마지막 줄에는 four를 두 번 작성해주어 첫 번째 행에서 item 1이 모든 열으 차지한 것처럼 extra item 4이 마지막 행의 모든 열을 차지할 수 있도록 한다.
  • 이때 마지막 행에 다시 "one one"을 작성하면 item 1이 다시 가장 밑 행에 들어가는 것이 아니라 오류가 나게 된다. 즉 서로 맞대고 있는 area가 아닌 곳에 같은 item을 넣을 수는 없다.

gap


  • row-gap : 행(row) area 간격을 지정
  • column-gap : 열(column) area 간격을 지정
  • gap : 컨테이너 안에 포함되어 있는 모든 area의 행열 간격 지정

row-gap Example:

.one { grid-area: one; }
.two { grid-area: two; }
.three { grid-area: three; }
.four { grid-area: four; }

.container {
	display: grid;
    grid-template-columns: 1fr 1fr;
    grid-template-rows: 50px 50px 50px;
    row-gap: 10px;
    grid-template-areas:
    "one one"
    "two three"
    "four four";
}

column-gap Example:

.one { grid-area: one; }
.two { grid-area: two; }
.three { grid-area: three; }
.four { grid-area: four; }

.container {
	display: grid;
    grid-template-columns: 1fr 1fr;
    grid-template-rows: 50px 50px 50px;
    column-gap: 10px;
    grid-template-areas:
    "one one"
    "two three"
    "four four";
}

gap Example:

.one { grid-area: one; }
.two { grid-area: two; }
.three { grid-area: three; }
.four { grid-area: four; }

.container {
	display: grid;
    grid-template-columns: 1fr 1fr;
    grid-template-rows: 50px 50px 50px;
    gap: 10px;
    grid-template-areas:
    "one one"
    "two three"
    "four four";
}

profile
블로그 이사 → https://sqsung.tistory.com/

0개의 댓글