FrontEnd/css

[css/layout] css layout 방법 - 2️⃣ grid

김평범님 2020. 12. 18. 20:00
반응형

💜 2020 State of CSS Survey

1편에서는 레이아웃 중 가장 사랑받는 flexbox를 살펴보았다면

이번 편에서는 grid를 살펴보려고 한다. 

 

사실 실무에서  flexbox를 너무 잘 활용하고 있었고,

flexbox로 아쉬운 부분들은 기존 float방식으로 충분히 원하는 레이아웃을 짤 수 있었기에 

새로운 layout에 대한 필요성을 아직 느끼지 못했다.

flexbox 사용이 궁금하다면 전의 포스팅을 먼저 참고하고 오자!

 

[css/layout] CSS Layout 방법 - 1️⃣ flexbox

💜 2020 State of CSS Survey 2020년 State of CSS Survey 결과가 발표되었다. 개발자의 고충은 내가 만들긴 했는데 이 방법을 써도 되는 걸까?라는 의문을 항상 갖게 된다. 이럴 때 도움이 되는 것은 Survey! 201.

ordinary-code.tistory.com

 

이번에 grid에 주목하고 싶은 이유는 2020 State of CSS Survey 결과에서

grid를 사용해봤다는 응답자 수가 2019년에는 54.7% 였지만, 

2020년에  73.3%로 큰 폭으로 늘었기 때문이다.

 

Grid를 사용한 사람이 2020년에 큰폭으로 늘어났다.

 

사용해본 사람이 늘었다는 건 그만큼 편리하거나 이제 다들 gird에 주목하고 있는 건 아닐까? 

그리고 73%나 알고 있는걸 이제 모르면 안 된다는 생각이 강하게 들었기 때문에

오늘은 css layout 방법 중 gird에 대해 공부해보려고 한다.

 

사실 필자도 아직 실무에서 활용해본 적이  전혀 없어 이번 포스팅으로 grid의 매력을 찾아볼 예정이다.

 


👧 Grid에 대해 기본 다지기

Grid에 대한 기본 배경

Grid를 이용하면 기존 float나 position을 사용하지 않고도 

간단히 레이어를 짤 수 있도록 해준다고 한다.

 

다만 문제는 Internet Explorer를 모든 버전에서 지원하지 않고

오직 edge에서만 해당 기능을 사용할 수 있다는 점이다

 

반드시 Internet Explorer를 이용해야 하는 개발자들은

이를 보안할 수 있는 방법을 찾지 않는 이상 도입하긴 힘들 것으로 보인다.

(다행히 나는 익스플로러에 자유로운 개발자라 일단 보안법 대신 사용법만 포스팅에서 다뤄보고자 한다.)

 

 

 

 

Grid 기본 구조

Grid도 flex와 마찬가지로 

Gird 컨테이너grid 아이템으로 이루어진다.

레이아웃을 짜야할 item들을 grid 컨테이너로 감싸줘야 정상적으로 작동한다.

 

전체 Code

<html>
<head>
    <style>
        @font-face {
            font-family: 'Cafe24Oneprettynight';
            src: url('https://cdn.jsdelivr.net/gh/projectnoonnu/noonfonts_twelve@1.1/Cafe24Oneprettynight.woff') format('woff');
            font-weight: normal;
            font-style: normal;
        }
        * {
            font-family: 'Cafe24Oneprettynight';
            font-size:16px;
        }
        .grid-container {
            padding:10px;
            display:grid;
        }
        .grid-container div {
            padding:10px;
            margin:10px;
            border-radius:10px;
            color:#fff;
            background:lightcoral;
        }
    </style>
</head>
<body>
    <div class="grid-container">
        <div>box-1</div>
        <div>box-2</div>
        <div>box-3</div>
        <div>box-4</div>
        <div>box-5</div>
        <div>box-6</div>
    </div>
</body>
</html>

 

HTML

정렬을 원하는 element를 생성한 뒤 전체를 감싸는 . grid-container element를 생성해주었다.

 

<div class="grid-container">
  <div>box-1</div>
  <div>box-2</div>
  <div>box-3</div>
  <div>box-4</div>
  <div>box-5</div>
  <div>box-6</div>
