> For the complete documentation index, see [llms.txt](https://yamoo9.gitbook.io/css-grid/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://yamoo9.gitbook.io/css-grid/css-grid-layout-usage-guide/asymmetrical-grid-layout/rel-acoustics.md).

# Rel Acoustics

![dribbble.com/shots/2792525-Rel-Acoustics](/files/-LHEnPq1N36rFojJQH7s)

## Anthony Harmon의 디자인

[Anthony Harmon](https://twitter.com/aharmon)의 [Rel Acoustics 디자인 레이아웃](https://dribbble.com/shots/2792525-Rel-Acoustics/attachments/571167)은 비 정형 그리드 레이아웃을 실습하기 유용합니다. 그는 불규칙적인 구조의 레이아웃을 사용해 보다 유연하고, 세련된 디자인 결과물을 만들어 냈습니다.

![](/files/-LHG5XM5klbdB5ZFfeIh)

## 웹 그래픽 디자인 — 겹치기 <a href="#web-graphic-design" id="web-graphic-design"></a>

웹 디자이너는 문서의 흐름과 HTML 마크업 순서를 고려해 디자인 해야 합니다. 부유하는 박스로 레이아웃을 만들고, 벽돌을 쌓듯 페이지를 채웁니다. 반응형 웹 디자인의 세계에서는 이러한 접근 방법이 매우 자연스러운 것처럼 보입니다.&#x20;

하지만 고정된 판형 크기에 디자이너 자신이 원하는 위치에 텍스트와 이미지를 배치 할 수 있는 인쇄 상의 레이아웃 과는 거리가 있어 보다 실험적이고 시각적으로 대담한 레이아웃을 구현할 수 있습니다. 게다가 CSS Grid를 활용하면 `x`, `y`축을 따라 디자인 요소를 배치 할 수 있는 것 외에도, 레이아웃 간격을 메우고 설계를 통해 보다 대담한 처리가 가능합니다.

![](/files/-LHGA4i35i7RugmbwBQg)

> “We’ve got to start reimagining what good graphic design can be with overlapping things.” \
> – [Jen Simmons](https://www.youtube.com/watch?v=EashgVqboWo)

{% hint style="success" %}
Mozilla의 디자이너이자 개발자인 **Jen Simmons**는 좋은 디자인에 대해 다음과 같이 말했습니다.\
\
"**요소를 겹쳐 봄으로 좋은 그래픽 디자인을 재구성 하기 시작해야 합니다.**"
{% endhint %}

![](/files/-LHGALW_VjrV7WCVI4av)

{% embed url="<http://labs.jensimmons.com/2017/01-018.html>" %}
labs.jensimmons.com/2017/01-018.html
{% endembed %}

![](/files/-LHGAZiduQcAiE1eJqmX)

{% embed url="<http://labs.jensimmons.com/2017/01-002.html>" %}
labs.jensimmons.com/2017/01-002.html
{% endembed %}

[Anthony Harmon의 디자인](/css-grid/css-grid-layout-usage-guide/asymmetrical-grid-layout/rel-acoustics.md#anthony-harmon) 또한 [Jen Simonmons가 거론한 요소와 요소를 겹치는 행위](/css-grid/css-grid-layout-usage-guide/asymmetrical-grid-layout/rel-acoustics.md#web-graphic-design)를 통해 디자인을 재해석 하여 구성했습니다. 이미지와 이미지 또는, 이미지와 텍스트를 겹쳐 매력적인 레이아웃을 구현해냈습니다.

![](/files/-LHGDOJIN6yrPRUKiyOf)

## 그리드 정의 <a href="#define-grid" id="define-grid"></a>

Anthony Harmon의 디자인은 그리드 열(columns)이 균일하지 않아 불규칙해 보입니다.&#x20;

![](/files/-LHGGlLb7FcI54-Iv20-)

{% hint style="danger" %}
Rel Acoustics의 요소를 겹치는 레이아웃 섹션만 구현해봅니다. 다른 섹션의 레이아웃도 비슷한 방법을 사용해 구현할 수 있습니다.
{% endhint %}

섹션 요소를 그리드 컨테이너로 하는 HTML 마크업을 작성합니다.

{% code title="" %}

```markup
<section class="asymmetrical-grid">
  ...
</section>
```

{% endcode %}

이어서 섹션 요소를 그리드 컨테이너로 설정합니다.

{% code title="" %}

```css
.asymmetrical-grid {
  display: grid;
}
```

{% endcode %}

### 열 너비 계산 <a href="#calc-columns" id="calc-columns"></a>

불 규칙적으로 나열된 각 열의 폭을 계산하여 `grid-template-columns` 속성에 설정해야 합니다. 분수(fr) 계산은 가장 작은 열(55px)을 기준으로 다른 열(165px)의 크기 비율을 찾아내야 합니다.

> 55px                = 1fr \
> 165px / 55px = 3fr

![](/files/-LHGIWzvHQVzCNV8GNs2)

분수는 전체 너비의 상대적 비율로 각 열의 너비를 비율로 구성하면 다음과 같습니다.

> **3** :  **6**  :  **1**  :  **5**  :  **10**  :  **2**

찾아낸 분수 비율을 토대로 그리드 열 템플릿을 만드는 코드를 작성합니다.

{% code title="" %}

```css
.asymmetrical-grid {
  display: grid;
  grid-template-columns: 3fr 6fr 1fr 5fr 10fr 2fr;
}
```

{% endcode %}

### 행 높이 계산 <a href="#calc-rows" id="calc-rows"></a>

그리드 행 템플릿은 고정 또는 자동(auto) 값을 사용하여 구성합니다. 자동 값을 사용하면 콘텐츠에 따라 행 높이가 변경됩니다. 콘텐츠 양에 따라 높이가 늘어나거나, 축소됩니다.

```css
.asymmetrical-grid {
  display: grid;
  grid-template-columns: 3fr 6fr 1fr 5fr 10fr 2fr;
  grid-template-rows: 100px auto 15px auto auto;
}
```

### 이미지 요소 생성 <a href="#create-images" id="create-images"></a>

HTML의 `<img>` 요소를 사용해 콘텐츠 이미지, 또는 CSS `background-image` 속성을 사용해 배경 이미지를 사용할 수 있습니다. [`object-fit`](https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit) 속성을 사용하면 `<img>` 요소를 박스 비율에 맞춰 핏(fit) 하거나, 채우거나(fill), 덮어쓸(cover) 수 있지만 안타깝게도 [IE 브라우저는 해당 속성을 지원하지 않아 사용 할 수 없습니다.](https://caniuse.com/#search=object-fit)

![object-fit 속성 예시 | MDN](/files/-LHGNh3n-E7uVniuIAI5)

이러한 이유로 이미지 조정에 대한 유연성을 활용하기 위해 배경 이미지를 사용합니다. 배경 이미지로 사용할 `<figure>` 요소를 HTML 마크업에 추가합니다.

{% code title="" %}

```markup
<figure class="grid-item img-1"></figure>
<figure class="grid-item img-2"></figure>
<figure class="grid-item img-3"></figure>
```

{% endcode %}

{% hint style="warning" %}
\<div> 요소는 아무런 의미를 가지지 않는 요소로 적합하지 않습니다. 만약 \<div> 요소를 사용하고자 한다면 img  역할(role)을 부여해 사용하길 권합니다.

```markup
<div role="img" class="grid-item img-1"></div>
```

{% endhint %}

이어서 배경 이미지를 각 요소를 식별하는 선택자를 사용하여 설정합니다.

```css
.grid-item[class*="img-"] { background-size: cover; }

.grid-item.img-1 { background: "url(wooden.jpg)";  }
.grid-item.img-2 { background: "url(speaker.jpg)"; }
.grid-item.img-3 { background: "url(waves.jpg)";   }
```

### 이미지 배치 <a href="#placement-images" id="placement-images"></a>

그리드 라인의 시작/끝을 기준으로 각 이미지를 적정 위치에 배치 합니다.

![](/files/-LHGQU59e0-fN8arrme5)

1번째 이미지는 1열 - 3열에 위치합니다.

```css
.grid-item.img-1 {
  grid-column-start: 1;
  grid-column-end: 3;
}
```

`span` 문법을 사용하면 다음과 같이 작성할 수 있습니다.

```css
.grid-item.img-1 {
  grid-column-start: 1;
  grid-column-end: span 2;
}
```

속기형 문법을 사용하면 다음과 같이 작성합니다.

```css
.grid-item.img-1 {
  grid-column: 1 / 3; /* 또는  grid-column: 1 / span 2;  */
}
```

그리고 2행 - 5행에 위치합니다. 코드는 다음과 같이 작성합니다.

```css
.grid-item.img-1 {
  grid-row-start: 2;
  grid-row-end: 5;
}
```

또는

```css
.grid-item.img-1 {
  grid-row-start: 2;
  grid-row-end: span 3;
}
```

혹은&#x20;

```css
.grid-item.img-1 {
  grid-row: 2 / span 3; /* 또는  grid-row: 2 / 5;  */
}
```

### 콘텐츠 추가 및 배치 <a href="#adding-contents" id="adding-contents"></a>

`.asymmetrical-grid` 그리드 컨테이너 요소 내부에 다음과 같이 텍스트 콘텐츠를 추가하는 코드를 작성합니다.

```markup
<blockquote class="strapline">
  <p>“Almost immediately, word spread of a Welshman who had built this 
      incredible sounding sub bass system, and soon enough audiophiles 
      began searching out these legendary subs that were built like 
      no other.”</p>
</blockquote>
   
<div class="cta-wrapper">  
  <div class="cta">
    <h1>Gibraltar</h1>
    <p>Introducing 212/SE, our most powerful and agile subwoofer, 
       designed exclusively for larger systems and rooms to allow 
       superior state of the art speakers to spring to full voice.</p>
    <a class="button" href="">View Product Details →</a>
  </div>
</div>
```

다음 단계로 이미지를 배치 했던 것처럼 텍스트 콘텐츠를 그리드 라인을 기준으로 하여 적정 위치에 배치합니다.

```css
.strapline {
  grid-column: 3 / span 3;
  grid-row: 2 / span 1;
}
 
.cta-wrapper {
  grid-column: 4 / span 2;
  grid-row: 4 / span 2;
}
```

### `z-index` 설정

각 요소가 겹쳐 배치 되면, 나중에 마크업 된 요소가 위에 배치 됩니다. `.img-1`을 `.img-2` 보다 위에 배치 되게 하려면 `z-index` 속성을 사용해 정수 값을 설정합니다.

```css
z-index: 10;
```

![](/files/-LHGbCSvb5nU8eKxtuQ0)

### 그리드 가이드 <a href="#grid-guide" id="grid-guide"></a>

Firefox 브라우저 개발도구를 사용하면 보다 풍부한 기능을 사용해 CSS Grid 레이아웃을 분석할 수 있습니다.

![개발도구 Layout 탭 | Firefox](/files/-LHGbuPIsP8lcn7_2dH0)

Rules 탭의 grid 아이콘을 클릭하면 브라우저 화면에 시각적으로 Grid가 오버레이 되어 표시 됩니다.

![](/files/-LHGcN3qrV8TPMZ6g2yG)

### 콘텐츠 스타일링 <a href="#styling-contents" id="styling-contents"></a>

`<head>` 내부에 Google 웹폰트 [Open Sans](https://fonts.google.com/specimen/Open+Sans?selection.family=Open+Sans), [Playfair Display](https://fonts.google.com/specimen/Playfair+Display)를 호출하는 코드를 작성합니다.

```markup
<link 
  href="//fonts.googleapis.com/css?family=Open+Sans|Playfair+Display:400,400i,700" 
  rel="stylesheet">
```

디자인을 참고하여 콘텐츠 영역을 스타일링 하는 코드를 다음과 같이 추가합니다.

```css
body {
  font: 1em/1.7 "Open sans", sans-serif;
  color: #292929;
}
 
.strapline {
  margin: 0 0 2em 0;
  font: italic 1.1em/2 "Playfair Display", serif;
}
 
.cta h1 {
  position: relative;
  margin: 0 0 20px 0;
  font: bold 6em/1 "Playfair Display", serif;
}
```

버튼 요소 또한 스타일 코드를 추가합니다.

```css
.button {
  display: inline-block;
  padding: .8em 1.5em;
  text-decoration: none;
  background: #292929;
  color: white;
}
 
.button:hover {
  background: #000;
}
```

이어서 `.strapline` 텍스트를 가운데 정렬하고, `.cta-wrapper`에 패딩을 설정해 레이아웃을 조정합니다.

![](/files/-LHGevgGbkEadHN4QAmc)

### 장식 추가 및 배치 <a href="#add-flourishes" id="add-flourishes"></a>

`.strapline` 요소에 `::before` 가상 요소(pseudo element)를 사용해 장식 이미지를 추가 합니다.

```css
.strapline {
  position: relative;
  margin-top: 100px;
}
 
.strapline::before {
  content: "";
  position: absolute;
  top: -3em;
  left: 40%;
  width: 20%;
  height: 0.5em;
  background: url("wavy.svg") repeat-x;
  background-size: cover;
}
```

![.strapline 위에 배치된 물결 장식](/files/-LHGgwx53oOUdLQoBoJm)

.cta h1 요소 옆에 위치한 왕관 배지 또한 마찬가지 방법을 사용해 추가 배치 합니다.

```css
.cta h1::before {
  content: '';
  position: absolute;
  left: -120px;
  top: 0;
  height: 1em;
  width: 1em;
  background: url(badge.svg) no-repeat center center;
  background-size: 80%;
}
```

![.cta h1 요소 왼편에 배치된 왕관 장식](/files/-LHGhSLvGYPSboTOH5C0)

물결, 왕관 장식이 모두 추가하면 완성입니다.

![](/files/-LHGhp2iiih2kneLR4m4)

## 반응형 뷰 <a href="#responsive-view" id="responsive-view"></a>

작은 화면에서는 다른 레이아웃을 제공하고 싶다면 미디어 쿼리를 사용해 화면 뷰를 변경해줄 수 있습니다. 모바일에서는 2열의 정형 그리드를 사용하고, `768px` 이상 화면 뷰에서는 6열의 비 정형 그리드를 사용하도록 설정할 수 있습니다.

```css
.asymmetrical-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;   
}
 
@media (min-width: 48em /* 768px */) {
  .asymmetrical-grid {
    grid-template-columns: 3fr 6fr 1fr 5fr 10fr 2fr;
    grid-template-rows: 100px auto 15px auto auto;
  }
}
```

## 크로스 브라우징 (IE) <a href="#support-ie" id="support-ie"></a>

IE를 제외한 모던 브라우저는 [@support](https://caniuse.com/#search=support)를 사용할 수 있습니다. 즉, IE 와 다른 브라우저를 구분해 코드를 나눌 수 있습니다. 이 방법을 사용해 `float` 또는 `position` 등을 사용해 IE 에서도 레이아웃이 무너지지 않게 만들 수 있습니다.

![](/files/-LHGkNmIKP5WoZyStl9C)

방법은 다음과 같이 코드를 작성해 IE와 모던 브라우저에 적용되는 코드를 나눕니다.

```css
/* IE 지원 Fallback */
.grid-item.img-1 { float: left; }

/* IE를 제외한 모던 브라우저 적용 */
@support (display: grid) {
  .asymmetrical-grid { 
    display: grid;
    grid-template-columns: 3fr 6fr 1fr 5fr 10fr 2fr;
    grid-template-rows: 100px auto 15px auto auto;
  }
}
```

하지만 이 방법은 IE를 위한 별도의 레이아웃 코드가 필요해 제작자를 피곤하게 합니다. Grid 문법 코드만 사용해 IE 브라우저에서도 레이아웃이 무너지지 않게 하려면 MS 접두사(`-ms-`) 문법이 추가적으로 필요합니다. 다행히 [CSS Grid ProjectKit for IE](/css-grid/css-grid-for-ie.md#projectkit) 도구를 사용하면 IE를 위한 코드를 자동으로 생성해줍니다.

```css
.asymmetrical-grid {  
  display: -ms-grid;  
  display: grid;  
  -ms-grid-columns: 3fr 6fr 1fr 5fr 10fr 2fr;  
      grid-template-columns: 3fr 6fr 1fr 5fr 10fr 2fr;  
  -ms-grid-rows: 100px auto 15px auto auto;  
      grid-template-rows: 100px auto 15px auto auto;
}

.grid-item.img-1 {  
  -ms-grid-column: 1;  
  -ms-grid-column-span: 2;  
  grid-column: 1 / 3;
  -ms-grid-row: 2;
  -ms-grid-row-span: 3;
  grid-row: 2 / span 3;
}

.strapline {  
  -ms-grid-column: 3;  
  -ms-grid-column-span: 3;  
  grid-column: 3 / span 3;  
  -ms-grid-row: 2;  
  -ms-grid-row-span: 1;  
  grid-row: 2 / span 1;
} 

.cta-wrapper {  
  -ms-grid-column: 4;  
  -ms-grid-column-span: 2;  
  grid-column: 4 / span 2;  
  -ms-grid-row: 4;  
  -ms-grid-row-span: 2;  
  grid-row: 4 / span 2;
}
```
