[Bootstrap] Layout : Grid

작성:    

업데이트:

카테고리:

태그: , ,

Grid

앞서 다루던 Utility에서 Flex를 더 다뤄보려고 하니 breakpoint prefix에 대한 얘기가 안 나올 수 없었고, 이미 이전 포스트에서도 이후에 설명할 것이라고 간간히 지나갔는데 이를 먼저 짚고 넘어가야 할 것 같아서 Grid에 대한 설명을 한다.


Grid와 구성 요소

Grid란 row와 col의 방식으로 레이아웃을 구성하여 디자인과 배치에 도움을 주는 방식이다. Bootstrap의 Grid system은 Flexbox로 제작되었으며, Column, Gutter, Container로 구성되어 있다.

Column은 실제 컨텐츠를 포함하는 부분이고, Gutter는 column과 column 사이의 공간을 의미한다. 그리고 이 column들을 모두 담고 있는 공간이 Container이다. 이 Container 내에서 row와 col을 작성하는데, container 역시 viewport에 따라 여러 종류로 구분되긴 하지만 이에 대해 다루지는 않을 것이다.


12 columns

image

Grid는 12개 columns 방식과 16개 columns 방식이 있는데, 부트스트랩에서는 12 columns 방식을 사용한다. 그 이유는 12가 약수가 많아서 breakpoint에 따라 다양한 columns로 묶어서 나누어 구성할 수 있다는 장점 때문이다.


6 breakpoints

Grid layout은 viewport에 따라 6가지의 section으로 나뉜다.

Extra small (xs)
Small (sm)
Medium (md)
Large (lg)
Extra large (xl)
Extra extra large (xxl)


그리고 이에 대한 자세한 정보는 아래와 같다.

image


기존 breakpoint를 사용할 때처럼 특정 px을 breakpoint로 설정하면 그 이후에 대해서 해당 col을 적용한다는 의미이다. d-none이 있고, md breakpoint 이후부터는 block으로 보이게 하고 싶다면 d-none d-md-block 처럼 -md- infix를 사이에 넣어주면 되겠다.


Grid의 사용

Auto-layout columns

Grid는 container 내에서 시작된다. 이 container 내에서 row와 col 클래스로 구성되며, row 클래스를 부여한 태그 내에 자식 태그로 col 클래스를 부여하면 되겠다.

이때 단순히 col만 사용하면 col의 개수에 따라 자동으로 너비를 맞춰준다.


<div class="container">
  <div class="row">
    <div class="col">1 of 2</div>
    <div class="col">2 of 2</div>
  </div>
  <div class="row">
    <div class="col">1 of 3</div>
    <div class="col">2 of 3</div>
    <div class="col">3 of 3</div>
  </div>
</div>

위의 태그처럼 작성하면 아래와 같은 결과를 가질 수 있다.

image

첫 번째 row는 내부에 2개의 col을 가지고 있어서 전체 너비의 절반씩을 차지하고, 두 번째 row는 내부에 3개의 col을 가지고 있어서 전체 너비의 1/3씩을 차지한다.


Setting one column width

이때 col-#의 클래스, 즉 col에 12이하의 숫자를 넣어 차지하는 columns의 개수를 임의로 설정한다. 만약 나머지는 col로 지정하고 하나만 col width를 부여해주면 어떻게 될까.


<div class="container">
  <div class="row">
    <div class="col">1 of 3</div>
    <div class="col-6">2 of 3 (wider)</div>
    <div class="col">3 of 3</div>
  </div>
  <div class="row">
    <div class="col">1 of 3</div>
    <div class="col-5">2 of 3 (wider)</div>
    <div class="col">3 of 3</div>
  </div>
</div>

첫 번째 row에는 2번째 col에 6을 설정하고, 두 번째 row에도 2번째 col에 5를 설정하였다. 그 결과이다.


image

첫 번째 row의 두 번째 col은 12 중에 6, 즉 절반의 너비를 가지게 되었고, 나머지는 auto이기 때문에 같은 크기를 가져가게 되었다.