</div>

 

CSS

.grid-container element에 display:grid 속성을 설정해주었다.

 

.grid-container {
	display:grid;
}

 

 

css grid 적용된 결과화면

 

결과적으로 flex를 적용했을 때와는 다르게 display:block형태와 거의 동일한 화면이 나타났다.

화면상으로는 변경된 것이 없지만 지금부터 우린 css grid를 사용할 준비가 된 것이다.

 

지금부터 grid에서 제공하는 개념과 속성으로 우리의 입맛에 맞는 레이아웃을 구성해보도록 하겠다.

 

 

 

 

Grid를 사용하기 위해  반드시 알아야 되는 개념

 

처음 gird 도 생소하겠지만, 일단 용어를 모르면 밑의 얘기가 잘 이해가 안 될 것 같아

grid 구성을 하고 있는 몇가지의 개념을 알고 넘어가 보자.

 

 

css grid를 이용해 만들고 싶은 레이아웃을 상상해보자.

예를 들어 카드뉴스를 만들어본다고 가정해보자!

각 줄마다 3개씩  카드 뉴스가 나열되는 방식이며 카드 뉴스가 총 9장이 있다고 상상해보자.

9장의 카드뉴스로 구성된 레이아웃

 

 

 

 

 

Column/Row

위 의 형식의 카드 뉴스를 grid를 이용해서 만든다고 했을 때

해당 레이아웃은 column 과 row로 이루어져 있다.

 

 

세로 선을 기준으로  나뉘는 구역을 Column 이라고 한다.

 

grid의 세로선을 기준으로 나눠지는 column 구역

 

 

가로선을 기준으로 나누어지는 구역이 Row라고 한다.

 

grid의 가로선을 기준으로 나눠지는 Row 구역

 

 

 

 

Grid Line

gird에서 Column과 Row로 나눠지면서 선들이 생기게 된다.

이때 도 마찬가지로 세로선을 Column Line이라고 하며 가로 생기는 선을 RowLine이라고 한다.

 

Column Line:  Grid 구역에서 세로로 나눠지는 선 왼쪽부터 오른쪽으로 세어나간다.

 

column-line

 

 

Row Line : Grid 구역에서 가로로 나눠지는 선 위에서 아래로으로 세어나간다.

 

 

row-line

 

GridCell

grid line들이 교차하면서 만들어진 공간을 grid-cell이라고 말한다.

 

grid-cell

 

GridGap

Column과 Row 사이사이를 띄우는 영역을 말한다.

 

Grid-gap 영역

 

 


1️⃣ Grid Container에서 사용 가능한 속성

grid-template-columns

 grid container에 grid-template-columns을 이용하면

우리가 만든 grid 구역을  column을  몇 칸으로 구성할지를 정할 수 있다.

 

처음 만든 예제에 아래의 속성을 추가한 뒤 실행해보자.

 

.grid-container {
  grid-template-columns: auto auto auto;
}

 

grid-template-columns: auto auto auto 결과화면

auto를 3번 적어준 것으로 우리는 해당 grid에 column을 3개의 구역으로 나눌 수 있게 되었고

해당 넓이 값은 auto를 설정했기 때문에 자동적으로 동일한 넓이를 계산해주었다.

 

이처럼 grid-template-columns에 column이 차지할 값을 입력해주면 해당 값의 수만큼 column 구역이 나뉘게 된다.

 

 

grid-template-columns 단위

 

auto : 본인의 내부 콘텐츠의 크기만큼의 값을 기본적으로 가지고 구역을 나눔

px : column의 구역을 px단위의 고정값으로 구역을 나눔.

% : column 구역을 % 단위로 계산해서 구역을 나눔

fr : grid에서 여유 공간에서 얼마만큼의 비율로 크기를 할당할지를 설정한다.(분수의 개념으로 이해하면 된다)

 

grid-template-columns: 100px 100px 100px;
grid-template-columns: 20% 50% 30%; 결과화면

 

 

grid-template-columns의 여러 개 단위를 혼합하여 사용해도 상관없다.

아래와 같은 코드를 넣고 반응형 테스트를 진행했다.

 

grid-template-columns: 2fr 150px 30px 1fr auto;

 

grid-template-columns: 2fr 150px 30px 1fr auto; 반응형 결과

 

150px , 30px 등 px로 나눠진 grid는 스크린 크기가 작아져도 넓이가 해당 값으로 고정되었다.

auto의 경우 자신의 콘텐츠가 가지고 있는 크기만의 최소한의 크기를 유지하며

fr의 경우 스크린 크기가 변경되면서 남은 여유공간을  지정한 크기만큼 유지하면서 넓이가 줄어드는 걸 확인할 수 있다.

 

 

 

 

grid-template-rows

grid container에 grid-template-rows는 

우리가 만든 grid 구역에서 row의 구역의  높이를  설정할 수 있다.

 

마찬가지로 처음 만들었던 속성에 grid-template-rows 예제를 만들어서 적용해보았다.

 

.grid-container {
  height:300px;
  grid-template-columns: auto auto;
  grid-template-rows: 80px 50px 40px;
}

 

grid-template-rows: 80px 50px 40px 결과화면

사용 방법은 grid-template-columns와 동일하며, 사용할 수 있는 단위도 동일하다.

 

grid-template-rows 단위

 

auto : 본인의 내부 콘텐츠의 크기만큼 row 높이가 설정됨

px : 지정된 px단위로 row 높이가 설정됨 

% : grid 높이에서  지정한 % 만큼 차지하는 값이 row 높이로 설정됨

fr : grid의 여유 공간에서 얼마만큼의 비율로 크기를 할당할지를 설정한다.(분수의 개념으로 이해하면 된다)

 

각 grid-template-rows 사용법은 grid-template-columns와 거의 동일하니 테스트를 통해서 확인해보길 바란다😅

 

 

 

🧨grid-template-rows와 grid-item margin과의 관계

 

예시 코드에서 grid-item에 margin:10px 속성이 추가된 상태였다.

확인해보니 grid-template-rows에 px로 높이를 설정해줄 경우 해당 margin값까지 포함해서 높이값으로 설정된다.

grid를 사용할 때 grid-item과의 적절한 간격을 유지하기 위해서

margin 값보다는 grid-gap을 이용하는 게 더 좋다.

 

grid item에 margin이 있을 경우 결과화면

 

 

grid-gap

grid-gap속성은 row와 column 사이의 간격을 지정해줄 수 있다.

예시를 보자.

 

기존과 동일하게 grid-template-rows: 80px 50px 40px; 속성을 준 뒤 

기존 코드에서  grid-item에 지정했던 margin:10px 속성을 빼 준 뒤 grid-gap:10px; 속성을 추가했다.

 

.grid-container {
  padding:10px;
  display:grid;
  grid-template-columns: auto auto;
  grid-template-rows: 80px 50px 40px;
  grid-gap:10px;
}
.grid-container div {
  padding:10px;
  border-radius:10px;
  color:#fff;
  background:lightcoral;
}

 

grid-gap:10px 속성 추가 결과

 

 

grid-item에 margin을 제거하니 grid-item이 80px의 높이값을 갖게 되었다.

뿐만 아니라 grid-gap 속성을 추가하여 여전히 grid-item 간의 간격인 10px유지가 되는 걸 볼 수 있다.

 

grid-gap 지정 시 컨텐츠 사이에만 간격이 생기는걸 확인할 수 있다.

 

 

 

 

 

grid-template-areas 사용하기

grid-template-areas를 사용하면 좀 더 논리적인 구조로 grid를 구성할 수 있다.

grid-template-columns & grid-template-rows와 다르게 

grid-tempate-areas를 사용하면 각 구역을 이름으로 지정해서 나눠 줄 수 있다.

 

 

우리가 생각할 수 있는 가장 기본적인 홈페이지의 형태를 상상해보자.

맨 위에는 header가 있으며

그 아래 내비게이션과 콘텐츠 페이지가 있으며

그 아래 footer가 있는 게 가장 일반적인 형태일 것이다.

 

이런 형태의 페이지를 grid-template-areas를 이용하면 손쉽게 구현할 수 있다.

 

Code