두 번째 row의 두 번째 col은 절반보다 조금 안 되는 5만큼의 너비를 가졌다. 그래서 위의 col-6보다는 조금 작다. 역시 col width를 따로 지정하지 않은 양 옆의 col들은 남은 공간을 같은 크기만큼 가져갔다.


Setting all columns width

모든 col들에 col width를 부여해보겠다.

<div class="container">
  <div class="row">
    <div class="col">col</div>
    <div class="col">col</div>
    <div class="col">col</div>
    <div class="col">col</div>
  </div>
  <div class="row">
    <div class="col-8">col-8</div>
    <div class="col-4">col-4</div>
  </div>
</div>

비교군으로 col 4개를 가지는 row를 두겠다.


image

결과 화면이다. 위의 col 4개는 자동으로 columns를 나눠 갖지만, row의 모든 col이 12개의 col width를 가진다면 똑같이 container에는 꽉 찬 너비를 가지면서 비율이 달라지게 된다.

만약 col width의 합이 12보다 작다면 container 내부에 여백이 생길 것이고, col width의 합이 12보다 크면 한 줄이 아니라 두 줄로 변경되며 줄 바꿈이 된다.


본격적인 반응형 웹 대응

Mix and Match

breakpoint infix를 col과 width 사이에 넣어 특정 breakpoint 이상이면 col width를 다르게 부여하여 반응형 웹에 대응해본다.


<div class="container">
  <!-- Stack the columns on mobile by making one full-width and the other half-width -->
  <div class="row">
    <div class="col-md-8">.col-md-8</div>
    <div class="col-6 col-md-4">.col-6 .col-md-4</div>
  </div>

  <!-- Columns start at 50% wide on mobile and bump up to 33.3% wide on desktop -->
  <div class="row">
    <div class="col-6 col-md-4">.col-6 .col-md-4</div>
    <div class="col-6 col-md-4">.col-6 .col-md-4</div>
    <div class="col-6 col-md-4">.col-6 .col-md-4</div>
  </div>

  <!-- Columns are always 50% wide, on mobile and desktop -->
  <div class="row">
    <div class="col-6">.col-6</div>
    <div class="col-6">.col-6</div>
  </div>
</div>

col-md- prefix를 사용한 html 파일이다. 그 결과를 아래에서 보자.


image

두 번째 row를 보면 각각 col-6 col-md-4가 부여되었다. 이는 즉, md(medium) 시점 이전에는 default col-6으로 최대 2개까지 배치되도록 하다가, md 시점을 지나면 col-4로 최대 3개까지 배치되도록 하겠다는 코드이다. 사진은 3개가 한 라인에 있으므로 col-4로 적용되는 medium px 보다 넓은 viewport에서의 모습이라고 보면 되겠다.


Row columns

지금까지는 col-# 식으로 col width를 col 태그에 위치시켰다. 하지만 row에서 한 번에 이들을 조작하는 방법은 없을까. 그것이 row columns이다. row-col-# 로 사용한다. 물론 breakpoint infix도 사용이 가능하다. 예시를 살펴보자.

<div class="container">
  <div class="row row-cols-2">
    <div class="col">Column</div>
    <div class="col">Column</div>
    <div class="col">Column</div>
    <div class="col">Column</div>
  </div>
</div>

image

원래 같았으면, col이 2개씩 나오게 하고 싶었다면 col마다 col-6로 절반의 col width를 부여했어야 했다. 그런데 row 태그에서 row-cols-2 클래스를 부여해 ‘이 row에는 2개의 col만 항상 배치되게 한다’ 라는 의도를 완성시켰다.


<div class="container">
  <div class="row row-cols-3">
    <div class="col">Column</div>
    <div class="col">Column</div>
    <div class="col">Column</div>
    <div class="col">Column</div>
  </div>
</div>

image

이는 꽤나 유용하다. col이 4개가 있는 상황에서 row에 row-cols-3을 부여하면 어찌됐든 이 row는 3개의 col을 한 라인에 가져야 하기 때문에 사진처럼 마지막 col은 다음 라인에 배치되게 된다.