<html>
<head>
    <style>
        .container {
            padding: 10px;
            display: grid;
            grid-template-areas: "header header" "nav section" "footer footer";
            grid-template-rows: 100px 400px 100px;
            grid-template-columns: 80px auto;
        }

        .container > * {
            padding: 10px;
        }
        header {
            grid-area: header;
            background:lightsteelblue;
        }
        nav {
            grid-area: nav;
            background:lightgoldenrodyellow;
        }
        section {
            grid-area : section;
            background:lightcyan;
        }
        footer {
            grid-area: footer;
            background:lightblue;
        }
    </style>
</head>
<body>
<div class="container">
    <header>header</header>
    <nav>Navigation</nav>
    <section>Main Section</section>
    <footer>Footer</footer>
</div>
</body>
</html>

 

해당 코드 결과화면

 

 

아래의 코드처럼 grid-item은  grid-area 속성을 이용하면 이름을 지정할 수 있다.

 

header {
  grid-area: header;
}
nav {
  grid-area: nav;
}
section {
  grid-area : section;
}
footer {
  grid-area: footer;
}

 

이처럼 지정한 이름을 grid-template-areas에서 어느 구역에 얼마큼 차지할지 정할 수 있다.

과거 표를 이용해서 레이아웃을 짰던 것과 비슷하다.

"" 안은 하나의 column이며 띄어쓰기를 진행하면 row를 추가하는 형식이다.

 

.container {
	grid-template-areas: "header header" "nav section" "footer footer";
}

 

이처럼 grid-template-areas를 이용하면

가장 최상의 레이아웃 형태를 매우 쉽고 직관적이게 구성할 수 있다.


2️⃣ Grid item에서 사용 가능한 속성

 

grid container에 속성을 이용해서 grid의 구역을 나눠보았다.

 

그럼 앞에서 만든 하나하나 칸에 해당하는 grid-cell에는 하나의 grid-item만 들어갈 수 있는 건가?

물론 아니다! 이 부분이 flex와 grid의 가장 큰 차이이다.

 

우리는 지금부터 grid-item의 특정 속성을 이용해서 해당 grid-item을 원하는 위치에 원하는 크기로 배치해보도록 하겠다.

 

grid-column

grid-column은  grid-column-start와 grid-column-end가 합쳐진 축약형 css이다.

해당 속성을 이용하면 grid-item이 grid column에서 얼마만큼의 grid-cell을 차지할지 지정할 수 있다.

 

 

 

column-Line 세는 방법

 

크기를 지정할 때 사용하는 것이 grid-Line이다.

각 브라우저의 개발자 도구를 활용하면 gird-line번호를 확인할 수 있다.

Column의 경우 gridLine은 왼쪽에서 오른쪽으로 숫자를 하나씩 키워서 셀 수 있고

오른쪽에서 왼쪽으로 올 경우는 -1부터 숫자가를 하나씩 줄여가면 된다.

 

크롬 개발자 도구를 이용하면 Grid-line 번호를 확인할 수 있다.

 

 

사용 예시

 

column 2칸 row가 3칸으로 이루어진 gird에서

첫 번째 grid-item이 첫 줄을 모두 차지하는 코드를 짜보았다.

grid-column-line이 총 1부터 3까지 있을 경우

처음 시작할 grid-column-line숫자를 적고 / 뒤쪽에 끝내고 싶은  grid-column-line숫자를 적어주면 된다.

 

.grid-container div:nth-child(1) {
	grid-column : 1 / 3
}

 

첫번째 div가 1부터 3라인까지 모두 차지하는걸 확인할 수 있다.

 

 

축약형이 아니라 풀어적어주면 아래 코드처럼 쓸 수 있다.

 

.grid-container div:nth-child(1) {
  grid-column-start : 1;
  grid-column-end: 3
}

 

 

 

음수 형태의 Gridline 사용해보기

 

column 3칸 row가 2칸으로 이루어진 gird에서 

첫 번째 요소가 왼쪽에서 2칸을 차지하는 결과를 만들어보자.

 

.grid-container {
  grid-template-columns: auto auto auto;
}
.grid-container div:nth-child(1) {
  grid-column-start : -1;
  grid-column-end: -3;
}

 

첫번째 div가 -1부터 -3라인을 지정하니 왼쪽에 배치되는걸 확인할 수 있다.

 

 

 

 

grid -column에서 span 사용해보기

 

위의 방식처럼 라인수를 센 다음에 처음과 끝을 지정할 수 돼있지만,

라인 수가 많아질 경우 span이라는 개념을 이용하면 좀 더 쉽게 구역을 지정할 수 있다.

 

span 뒤에 채우고 싶은 grid-cell의 수를 작성해주면

해당 숫자의 칸만큼 자동으로 채워진다.

 

예시를 보자.

//1칸 차지할 경우
.grid-container div:nth-child(1) {
	grid-column: span 1;
}


//2칸 차지할 경우
.grid-container div:nth-child(1) {
	grid-column: span 2;
}

//3칸 차지할 경우
.grid-container div:nth-child(1) {
	grid-column: span 3;
}

 

grid-column : span 1; (왼) / grid-column : span 2; (중앙) / grid-column: span 3;(오른쪽)

 

위의 결과처럼 span을 이용하면 라인을 세지 않아도

손쉽게 원하는 만큼 칸을 채울 수 있다.

 

 

span 단독 사용이 아닌 끝 속성으로 사용할 경우

grid-column-line 2번째 줄부터 시작해서 4칸을 자동으로 채워준다.

 

.grid-container div:nth-child(1) {
	grid-column: 2 / span 4;
}

 

grid-column: 2 / span 4; 결과 화면

 

 

 

grid-row

grid-row은  grid-row-start와 grid-row-end가 합쳐진 축약형 css이다.

해당 속성을 이용하면 grid-item이 grid row에서 얼마만큼의 grid-cell을 차지할지 지정할 수 있다.

 

grid-column은 column에서 얼마나 차지한다고 지정하는 속성이었으면

grid-row는 rolw에서 얼마나 차지할지 지정하는 속성이다.

 

사용방법은 column과 모두 동일하니 간단한 예제 몇 개를 보여드리고 넘어가겠다.

 

 

 

 

사용 예시

 

첫 번째 div가 가장 왼쪽에서 모든 높이를 채워보도록 하겠다.

 

.grid-container div:nth-child(1) {
	grid-row: 1 / 4;
}

 

grid-row: 1 / 4; 결과화면, row-line 1부터 4까지를 차지하게 된다.

 

 

 

첫번째 div가 가장 왼쪽 아래에서 2칸을 차지하도록 해보겠다.

 

.grid-container div:nth-child(1) {
	grid-row: -1 / -3;
}

 

grid-row: -1 / -3; 결과화면 -1부터 시작할 경우 아래서 칸을 채워나가는걸 볼 수 있다.

 

 

마찬가지로 span 사용도 가능하다.

 

.grid-container div:nth-child(1) {
	grid-row: span 3;
}

gird-row: span 3 결과화면, 위에서부터 3칸이 채워지게 된다.

 

 

 

 

 

 

 

grid-column & grid-row  혼합해서 사용해보기

당연한 말이겠지만, grid-column과 grid-row를 같이 사용하는 것도 가능하다.

아래 예시를 보자.

 

grid-line 혼합 사용 예시

 

각 div에 grid-column과 grid-row 규칙을 줘보았다.

시작과 끝 값을 라인으로 지정할 경우

div를 겹쳐서 표시하는 것도 가능하다.

 

//겹치는 효과를 보여주기 위해 opacity값 적용
.grid-container div {
  padding:10px;
  border-radius:10px;
  color:#fff;
  background:rgba(237,130,138,0.3);
  border:1px solid lightcoral;
}

.grid-container div:nth-child(1) {
  grid-column: 1 / span 2;
  grid-row: 1/ span 2;
}

.grid-container div:nth-child(2) {
  grid-column : 2 / 4;
  grid-row: 2 / span 1;
}

.grid-container div:nth-child(3) {
  grid-column : -1 / -3;
  grid-row: 1 / 3;
}

 

위 코드 결과화면
위 코드 grid-line 구조

 

 

 

 

span 혼합 사용 예시

 