<div class="container">
  <div class="row row-cols-auto">
    <div class="col">Column</div>
    <div class="col">Column</div>
    <div class="col">Column</div>
    <div class="col">Column</div>
  </div>
</div>

image

“With .row-cols-auto you can give the columns their natural width.” 즉, row-cols-auto를 사용하면 col들이 가지고 있는 각각의 content나 width만큼 col을 차지한다는 것이다. 예시 코드는 모두 Column으로 동일하기 때문에 같은 크기의 블럭으로 결과가 나온다.

content 크기만큼의 col width를 가진 inline적 요소라고 생각하면 되겠다.


<div class="container">
  <div class="row row-cols-4">
    <div class="col">Column</div>
    <div class="col">Column</div>
    <div class="col-6">Column</div>
    <div class="col">Column</div>
  </div>
</div>

코드를 보면 row-cols-4 이므로 4개의 col이 오고, 3번째 col이 6의 width를 가지므로 나머지가 2씩 가지면 될 것이라고 생각할 수 있다.


image

하지만 결과를 보면 예상과 다르다는 것을 알 수 있다. row에서는 row-cols-4에 걸맞게 모든 col width를 3씩 주면서 그려나가고 있다가 col-6을 만나며 12칸의 column을 모두 채우게 된 것이다. 그래서 다음 col을 밑의 줄로 내려주는 것이다.


<div class="container">
  <div class="row row-cols-1 row-cols-sm-2 row-cols-md-4">
    <div class="col">Column</div>
    <div class="col">Column</div>
    <div class="col">Column</div>
    <div class="col">Column</div>
  </div>
</div>

결과 사진은 viewport에 따라 다르게 나오니 말로 설명하도록 하겠다. 기본적으로는 1라인에 1col씩 두되, sm인 576px 이상부터는 1라인에 2col씩 두고, md인 768px 이상부터는 1라인에 4col씩 배치하라는 말이다.

이는 col 마다 클래스를 부여한다면 col-12 col-sm-6 col-md-3을 각각 주면서 구현할 수 있다. 하지만 row에 row-cols-{breakpoint}-# 형식의 클래스를 부여하며 row 선에서 깔끔하게 정리하였다.


offset


Nesting

<div class="container">
  <div class="row">
    <!-- 1번 col -->
    <div class="col-sm-3">Level 1: .col-sm-3</div>

    <!-- 2번 col -->
    <div class="col-sm-9">
      <div class="row">
        <div class="col-8 col-sm-6">Level 2: .col-8 .col-sm-6</div>
        <div class="col-4 col-sm-6">Level 2: .col-4 .col-sm-6</div>
      </div>
    </div>
  </div>
</div>

row 안에 2개의 col을 가지는데, 1번 col은 단순한 col이고, 2번 col은 내부에 또다시 row와 col을 가지는, 하나의 container로서 작용하고 있다.

col 내부에서 row를 선언하며 다시 그 내부에 col들에 대한 속성들을 부여하면서 container 안의 container를 구현하였다. 결과를 확인해보자.

image


<div class="container">
  <div class="row">
    <div class="item col-md-3">item1</div>
    <div class="item col-md-9">
      <div class="row row-cols-2 row-cols-lg-4">
        <div class="item3">item2</div>
        <div class="item3">item3</div>
        <div class="item3">item4</div>
        <div class="item3">item5</div>
      </div>
    </div>
  </div>
</div>

이를 크기에 맞게 살펴보자.


image

md인 768px 이전의 모습이다. col들이 각각의 라인을 설정해 block처럼 존재한다. 그런데 md인 768px을 기점으로 3칸과 9칸의 col width를 가지며 1라인에 두 col이 존재하게 되었다.

image

이 과정동안 두번째 col 내부의 2*2 col들의 레이아웃은 변하지 않는다. 하지만 row-cols-lg-4에 의해 lg인 992px을 기점으로 1라인에 4칸의 col들이 들어가게 된다.

image


REFERENCE

댓글남기기