grid-line이 아닌 span 속성만으로 구성해보니

조금 다르게 결과가 나타난다.

 

.grid-container div:nth-child(1) {
  grid-column: span 2;
  grid-row: span 2;
}

.grid-container div:nth-child(2) {
  grid-column : span 2;
  grid-row: span 1;
}

.grid-container div:nth-child(3) {
  grid-column : span 3;
  grid-row: span 2;
}

 

결과 화면
위 코드grid 코드

 

span을 이용해서 grid를 구성하면

grid 칸이 나눠진 곳에서 지정된 span 값이 확보되는 곳에 해당 크기의 div를 그려준다.

 

 

2번째 div의 grid-column을 span 2로 2칸을 채워야 했는데

div 1번이 이미 2칸을 차지하여 왼쪽에 1칸 밖에 남지 않았기 때문에

밑의 grid로 내려가서 2칸을 채워준다.

 

자연스럽게 자리를 차지하지 못한 곳은 여백으로 남게 된다.


3️⃣ grid-area 사용하기

 

grid-area는 grid-row-start, grid-column-start, grid-row-end, grid-column-end를

한 번에 설정할 수 있는 축약형 css이다.

 

 

grid-column : 1 /3; 과 grid -row : 1 / 3; 를 지정할 경우,

grid-item이 가로 2칸 세로 2칸을 차지하게 된다. 

이 속성을 grid-area로 바꿔볼 경우 아래처럼 축약해서 작성이 가능하다.

 

.grid-container div:nth-child(1) {
	grid-area: 1 / 1 / 3 / 3;
}

 

grid-area: 1 / 1 / 3 / 3; 결과화면

 

 


🧐 마무리하며

 

grid에서 사용할 개념과 간단한 예제로 Grid의 사용법을 배워봤다.

grid의 몇 가지 개념만 이해하면 position:absolute를 이용해야 했던 layout도 쉽게 만드는 것이 가능하고

grid의 구역의 라인만 잘 파악하면 원하는 레이아웃을 쉽게 지정할 수 있었다.

 

사용해본 결과 반응형 작업을 할 때도 편안하게 진행할 수도 있을 것 같다.

대부분 inline-box나 flex를 이용할 경우 

html 콘텐츠 위치 때문에 반응형 시 div 이동에 약간의 제약이 있었는데

이 부분이 가장 좋을 것 같다.

(만약 가장 위에 있던 div를 밑으로 옮긴다던지, 오른쪽 왼쪽 이유로 붙었던 div가 크기가 줄어들며 위아래로 붙는데 이때 때 왼쪽 콘텐츠를 위로 올리고 싶을 때가 있다. 이럴 경우 inline-block의 경우 div 순서를 따라가다 보니.. 반응형을 위해 html에 불필요한 div가 더 사용하는 경우가 있었다. (아무튼 많이 불만이 있었다. 말이 많아지게 된다.))

 

 

특히 가장 큰 레이아웃을 구성할 경우

grid-template-areas는 직관적이라서 홈페이지 등 불특정 다수의 사용자가 오는 프로젝트가 아니라

 브라우저를 컨트롤할 수 있는 소규모 사용자 프로젝트에서는 바로 적용해봐도 될 것 같다.

 

 

 


Reference

www.w3schools.com/css/css_grid.asp

 

CSS Grid Layout

CSS Grid Layout Module Header Menu Main Right Footer Try it Yourself » Grid Layout The CSS Grid Layout Module offers a grid-based layout system, with rows and columns, making it easier to design web pages without

www.w3schools.com

developer.mozilla.org/ko/docs/Web/CSS/grid

 

grid

grid CSS 속성은 shorthand property 입니다. 외재적인 속성인 (grid-template-rows, grid-template-columns, grid-template-areas), 값과 내재적인 속성인 (grid-auto-rows, grid-auto-columns, grid-auto-flow), 값을 한번에 설정합니다.

developer.mozilla.org

css-tricks.com/snippets/css/complete-guide-grid/

 

A Complete Guide to Grid | CSS-Tricks

Our comprehensive guide to CSS grid, focusing on all the settings both for the grid parent container and the grid child elements.

css-tricks.com

 

반응형