HTML text fundamentals - Web 개발 학습하기

HTML text fundamentals
======================

* 이전
* Overview: Introduction to HTML
* 다음

 HTML의 주요 작업 중 하나는 브라우저가 텍스트를 올바르게 표시 할 수 있도록 텍스트 구조와 의미 (시멘틱(semantics)라고도 함)를 제공하는 것입니다.
 이번 글에서는 HTML을 사용하여 제목 및 단락을 추가하고, 단어를 강조하고, 목록을 만드는 등의 방법으로 텍스트 페이지를 구성하는 방법을 설명합니다.

|  |  |
| --- | --- |
| 선행 학습: | HTML 시작하기에서 다뤄봤던 HTML의 기초에 익숙해지기. |
| 목표: |
 문단, 제목, 목록, 강조 및 인용구를 포함한 구조와 의미를 부여하기 위해
 텍스트의 기본 페이지를 표시하는 방법에 대해 배웁니다.
  |

기본적인 것: 제목과 단락
--------------

대부분의 구조화 된 텍스트는 기사, 신문, 대학 교과서, 잡지 등 무엇을 읽든지 간에 제목과 단락으로 구성됩니다.

![An example of a newspaper front cover, showing use of a top level heading, subheadings and paragraphs.](/ko/docs/Learn/HTML/Introduction_to_HTML/HTML_text_fundamentals/newspaper_small.jpg)

구조화된 컨텐츠는 읽는 경험을 더 쉽고 즐겁게 만들어줍니다.

HTML에서는 각 단락은 `<p>` 요소 안에 둘러싸여 있어야 합니다. 다음에 나오는 것 처럼 :

```html
<p>I am a paragraph, oh yes I am.</p>
```

각 제목도 heading 요소 안에 둘려싸여 있어야 합니다 :

```html
<h1>I am the title of the story.</h1>
```

heading 요소는 총 6개가 있습니다— `<h1>`, `<h2>`, `<h3>`, `<h4>`, `<h5>`, and `<h6>`. 각 요소는 문서에서 다른 수준의 내용을 나타냅니다 ; 메인 제목을 `<h1>` 으로 나타내고, 소제목을 `<h2>` 으로 나타내고, 소제목의 소제목을 `<h3>`으로 나타내고 이런 식으로 제목들을 나타냅니다 .

### 구조화된 계층을 구현하기

예를 들어, 한 이야기에서
은 이야기의 제목을 나타내고
는 각 장의 제목을 나타내고
는 각 장의 하위 절을 나타내고 이런 식으로 나타냅니다.

```html
<h1>The Crushing Bore</h1>

<p>By Chris Mills</p>

<h2>Chapter 1: The dark night</h2>

<p>
  It was a dark night. Somewhere, an owl hooted. The rain lashed down on the ...
</p>

<h2>Chapter 2: The eternal silence</h2>

<p>
  Our protagonist could not so much as a whisper out of the shadowy figure ...
</p>

<h3>The specter speaks</h3>

<p>
  Several more hours had passed, when all of a sudden the specter sat bolt
  upright and exclaimed, "Please have mercy on my soul!"
</p>
```

구조화된 계층이 타당해 보이는 한 연관된 요소들이 정확히 무엇을 나타내는지는 당신에게 달려있습니다. 다만 그러한 구조들을 만들 때 다음 몇 가지의 관례만 기억하면 됩니다:

* 가급적이면 페이지 당 하나의 `<h1>` 만 사용해야 합니다. — `<h1>`은 최상위에 있는 표제이며 나머지 다른 표제들은 계층적으로 이것 밑에 위치합니다.
* 각 표제들을 계층적으로 올바른 순서로 사용해야 함을 명심하세요.
을 하위 표제로 사용하고 그 다음
를 하위 표제의 하위로 사용하지 마십시오. 이해하기 어려울 뿐더러 이상한 결과를 야기할 수 있습니다.
* 6개의 Heading을 사용할 수 있지만 꼭 필요한 것이 아니라면 한 페이지에 3개 이상을 사용하지 않도록 하십시오. 많은 목차 레벨을 가진 문서(예를 들어 너무 깊은 heading 계층)는 다루기 힘들고 탐색하기 어려습니다. 이러한 상황에서는 가능하다면 컨텐츠를 여러 페이지로 나누는 것이 바람직합니다.
### 왜 우리는 구조가 필요할까요?

이 질문에 대답하기 위해, text-start.html — 이 글에서 작동 원리를 보여주는 예시 첫 부분 (맛있는 hummus 레시피)- 을 봅시다. 이후 실습에서 필요하기 때문에 당신의 로컬 저장소에 이 파일의 복사본을 저장해야 합니다. 이 문서의 body는 다양한 컨텐츠 조각들을 가지고 있습니다. 이것들이 Marked up 된 것은 아니지만 줄바꿈으로 구분되어 있습니다. (다음 줄로 가기 위해 Enter/Return이 눌림)

하지만, 당신이 브라우저에서 문서를 열어보았을 때 당신은 텍스트가 한 덩어리로 뭉쳐있는 것을 볼 것입니다!

![A webpage that shows a wall of unformatted text, because there are no elements on the page to structure it.](/ko/docs/Learn/HTML/Introduction_to_HTML/HTML_text_fundamentals/screen_shot_2017-03-29_at_09.20.35.png)

이는 컨텐츠에 구조를 입히는 요소가 없기 때문인데, 그래서 브라우저는 무엇이 heading이고 무엇이 문단인지 알 수 없는 것입니다. 추가로:

* 웹 페이지를 보는 유저는 필요한 컨텐츠를 빠르게 훑어보는 경향이 있고 자주 heading만 읽기도 합니다. (we usually spend a very short time on a web page 우리는 보통 웹 페이지에서 매우 짧은 시간을 보냅니다.). 몇 초 안에 필요한 어떤 것도 찾지 못하면 그들은 실망하고 다른 곳으로 갈 수도 있습니다.
* 검색 엔진들은 당신의 페이지 내 heading을 페이지 검색 순위에 영향을 주는 중요한 키워드로 고려해 indexing 합니다. heading이 없다면, 당신의 페이지는 검색 엔진 최적화에 관해서는 형편없게 됩니다. SEO (Search Engine Optimization).
* 심각한 시각 장애인들은 자주 웹페이지를 읽지 못합니다. 대신 그들은 듣습니다. 이는 screen reader 라고 불리는 소프트웨어를 사용해 이루어집니다. 이 소프트웨어는 텍스트 컨텐츠에 더 빠르게 접근할 수 있는 방안을 제공합니다. 사용된 다양한 기술 중 하나로, 그들은 heading을 읽어줌으로서 문서의 개요를 제공하며 그들의 사용자들이 필요로 하는 정보를 빠르게 찾을 수 있도록 합니다. heading이 없었더라면 그들은 어쩔 수 없이 문서 전체를 읽어야 했을 것입니다.
* 컨텐츠를 CSS로 꾸미거나, JavaScript로 흥미로운 일을 하게 하기 위해서, 당신은 관련 컨텐츠를 감싸는 요소가 필요합니다. 그렇게 하면 CSS/JavaScript는 효과적으로 그에 적용될 수 있습니다.

그러므로 우리는 컨텐츠를 구조적인 markup에 적용시켜야 합니다.

### 활동적인 학습: 컨텐츠에 구조 입히기

실제 예시에 바로 적용해 봅시다. 아래 예시에서, Input 부분에 있는 raw text에 요소를 더해서 Output 부분에 heading과 두 문단으로 나오도록 해 봅시다.

실수를 하면 언제든 Reset 버튼을 눌러 리셋할 수 있습니다. 진행 중 막히면, Show solution 버튼을 눌러 답을 볼 수 있습니다.
```

<h2>Input</h2>
<textarea id="code" class="input">
My short story

I am a policewoman and my name is Trish.

My legs are made of cardboard and I am married to a fish.</textarea
>
<h2>Output</h2>
<div class="output"></div>
<div class="controls">
  <input id="reset" type="button" value="Reset" />
  <input id="solution" type="button" value="Show solution" />
</div>
```

```
body {
  font-family: "Open Sans Light", Helvetica, Arial, sans-serif;
}

.input,
.output {
  width: 90%;
  height: 8em;
  padding: 10px;
  border: 1px solid #0095dd;
  overflow: auto;
}

button {
  padding: 10px 10px 10px 0;
}
```

```
var textarea = document.getElementById("code");
var reset = document.getElementById("reset");
var code = textarea.value;
var output = document.querySelector(".output");
var solution = document.getElementById("solution");

function drawOutput() {
  output.innerHTML = textarea.value;
}

reset.addEventListener("click", function () {
  textarea.value = code;
  drawOutput();
});

solution.addEventListener("click", function () {
  textarea.value =
    "<h1>My short story</h1>\n<p>I am a policewoman and my name is Trish.</p>\n<p>My legs are made of cardboard and I am married to a fish.</p>";
  drawOutput();
});

textarea.addEventListener("input", drawOutput);
window.addEventListener("load", drawOutput);
```

### 우리는 왜 Semantic을 필요로 할까?

Semantic(직역 : 의미를 담은, 의미론적인)은 우리 주변 어디에서나 사용됩니다. 우리는 과거의 경험으로부터 일상적인 대상의 기능이 무엇인지 구분합니다. 우리가 어떤 것을 보면 그것의 기능은 무엇일지 알 수 있습니다. 그래서, 예를 들어, 우리가 빨간 신호등을 '멈춤'으로, 초록 신호등을 '출발'로 인식합니다. 잘못된 semantic들이 적용될 경우 상황은 복잡해집니다. (빨간색을 '출발'로 사용하는 나라가 있을까요? 없기를 바랍니다.)

비슷한 맥락에서, 우리는 정확한 요소를 사용하고 있는지, 우리의 컨텐츠에 정확한 의미, 기능, 모습을 담았는지 확실히 해야 합니다. 이 맥락에서 `<h1>` 요소 또한 텍스트에 "내 페이지 최상위 heading"의 역할로 감싸는 semantic 요소입니다.

```html
<h1>This is a top level heading</h1>
```

기본적으로, 브라우저는 이에 큰 사이즈의 폰트를 적용해 heading처럼 보이게 할 것입니다. (비록 당신이 CSS를 사용해 원하는 어떤 모습으로도 스타일 할 수 있지만 말입니다.) 더 중요하게, 이것의 의미론적인 가치는 다양한 방식으로 사용될 것입니다. 예를 들어 검색 엔진이나 screen reader들에서 말이죠. (위에서 서술한 것처럼.)

반면에, 당신은 어떤 요소도 최상위 heading처럼 *보이게* 할 수 있습니다. 다음을 고려해 봅시다:

```html
<span style="font-size: 32px; margin: 21px 0;"
 >Is this a top level heading?</span
>
```

이것은 `<span>` 요소입니다. 의미가 없죠. 당신은 컨텐츠에 추가적인 의미를 더하지 않고 CSS 를 적용하고 싶을 때 (혹은 JavaScript를 적용해 무언가를 하고 싶을 때) 이것을 사용합니다. (이것들에 대해서는 코스 뒤에서 더 알게 될겁니다.) 우리는 이것에 CSS를 더해 최상위 heading처럼 보이게 했지만, 이것이 semantic(의미론적인) 가치는 없기 때문에, 위에서 서술된 추가적인 이득들은 얻지 못할 것입니다. 작업에 관계있는 HTML 요소를 사용하는 것이 좋은 생각입니다.

Lists
-----

이제 List에 집중해 봅시다. List는 삶의 모든 부분에 있습니다 - 쇼핑 리스트에서 당신이 매일 집에 오기 위해 무의식적으로 따르는 지시들의 리스트까지, 이 튜토리얼에서 당신이 따르는 지시들의 리스트까지! 웹에서도 List는 어디에나 있습니다. 그리고 우리는 고려해야 할 3개의 종류를 가지고 있습니다.

### Unordered (순서 없음)

정렬되지 않은 목록은 항목의 순서가 중요하지 않은 항목 목록을 표시하는 데 사용됩니다

* 쇼핑 리스트 항목으로 예를 들어보자
```

milk
eggs
bread
hummus
```

순서 없는 리스트를 정렬하기 위해 `<ul>` element 를 이용해 감싸줍니다.

모든 리스트 아이템:

```html
<ul>
  milk
  eggs
  bread
  hummus
</ul>
```

마지막으로 그안의 리스트 항목들을 `<li>` (list item) 태그로 감싸줍니다.

```html
<ul>
  <li>milk</li>
  <li>eggs</li>
  <li>bread</li>
  <li>hummus</li>
</ul>
```

#### 활동적인 학습 : 순서 없는 리스트 만들기

HTML 순서 없는(unordered) 리스트를 만들기 위해 아래에 있는 샘플을 편집해보자.
```

<h2>Input</h2>
<textarea id="code" class="input">
milk
eggs
bread
hummus</textarea
>
<h2>Output</h2>
<div class="output"></div>
<div class="controls">
  <input id="reset" type="button" value="Reset" />
  <input id="solution" type="button" value="Show solution" />
</div>
```

```
body {
  font-family: "Open Sans Light", Helvetica, Arial, sans-serif;
}

.input,
.output {
  width: 90%;
  height: 6em;
  padding: 10px;
  border: 1px solid #0095dd;
  overflow: auto;
}

button {
  padding: 10px 10px 10px 0;
}
```

```
var textarea = document.getElementById("code");
var reset = document.getElementById("reset");
var code = textarea.value;
var output = document.querySelector(".output");
var solution = document.getElementById("solution");

function drawOutput() {
  output.innerHTML = textarea.value;
}

reset.addEventListener("click", function () {
  textarea.value = code;
  drawOutput();
});

solution.addEventListener("click", function () {
  textarea.value =
    "<ul>\n<li>milk</li>\n<li>eggs</li>\n<li>bread</li>\n<li>hummus</li>\n</ul>";
  drawOutput();
});

textarea.addEventListener("input", drawOutput);
window.addEventListener("load", drawOutput);
```

### Ordered (순서 있음)

순서 있는 리스트는 항목의 순서가 중요한 목록 입니다. 순서를 꼭 정해주세요

예제:
```

Drive to the end of the road
Turn right
Go straight across the first two roundabouts
Turn left at the third roundabout
The school is on your right, 300 meters up the road
```

`<ul>`태그가 아닌 `<ol>` 태그로 감싸는것을 제외하고는 마크업 구조는 순서가 없는 리스트와 동일하다.

```html
<ol>
  <li>Drive to the end of the road</li>
  <li>Turn right</li>
  <li>Go straight across the first two roundabouts</li>
  <li>Turn left at the third roundabout</li>
  <li>The school is on your right, 300 meters up the road</li>
</ol>
```

#### 활동적인 학습: 순서가 있는 리스트를 만들어보자

HTML 순서가 있는(ordered) 리스트를 만들기 위해 아래에 있는 샘플을 편집해보자.
```

<h2>Input</h2>
<textarea id="code" class="input">
Drive to the end of the road
Turn right
Go straight across the first two roundabouts
Turn left at the third roundabout
The school is on your right, 300 meters up the road</textarea
>
<h2>Output</h2>
<div class="output"></div>
<div class="controls">
  <input id="reset" type="button" value="Reset" />
  <input id="solution" type="button" value="Show solution" />
</div>
```

```
body {
  font-family: "Open Sans Light", Helvetica, Arial, sans-serif;
}

.input,
.output {
  width: 90%;
  height: 8em;
  padding: 10px;
  border: 1px solid #0095dd;
  overflow: auto;
}

button {
  padding: 10px 10px 10px 0;
}
```

```
var textarea = document.getElementById("code");
var reset = document.getElementById("reset");
var code = textarea.value;
var output = document.querySelector(".output");
var solution = document.getElementById("solution");

function drawOutput() {
  output.innerHTML = textarea.value;
}

reset.addEventListener("click", function () {
  textarea.value = code;
  drawOutput();
});

solution.addEventListener("click", function () {
  textarea.value =
    "<ol>\n<li>Drive to the end of the road</li>\n<li>Turn right</li>\n<li>Go straight across the first two roundabouts</li>\n<li>Turn left at the third roundabout</li>\n<li>The school is on your right, 300 meters up the road</li>\n</ol>";
  drawOutput();
});

textarea.addEventListener("input", drawOutput);
window.addEventListener("load", drawOutput);
```

### 활동적인 학습: 우리의 레시피 페이지를 만들어보자

이제 우리는 레시피 페이지 예시를 만드는 데 필요한 모든 정보를 가지고 있습니다. text-start.html 시작 파일을 저장해 그곳에서 작업을 하셔도 좋고, 아래에 있는 편집 가능한 샘플에서 작업을 할 수도 있습니다. 따로 파일을 생성해서 작업을 하면 언제든지 편집이 가능합니다. 아래 샘플에서 작업을 하면 다음에 이 페이지를 열 때 작업 기록이 사라져 있을 것입니다. 이 두가지 방법은 장점과 단점 모두를 지니고 있습니다.
```

<h2>Input</h2>
<textarea id="code" class="input">
Quick hummus recipe

    This recipe makes quick, tasty hummus, with no messing. It has been adapted from a number of different recipes that I have read over the years.

    Hummus is a delicious thick paste used heavily in Greek and Middle Eastern dishes. It is very tasty with salad, grilled meats and pitta breads.

    Ingredients

    1 can (400g) of chick peas (garbanzo beans)
    175g of tahini
    6 sundried tomatoes
    Half a red pepper
    A pinch of cayenne pepper
    1 clove of garlic
    A dash of olive oil

    Instructions

    Remove the skin from the garlic, and chop coarsely
    Remove all the seeds and stalk from the pepper, and chop coarsely
    Add all the ingredients into a food processor
    Process all the ingredients into a paste.
    If you want a coarse "chunky" hummus, process it for a short time
    If you want a smooth hummus, process it for a longer time

    For a different flavour, you could try blending in a small measure of lemon and coriander, chili pepper, lime and chipotle, harissa and mint, or spinach and feta cheese. Experiment and see what works for you.

    Storage

    Refrigerate the finished hummus in a sealed container. You should be able to use it for about a week after you've made it. If it starts to become fizzy, you should definitely discard it.

    Hummus is suitable for freezing; you should thaw it and use it within a couple of months.</textarea
>
<h2>Output</h2>
<div class="output"></div>
<div class="controls">
  <input id="reset" type="button" value="Reset" />
  <input id="solution" type="button" value="Show solution" />
</div>
```

```
body {
  font-family: "Open Sans Light", Helvetica, Arial, sans-serif;
}

.input,
.output {
  width: 90%;
  height: 8em;
  padding: 10px;
  border: 1px solid #0095dd;
  overflow: auto;
}

button {
  padding: 10px 10px 10px 0;
}
```

```
var textarea = document.getElementById("code");
var reset = document.getElementById("reset");
var code = textarea.value;
var output = document.querySelector(".output");
var solution = document.getElementById("solution");

function drawOutput() {
  output.innerHTML = textarea.value;
}

reset.addEventListener("click", function () {
  textarea.value = code;
  drawOutput();
});

solution.addEventListener("click", function () {
  textarea.value =
    '<h1>Quick hummous recipe</h1>\n\n<p>This recipe makes quick, tasty hummus, with no messing. It has been adapted from a number of different recipes that I have read over the years.</p>\n\n<p>Hummus is a delicious thick paste used heavily in Greek and Middle Eastern dishes. It is very tasty with salad, grilled meats and pitta breads.</p>\n\n<h2>Ingredients</h2>\n\n<ul>\n<li>1 can (400g) of chick peas (garbanzo beans)</li>\n<li>175g of tahini</li>\n<li>6 sundried tomatoes</li>\n<li>Half a red pepper</li>\n<li>A pinch of cayenne pepper</li>\n<li>1 clove of garlic</li>\n<li>A dash of olive oil</li>\n</ul>\n\n<h2>Instructions</h2>\n\n<ol>\n<li>Remove the skin from the garlic, and chop coarsely.</li>\n<li>Remove all the seeds and stalk from the pepper, and chop coarsely.</li>\n<li>Add all the ingredients into a food processor.</li>\n<li>Process all the ingredients into a paste.</li>\n<li>If you want a coarse "chunky" hummus, process it for a short time.</li>\n<li>If you want a smooth hummus, process it for a longer time.</li>\n</ol>\n\n<p>For a different flavour, you could try blending in a small measure of lemon and coriander, chili pepper, lime and chipotle, harissa and mint, or spinach and feta cheese. Experiment and see what works for you.</p>\n\n<h2>Storage</h2>\n\n<p>Refrigerate the finished hummus in a sealed container. You should be able to use it for about a week after you\'ve made it. If it starts to become fizzy, you should definitely discard it.</p>\n\n<p>Hummus is suitable for freezing; you should thaw it and use it within a couple of months.</p>';
  drawOutput();
});

textarea.addEventListener("input", drawOutput);

window.addEventListener("load", drawOutput);
```

위의 문제를 해결하는데 어려움을 겪고있다면, *Show solution* 버튼을 클릭하여 해답을 확인하거나, GitHub 레포지토리에 존재하는 text-complete.html 파일을 확인해 주시길 바랍니다.

### 리스트 내부의 리스트(Nesting lists)

하나의 리스트 내부에 다른 리스트를 추가하는 것은 아무런 문제가 없습니다. 당신이 최상위 리스트 아이템의 내부에 다른 리스트를 추가하고 싶다면, 하단의 예제들 중 두번째 예제를 확인해주세요.

```html
<ol>
  <li>Remove the skin from the garlic, and chop coarsely.</li>
  <li>Remove all the seeds and stalk from the pepper, and chop coarsely.</li>
  <li>Add all the ingredients into a food processor.</li>
  <li>Process all the ingredients into a paste.</li>
  <li>If you want a coarse "chunky" hummus, process it for a short time.</li>
  <li>If you want a smooth hummus, process it for a longer time.</li>
</ol>
```

마지막 두개의 리스트 아이템은 `Process all the ingredients into a paste.`와 밀접한 관계가 있는 내용입니다. 그러므로 두개의 리스트 아이템은 `Process all the ingredients into a paste.`의 내부에 중첩되어 나타나는 것이 더 좋을 것입니다. 하단과 같은 방법을 사용해서 말이죠.

```html
<ol>
  <li>Remove the skin from the garlic, and chop coarsely.</li>
  <li>Remove all the seeds and stalk from the pepper, and chop coarsely.</li>
  <li>Add all the ingredients into a food processor.</li>
  <li>
    Process all the ingredients into a paste.
    <ul>
      <li>
        If you want a coarse "chunky" hummus, process it for a short time.
      </li>
      <li>If you want a smooth hummus, process it for a longer time.</li>
    </ul>
  </li>
</ol>
```

첫번째의 예제로 돌아가, 두번째의 예제처럼 변경하는 연습을 해보시길 바랍니다.

중요와 강조
------

우리는 문장의 의미를 바꾸거나 특정한 단어를 강조하기위해 종종 일반적인 방법과 다르게 표현하기도 합니다. HTML은 그런 경우를 표시할 수 있도록 다양한 의미 요소를 제공하며, 이 섹션에서는 가장 일반적인 몇 가지 요소를 살펴보기로 합니다.

### 중요(Emphasis)

우리는 말을 하면서 특정 단어를 강세를 두고 발음하는 방법으로 의미를 다르게 표현합니다. 마찬가지로, 글에서는 단어에 강세를 두기 위해 이탤릭체로 표현하는 경향이 있습니다. 예를 들어, 다음 두 문장은 다른 의미를 가집니다.

I am glad you weren't late.

I am *glad* you weren't *late*.

첫 문장은 상대가 늦지 않은 것에 대해 진심으로 안도하는 것처럼 들립니다. 이와는 대조적으로, 두 번째 문장은 상대가 조금 늦게 도착한 것에대해 비꼬거나 짜증을 표현하는 것처럼 들립니다.

HTML에서는 이러한 경우를 표시하기 위해 `<em>` (emphasis) 요소를 사용합니다. 문서를 더 흥미롭게 읽게 될 뿐만 아니라, 화면판독기에 인식되면 다른 톤의 목소리로 표현됩니다. 브라우저에서는 기본적으로 이탤릭체로 스타일을 지정하지만, 단지 이탤릭체로 스타일링하기 위해 이 태그를 사용하는 것은 지양합니다. 스타일링을 위해서는`<span>` 요소에 약간의 CSS를 더하거나 `<i>`요소를 사용할 수 있습니다.(아래 참조).

```html
<p>I am <em>glad</em> you weren't <em>late</em>.</p>
```

### 강조(Strong importance)

우리는 중요한 단어를 강조하기 위해 강세를 두고 말하거나 글자를 두껍게 표현합니다. 예를들면,

This liquid is **highly toxic**.

I am counting on you. **Do not** be late!

HTML에서는 이러한 경우를 표시하기 위해 `<strong>` (en-US) (strong importance)요소를 사용합니다. 문서를 더 유용하게 만드는 것뿐만 아니라, 화면판독기에 인식되면 다른 톤의 목소리로 표현됩니다. 브라우저에서는 기본적으로 굵은 텍스트로 스타일을 지정하지만, 단지 굵게 스타일링하기 위해 이 태그를 사용하는 것은 지양합니다. 스타일링을 위해서는 `<span>` 요소에 약간의 CSS를 더하거나 `<b>` 요소를 사용할 수 있습니다.(아래 참조).

```html
<p>This liquid is <strong>highly toxic</strong>.</p>

<p>I am counting on you. <strong>Do not</strong> be late!</p>
```

원한다면 각각의 태그가 서로의 안에 위치할 수 있습니다.

```html
<p>
  This liquid is <strong>highly toxic</strong> — if you drink it,
  <strong>you may <em>die</em></strong
 >.
</p>
```

### Active learning: Let's be important!

이 Active Learning 섹션에서는 편집 가능한 예시를 제공하였습니다. 이 안에서 여러분이 필요하다고 생각되는 단어에 강조와 중요성을 더해보며 연습할 수 있기를 바랍니다.
```

<h2>Input</h2>
<textarea id="code" class="input">
<h1>Important notice</h1>

<p>On Sunday January 9th 2010, a gang of goths were
spotted stealing several garden gnomes from a shopping
center in downtown Milwaukee. They were all wearing green
jumpsuits and silly hats, and seemed to be having a whale
of a time. If anyone has any information about this
incident, please contact the police now.</p></textarea
>
<h2>Output</h2>
<div class="output"></div>
<div class="controls">
  <input id="reset" type="button" value="Reset" />
  <input id="solution" type="button" value="Show suggestion" />
</div>
```

```
body {
  font-family: "Open Sans Light", Helvetica, Arial, sans-serif;
}

.input,
.output {
  width: 90%;
  height: 8em;
  padding: 10px;
  border: 1px solid #0095dd;
  overflow: auto;
}

button {
  padding: 10px 10px 10px 0;
}
```

```
var textarea = document.getElementById("code");
var reset = document.getElementById("reset");
var code = textarea.value;
var output = document.querySelector(".output");
var solution = document.getElementById("solution");

function drawOutput() {
  output.innerHTML = textarea.value;
}

reset.addEventListener("click", function () {
  textarea.value = code;
  drawOutput();
});

solution.addEventListener("click", function () {
  textarea.value =
    "<h1>Important notice</h1>\n<p>On <strong>Sunday January 9th 2010</strong>, a gang of <em>goths</em> were spotted stealing <strong><em>several</em> garden gnomes</strong> from a shopping center in downtown <strong>Milwaukee</strong>. They were all wearing <em>green jumpsuits</em> and <em>silly hats</em>, and seemed to be having a whale of a time. If anyone has <strong>any</strong> information about this incident, please contact the police <strong>now</strong>.</p>";
  drawOutput();
});

textarea.addEventListener("input", drawOutput);
window.addEventListener("load", drawOutput);
```

### Italic, bold, underline

우리가 지금까지 얘기했던 요소들은 관련된 의미들을 명확히 구분했습니다. `<b>`, `<i>`, `<u>`의 상황들은 좀 복잡하죠. 이 요소들은 CSS가 형편없이 지원되거나 완전히 지원되지 않는 경우에 이탤릭체 또는 밑줄 등을 표현할 수 있도록 고안되었습니다. 의미론적이 아닌 표현에만 영향을 주는 이와 같은 요소들은 **현재적 요소**로 알려져 있으며, 더 이상 사용되어서는 안됩니다. 앞에서 살펴본 바와 같이 의미론은 접근성, SEO 등에 매우 중요하기 때문이죠.

HTML5 에서는 `<b>`, `<i>,` `<u>` 를 조금 혼란스럽긴 하지만 새로운 의미론적 역할로 재정립하였습니다.

가장 좋은 경험법칙: 적합한 요소가 더 없다면, 과거로부터 줄곧 굵거나 이탤릭체를 쓰거나 밑줄을 치는 방법으로 표현했던 의미를 전달하기 위해 `<b>`, `<i>`, `<u>` 를 사용하는 것이 적절할 것 같다. 그러나 늘 접근성에 관해 염두하는 것은 항상 중요하다. 이탤릭체의 개념은 스크린리더를 사용하는 사람이나 라틴 문자체계 이외의 사용자에게는 별로 도움이 되지 않는다.

* `<i>` 요소는 과거로부터 줄곧 기울임꼴로 전달되는 의미를 전달하기 위해 사용된다. 외래어, 분류학 명칭, 전문 용어, 생각...
* `<b>` 요소는 과거로부터 줄곧 굵은 글씨로 전달되는 의미를 전달할 때 사용한다. 주요 단어, 제품 이름, 주요 문장...
* `<u>` 요소는 과거로부터 줄곧 밑줄을 치는 것으로 전달되는 의미를 전달할 떄 사용한다. 적절한 이름, 잘못된 철자...

**참고:** 밑줄에 대한 위험성 중 하나: **사람들은 밑줄을 하이퍼링크와 강하게 연관시킨다.** 따라서 웹에서는 링크에만 밑줄을 긋는 것이 가장 좋다. 의미론적으로 적합한 경우 `<u>` 요소를 사용하되, CSS를 사용하여 기본 밑줄을 웹에서 더 적합하게 변경할 수 있는지 고려한다. 그것이 어떻게 이루어질 수 있는지는 아래의 예에서 확인할 수 있다.

```html
<!-- scientific names -->
<p>
  The Ruby-throated Hummingbird (<i>Archilochus colubris</i>) is the most common
  hummingbird in Eastern North America.
</p>

<!-- foreign words -->
<p>
  The menu was a sea of exotic words like <i lang="uk-latn">vatrushka</i>,
  <i lang="id">nasi goreng</i> and <i lang="fr">soupe à l'oignon</i>.
</p>

<!-- a known misspelling -->
<p>Someday I'll learn how to <u>spel</u> better.</p>

<!-- Highlight keywords in a set of instructions -->
<ol>
  <li><b>Slice</b> two pieces of bread off the loaf.</li>
  <li>
    <b>Insert</b> a tomato slice and a leaf of lettuce between the slices of
    bread.
  </li>
</ol>
```

요약
--

일단 이게 다에요! 이 글을 통해 여러분은 HTML에서 텍스트를 표현하기 시작하는 방법에 대해 좋은 아이디어를 얻었고, 이 영역에서 가장 중요한 몇가지 요소들을 알게되었습니다. 이 코스에에서 다룰 의미론적 요소는 훨씬 더 많으며 하이퍼링크를 만드는 방법에 대해 자세히 알아보도록 합시다.

* 이전
* Overview: Introduction to HTML
* 다음


HTML 시작하기 - Web 개발 학습하기

HTML 시작하기
=========

* Overview: Introduction to HTML
* 다음

이 문서는 HTML 의 기본적인 내용에 대한 글입니다. 이 글에서는 HTML 에 관련된 용어들(Element, Attribute ..)의 정의에 대해 설명할 것입니다. 또한 HTML이 무엇으로 이루어져 있는지(구성요소), 어떻게 구성되어 있는지(구조), 중요한 특징은 무엇인지에 대해 설명할 것입니다. 독자의 흥미를 위해 간단한 HTML 을 작성하는 과정도 포함되어 있습니다.

|  |  |
| --- | --- |
| 사전 지식 |
 기본적인 컴퓨터의 이해,
 기본 소프트웨어 설치하기,
 파일 다루기의 기본적 지식.
  |
| 목표 | HTML언어에 대해 익숙해지고, HTML을 이용하여 실습해봅니다. |

HTML이란?
-------

HTML (Hypertext Markup Language,하이퍼텍스트 마크업 언어)는 프로그래밍 언어는 아니고, 우리가 보는 웹페이지가 어떻게 구조화되어 있는지 브라우저로 하여금 알 수 있도록 하는 마크업 언어입니다. 이는 개발자로 하여금 복잡하게도 간단하게도 프로그래밍 할 수 있습니다. HTML은 elements로 구성되어 있으며, 이들은 적절한 방법으로 나타내고 실행하기 위해 각 컨텐츠의 여러 부분들을 감싸고 마크업 합니다. tags 는 웹 상의 다른 페이지로 이동하게 하는 하이퍼링크 내용들을 생성하거나, 단어를 강조하는 등의 역할을 합니다. 예를들어, 다음의 내용을 봅시다.
```

My cat is very grumpy
```

만약 다음의 문장을 그냥 그 자체로 표시하고 싶다면, 태그 중 (`<p>`)로 감싸 엘리먼트를 문단으로 명시할 수 있습니다.

```html
<p>My cat is very grumpy</p>
```

**참고:** HTML 요소는 대소문자를 구분하지 않습니다. 그 말은 `<title>` 요소는 `<title>`, `<TITLE>`, `<Title>`, `<TiTlE>` 들과 같이 사용할 수 있습니다. 하지만 대게는 가독성과 기타 이유때문에 소문자로 작성합니다.

HTML 요소(Element)의 구조
--------------------

HTML에서의 요소에 대해 좀 더 알아봅시다.

![](/ko/docs/Learn/HTML/Introduction_to_HTML/Getting_started/grumpy-cat-small.png)

엘리먼트의 주요 부분은 다음과 같습니다.

1. **여는 태그(Opening tag):** 이것은 요소의 이름과(이 경우 p), 열고 닫는 꺽쇠 괄호로 구성됩니다. 요소가 시작(이 경우 단락의 시작 부분)부터 효과가 적용되기 시작합니다.
2. **닫는 태그(Closing tag):** 이것은 요소의 이름 앞에 슬래시(/)가 있는것을 제외하면 여는 태그(opening tag)와 같습니다. 이것은 요소의 끝(이 경우 단락의 끝 부분)에 위치합니다. 닫는 태그를 적어주지 않는 것은 흔한 초심자의 오류이며, 이것은 이상한 결과를 낳게됩니다.
3. **내용(Content):** 요소의 내용이며, 이 경우 단순한 텍스트이다.
4. **요소(Element):** 여는 태그, 닫는 태그, 내용을 통틀어 요소(element)라고한다.
### 실습: 첫 번째 HTML 요소 만들어보기

Input 영역 아래의 줄을 `<em>` 과 `</em>` 태그를 이용해서 감싸 보세요. (줄의 앞에 요소를 열기위해 `<em>`태그를, 뒤에는 요소를 닫기위해 `</em>`태그를 두세요.) — 이것은 그 줄에 이탤릭강조효과를 줍니다! 여러분이 수정하는 결과는 실시간으로 Output 영역에서 볼 수 있습니다.

만약 실수를 했다면, 언제든지 Reset 버튼을 눌러서 초기화 할 수 있습니다. 만약 아무래도 답을 모르겠다면, Show solution 버튼을 이용해서 답을 볼 수 있습니다.
```

<h2>Live output</h2>
<div class="output" style="min-height: 50px;"></div>

<h2>Editable code</h2>
<p class="a11y-label">
  코드 영역에서 포커스를 이동하려면 Esc키를 누르십시오 (Tab키로 탭 문자를 삽입).
</p>

<textarea id="code" class="input" style="min-height: 100px; width: 95%">
  This is my text.
</textarea>

<div class="controls">
  <input id="reset" type="button" value="Reset" />
  <input id="solution" type="button" value="Show solution" />
</div>
```

```
html {
  font-family: "Open Sans Light", Helvetica, Arial, sans-serif;
}

h2 {
  font-size: 16px;
}

.a11y-label {
  margin: 0;
  text-align: right;
  font-size: 0.7rem;
  width: 98%;
}

body {
  margin: 10px;
  background: #f5f9fa;
}
```

```
var textarea = document.getElementById("code");
var reset = document.getElementById("reset");
var solution = document.getElementById("solution");
var output = document.querySelector(".output");
var code = textarea.value;
var userEntry = textarea.value;

function updateCode() {
  output.innerHTML = textarea.value;
}

reset.addEventListener("click", function () {
  textarea.value = code;
  userEntry = textarea.value;
  solutionEntry = htmlSolution;
  solution.value = "Show solution";
  updateCode();
});

solution.addEventListener("click", function () {
  if (solution.value === "Show solution") {
    textarea.value = solutionEntry;
    solution.value = "Hide solution";
  } else {
    textarea.value = userEntry;
    solution.value = "Show solution";
  }
  updateCode();
});

var htmlSolution = "<em>This is my text.</em>";
var solutionEntry = htmlSolution;

textarea.addEventListener("input", updateCode);
window.addEventListener("load", updateCode);

// stop tab key tabbing out of textarea and
// make it write a tab at the caret position instead

textarea.onkeydown = function (e) {
  if (e.keyCode === 9) {
    e.preventDefault();
    insertAtCaret("\t");
  }

  if (e.keyCode === 27) {
    textarea.blur();
  }
};

function insertAtCaret(text) {
  var scrollPos = textarea.scrollTop;
  var caretPos = textarea.selectionStart;

  var front = textarea.value.substring(0, caretPos);
  var back = textarea.value.substring(
    textarea.selectionEnd,
    textarea.value.length,
  );
  textarea.value = front + text + back;
  caretPos = caretPos + text.length;
  textarea.selectionStart = caretPos;
  textarea.selectionEnd = caretPos;
  textarea.focus();
  textarea.scrollTop = scrollPos;
}

// Update the saved userCode every time the user updates the text area code

textarea.onkeyup = function () {
  // We only want to save the state when the user code is being shown,
  // not the solution, so that solution is not saved over the user code
  if (solution.value === "Show solution") {
    userEntry = textarea.value;
  } else {
    solutionEntry = textarea.value;
  }

  updateCode();
};
```

### 포함(내포:內包)된 요소(Nesting elements)

요소 안에 다른 요소가 들어갈 수 있습니다. 그런 요소는 내포되었다고 표현합니다. "고양이가 매우 사납다" 라는 문단을 강조하기 위해서, '매우'라는 단어를 강조하는 `<strong>` (en-US) 요소를 중첩해서 사용할 수 있습니다.

```html
<p>My cat is <strong>very</strong> grumpy.</p>
```

요소 내표를 위해서는 확인해야 할 것이 있습니다. 위의 예제에서는 `p` 요소가 먼저 열렸고, 그리고 `strong` 요소가 열렸습니다. 그렇기 때문에 `strong` 요소가 먼저 닫힌 후에 `p` 요소가 닫혀야 합니다. 아래와 같은 문장은 중첩(重疊 : 서로 포개어(overlap 또는 stacking) 지거나, 엇갈려 겹쳐짐)되었으므로 잘못된 문장입니다.

```html
<p>My cat is <strong>very grumpy.</p></strong>
```

요소 내포을 위해서, 내포되어 지는 요소는 다른 요소 속에서 열고 닫혀야 하며 다른 요소를 포함시키는 요소는 그 바깥에서 열고 닫혀야 합니다. 위의 잘못된 예제와 같이 내포가 제대로 되지 않았을 경우엔 웹 브라우저가 임의로 결과를 보일 것이며, 그것은 원치않는 것일 수 있습니다. 그런데 잘못 된 내포에도 불구하고 어떤 브라우저에서 이상없이 보일 수도 있습니다. 하지만 그 것은 그저 그 브라우저가 문법에 흐물흐물(permittable)해서 웬만한 오류는 자체 수정해서 브라우저 창에 rendering해주기 때문일 뿐 입니다. '웬만한 오류는 알아서 처리해 준다.' 는 부분에서 초보자는 특히 주의해야 합니다.

### 블럭 레벨 요소 vs 인라인 요소(Block versus inline elements)

HTML에는 두가지 종류의 요소(Element) 가 있습니다. 블록 레벨 요소(Block level element) 와 인라인 요소(Inline element) 입니다.

* 블록 레벨 요소(Block-level elements) 는 웹페이지 상에 블록(Block)을 만드는 요소입니다. 블록 레벨 요소는 앞뒤 요소 사이에 새로운 줄(Line)을 만들고 나타납니다. 즉 블록 레벨 요소 이전과 이후 요소사이의 줄을 바꿉니다. 블록 레벨 요소는 일반적으로 페이지의 구조적 요소를 나타낼 때 사용됩니다. 예를 들어 개발자는 블록 레벨 요소를 사용하여 단락(Paragraphs), 목록(lists), 네비게이션 메뉴(Navigation Menus), 꼬리말(Footers) 등을 표현할 수 있습니다. 블록 레벨 요소는 인라인 요소(Inline elements)에 중첩될(Nested inside)수 없습니다. 그러나 블록 레벨 요소는 다른 블록 레벨 요소에 중첩될 수 있습니다.
* 인라인 요소(Inline elements)는 항상 블록 레벨 요소내에 포함되어 있습니다. 인라인 요소는 문서의 한 단락같은 큰 범위에는 적용될 수 없고 문장, 단어 같은 작은 부분에 대해서만 적용될 수 있습니다. 인라인 요소는 새로운 줄(Line)을 만들지 않습니다. 즉 인라인 요소를 작성하면 그것을 작성한 단락내에 나타나게 됩니다. 예를 들어, 인라인 요소에는 하이퍼링크를 정의하는 요소인 `<a>` , 텍스트(Text)를 강조하는 요소인 `<em>`,`<strong>` (en-US) 등이 있습니다.

다음 예시를 봅시다:

```html
<em>first</em>
<em>second</em>
<em>third</em>

<p>fourth</p>
<p>fifth</p>
<p>sixth</p>
```

`<em>` 은 인라인 요소(inline element) 이므로, 밑에서 보실 수 있듯이, 처음 세 개의 요소는 서로 같은 줄에, 사이에 공백이 없이 위치합니다. 한편, `<p>` 는 블록 레벨 요소이므로, 각 요소들은 새로운 줄에 나타나며, 위와 아래에 여백이 있습니다 (여백은 브라우저가 문단에 적용하는 기본 CSS styling 때문에 적용됩니다).

**참고:** HTML5에서 요소 분류를 재정의 했습니다: Element content categories. 이러한 정의는 이전의 정의보다 더 정확하고 덜 모호하지만, "블록"과 "인라인"보다 이해하기 훨씬 더 복잡하기 때문에, 이 주제 내내 이 정의들을 고수할 것입니다.

**참고:** 이 주제에서 사용되는 "블럭(block)"과 "인라인(inline)"의 뜻은 the types of CSS boxes (en-US)에서 사용하고 있는 같은 단어와 혼돈하면 안 됩니다. 기본적으로는 상관관계가 있지만 CSS 표시 유형을 변경해도 요소의 범주는 변경되지 않으며 요소가 포함할 수 있는 요소와 요소가 포함될 수 있는 요소에는 영향을 주지 않는다. HTML5가 이러한 용어들을 삭제했던 이유 중 하나는 이러한 다소 흔한 혼란을 막기 위해서였다.

**참고:** Block-level elements문서와 Inline elements문서를 참고하면 블럭과 인라인 요소에 대한 유용한 내용을 찾을 수 있습니다.

### 빈 요소(Empty elements)

모든 요소가 위에 언급된 여는 태그, 내용, 닫는 태그 패턴을 따르는 것은 아닙니다. 주로 문서에 무언가를 첨부하기 위해 단일 태그(Single tag)를 사용하는 요소도 있습니다. 예를 들어 `<img>` 요소는 해당 위치에 이미지를 삽입하기 위한 요소입니다:

```html
<img
 src="https://raw.githubusercontent.com/mdn/beginner-html-site/gh-pages/images/firefox-icon.png" />
```

위에 대한 결과는 다음과 같이 나올 것입니다:

**참고:** 빈 요소는 가끔 Void 요소로 불리기도 합니다.

속성(Attributes)
--------------

요소는 아래 이미지와 같이 속성을 가질 수 있습니다:

![My cat is very grumpy](/ko/docs/Learn/HTML/Introduction_to_HTML/Getting_started/grumpy-cat-attribute-small.png)

속성은 요소에 실제론 나타내고 싶지 않지만 추가적인 내용을 담고 싶을 때 사용합니다. 위에는 나중에 스타일에 관련된 내용이나 기타 내용을 위해 해당 목표를 구분할 수 있는 `class` 속성을 부여했습니다.

속성을 사용할 때에는 아래 내용을 지켜야 합니다:

1. 요소 이름 다음에 바로 오는 속성은 요소 이름과 속성 사이에 공백이 있어야 되고, 하나 이상의 속성들이 있는 경우엔 속성 사이에 공백이 있어야 합니다.
2. 속성 이름 다음엔 등호(=)가 붙습니다.
3. 속성 값은 열고 닫는 따옴표로 감싸야 합니다.
### 실습: 요소에 속성 추가하기

또다른 요소 중 하나인 `<a>` 요소는 "anchor"를 의미하는데, 닻이 배를 항구로 연결하듯 텍스트를 감싸서 하이퍼링크로 만듭니다. 이 요소는 여러 속성을 가질 수 있지만 아래에 있는 두 개가 주로 사용됩니다:

`href`

이 속성에는 당신이 연결하고자 하는 웹 주소를 지정합니다. 그 예로, `href="https://www.mozilla.org/"`.

`title`

`title` 속성은 링크에 대한 추가 정보를 나타냅니다. 그 예로, `title="The Mozilla homepage"`. 이 내용은 링크 위로 마우스를 옮겼을 때 나타날 것입니다.

`target`

`target` 속성은 링크가 어떻게 열릴 것인지를 지정합니다. 예를 들어, `target="_blank"` 는 링크를 새 탭에서 보여줍니다. 당신이 현재 탭에서 링크를 보여주고싶다면 이 속성을 생략하면 됩니다.

당신이 즐겨 찾는 웹 사이트에 대한 링크를 만들기 위해 아래 입력 영역에서 행을 편집해 봅시다. 첫 번째로, `<a>` 요소를 추가합니다. 다음으로 `href` 속성과 `title` 속성을 추가합니다. 마지막으로 새 탭에서 링크를 열도록 `target` 속성을 지정합니다. 당신은 출력 영역에서 수정사항이 바로 변경되는 것을 볼 수 있습니다. 링크 위에 마우스를 올리면 `title` 속성 내용이 보여지고, 클릭하면 `href` 요소의 웹 주소로 이동할 것입니다. 각 요소의 이름과 그 값 사이에는 빈 칸이 필요하다는 것을 기억해야 합니다.

만약 실수했다면 Reset 버튼을 눌러 처음으로 돌아갈 수 있습니다. 도움이 필요한 경우에는 답을 Show solution 버튼을 눌러 정답을 볼 수 있습니다.
```

<h2>Live output</h2>

<div class="output" style="min-height: 50px;"></div>

<h2>Editable code</h2>
<p class="a11y-label">
  Press Esc to move focus away from the code area (Tab inserts a tab character).
</p>

<textarea id="code" class="input" style="min-height: 100px;width: 95%">
  <p>A link to my favorite website.</p>
</textarea>

<div class="playable-buttons">
  <input id="reset" type="button" value="Reset" />
  <input id="solution" type="button" value="Show solution" />
</div>
```

```
html {
  font-family: sans-serif;
}

h2 {
  font-size: 16px;
}

.a11y-label {
  margin: 0;
  text-align: right;
  font-size: 0.7rem;
  width: 98%;
}

body {
  margin: 10px;
  background: #f5f9fa;
}
```

```
var textarea = document.getElementById("code");
var reset = document.getElementById("reset");
var solution = document.getElementById("solution");
var output = document.querySelector(".output");
var code = textarea.value;
var userEntry = textarea.value;

function updateCode() {
  output.innerHTML = textarea.value;
}

reset.addEventListener("click", function () {
  textarea.value = code;
  userEntry = textarea.value;
  solutionEntry = htmlSolution;
  solution.value = "Show solution";
  updateCode();
});

solution.addEventListener("click", function () {
  if (solution.value === "Show solution") {
    textarea.value = solutionEntry;
    solution.value = "Hide solution";
  } else {
    textarea.value = userEntry;
    solution.value = "Show solution";
  }
  updateCode();
});

var htmlSolution =
  '<p>A link to my <a href="https://www.mozilla.org/" title="The Mozilla homepage" target="\_blank">favorite website</a>.</p>';
var solutionEntry = htmlSolution;

textarea.addEventListener("input", updateCode);
window.addEventListener("load", updateCode);

// stop tab key tabbing out of textarea and
// make it write a tab at the caret position instead

textarea.onkeydown = function (e) {
  if (e.keyCode === 9) {
    e.preventDefault();
    insertAtCaret("\t");
  }

  if (e.keyCode === 27) {
    textarea.blur();
  }
};

function insertAtCaret(text) {
  var scrollPos = textarea.scrollTop;
  var caretPos = textarea.selectionStart;

  var front = textarea.value.substring(0, caretPos);
  var back = textarea.value.substring(
    textarea.selectionEnd,
    textarea.value.length,
  );
  textarea.value = front + text + back;
  caretPos = caretPos + text.length;
  textarea.selectionStart = caretPos;
  textarea.selectionEnd = caretPos;
  textarea.focus();
  textarea.scrollTop = scrollPos;
}

// Update the saved userCode every time the user updates the text area code

textarea.onkeyup = function () {
  // We only want to save the state when the user code is being shown,
  // not the solution, so that solution is not saved over the user code
  if (solution.value === "Show solution") {
    userEntry = textarea.value;
  } else {
    solutionEntry = textarea.value;
  }

  updateCode();
};
```

### 참과 거짓 속성(Boolean attributes)

때때로 값이 없는 속성을 볼 수 있을텐데 이것은 허용되는 것입니다. 이를 불 속성이라고 하며, 일반적으로 그 속성의 이름과 동일한 하나의 값만을 가질 수 있습니다. 예를 들어 `disabled` (en-US) 속성을 양식 입력 요소에 할당하면 사용자가 데이터를 입력할 수 없도록 비활성화(회색으로 표시) 할 수 있습니다.
```

<input type="text" disabled="disabled">
```

이것은 다음과 같이 줄여쓸 수 있습니다. (당신이 참고할 수 있도록 비활성화를 하지 않은 형태도 포함했습니다.)

```html
<input type="text" disabled />

<input type="text" />
```

이 둘은 다음과 같은 결과를 보여줍니다.

### 속성값의 따옴표 생략

웹을 둘러보면 따옴표가 없는 속성값을 포함한 온갖 이상한 마크업 스타일을 볼 것입니다. 어떤 상황에선 이런 것이 허용되지만, 다른 상황에서는 당신의 마크업 형식을 망쳐버립니다. 이전에 작성한 코드에서 우리는 `href` 속성만 있는 기본적인 버전을 작성했습니다.

```html
<a href=https://www.mozilla.org/>favorite website</a>
```

하지만 여기에 `title` 속성을 추가하면 문제가 발생합니다.

```html
<a href=https://www.mozilla.org/ title=The Mozilla homepage>favorite website</a>
```

이 때 브라우저는 당신의 마크업을 잘못 해석해서 title이 세 개의 속성값을 가진다고 생각할 것입니다. `title` 속성값 "The"와 두 개의 불 속성값 `Mozilla`, `homepage`라고 말이죠. 이 것은 우리가 의도한 것도 아닐 뿐더러 아래의 예시처럼 오류가 발생하거나 예상치 못한 동작을 할 수도 있습니다. 링크 위에 마우스를 올려 title이 어떻게 보이는지 확인해 보세요.

우리는 항상 속성값에 따옴표를 붙이라고 조언합니다. 이런 오류를 피할 수도 있고, 코드의 가독성도 좋아지기 때문입니다.

### 작은 따옴표, 큰 따옴표?

이 글에서 모든 속성값은 큰 따옴표에 둘러싸여 있는 것을 볼 수 있습니다. 하지만 당신은 어떤 사람의 HTML에서 작은 따옴표를 볼 수 있을 것입니다. 이 것은 스타일의 문제로, 당신이 좋아하는 방법을 사용하면 됩니다. 아래 두 문장은 똑같이 동작합니다.

```html
<a href="http://www.example.com">A link to my example.</a>

<a href="http://www.example.com">A link to my example.</a>
```

주의해야할 점은 두 개를 섞어 쓰면 안된다는 것입니다. 다음은 잘못 사용한 예입니다.

```html
<a href="http://www.example.com'>A link to my example.</a>
```

만약 한 가지 따옴표를 사용했다면 다른 따옴표로 속성값을 둘러싸서 오류를 방지할 수 있습니다.

```html
<a href="http://www.example.com" title="Isn't this fun?"
 >A link to my example.</a
>
```

하지만 만약 당신이 따옴표 안에 같은 따옴표를 사용하고 싶다면(작은 따옴표든 큰 따옴표든) 따옴표를 표시하기 위해서 HTML entities를 사용하세요. 예를 들어 이렇게 하면 잘못됩니다.
```

<a href='http://www.example.com' title='Isn't this fun?'>A link to my example.</a>
```

그래서 이렇게 바꿔주면 잘 작동합니다.
```

<a href='http://www.example.com' title='Isn't this fun?'>A link to my example.</a>
```

HTML 문서의 구조
-----------

That wraps up the basics of individual HTML elements, but they aren't very useful on their own. 이제 어떻게 개별 요소를 결합해 전체 HTML 페이지를 구성하는지에 대해 살펴봅시다.

```html
<!doctype html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>My test page</title>
  </head>
  <body>
    <p>This is my page</p>
  </body>
</html>
```

여기를 보면,

1. `<!DOCTYPE html>`: 문서 형식을 나타냅니다. HTML 초창기에 (1991~2년) doctype은 HTML 페이지가 자동 오류 검사나 다른 유용한 것이 가능한 좋은 HTML을 의미하는 연결고리처럼 작동하는 것을 뜻했습니다. 이런 형식으로 사용했습니다.

```html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
```

하지만 요즘에는 아무도 신경쓰지 않으며, 그저 모든 것이 제대로 작동하기 위해 포함되어야 하는 역사적 유물일 뿐입니다. `<!DOCTYPE html>` 은 유효한 문서 형식을 나타내는 짧은 문장이고, 이 것만 알고 있으면 됩니다.
2. `<html></html>`: `<html>` 요소입니다. 이 요소는 전체 페이지의 콘텐츠를 포함하며, 기본 요소로도 알려져 있습니다.
3. `<head></head>`: `<head>` 요소입니다. 이 요소는 홈페이지 이용자에게는 보이지 않지만 검색 결과에 노출 될 키워드, 홈페이지 설명, CSS 스타일, character setdeclaration 등 HTML 페이지의 모든 내용을 담고 있습니다. 자세한 내용은 다음 장에서 다룹니다.
4. `<meta charset="utf-8">`: 이 요소는 HTML 문서의 문자 인코딩 설정을 UTF-8로 지정하는 것이며 예시에서 지정한 UTF-8에는 전세계에서 사용되는 언어에 대한 대부분의 문자가 포함됩니다. 이 설정을 사용하면 페이지에 포함 된 모든 텍스트 내용을 처리 할 수 있습니다. 이것을 설정하면 나중에 문자 인코딩과 관련된 일부 문제를 피하는 데 도움이 될 수 있으므로 문자 인코딩 설정을 하지 않을 이유가 없습니다.
5. `<title></title>`: `<title>` 요소입니다. 이 요소를 사용하면 페이지 제목이 설정되며 페이지가 로드되는 브라우저 탭에 표시되는 제목으로 사용됩니다. 페이지 제목은 페이지가 책갈피 될 때 페이지를 설명하는 데에도 사용됩니다.
6. `<body></body>`: `<body>` 요소 여기에는 텍스트, 이미지, 비디오, 게임, 재생 가능한 오디오 트랙 등을 비롯하여 페이지에 표시되는 모든 콘텐츠가 포함됩니다.
### 실습: HTML 문서에 일부 기능 추가하기

로컬 컴퓨터에서 일부 HTML을 작성하여 실험하고 싶다면 다음을 수행하십시오.

1. 위에 나열된 HTML 페이지 예제를 복사하십시오.
2. 텍스트 편집기에서 새 파일을 작성하십시오.
3. 코드를 새 텍스트 파일에 붙여 넣습니다.
4. 파일을 `index.html`로 저장하십시오.

**참고:** 기본 HTML 템플릿은 MDN Learning Area Github repo 에서도 찾을 수 있습니다.

이제 웹 브라우저에서 이 파일을 열어 렌더링 된 코드의 모양을 확인할 수 있습니다. 코드를 편집하고 브라우저를 새로 고침하여 결과를 확인하십시오. 첫 페이지는 다음과 같습니다.

![A simple HTML page that says This is my page](/ko/docs/Learn/HTML/Introduction_to_HTML/Getting_started/template-screenshot.png)이 연습에서는 앞에서 설명한대로 컴퓨터에서 로컬로 코드를 편집하거나 아래 샘플 창에서 편집 할 수 있습니다 (편집 가능한 샘플 창은 `<body>` 요소의 내용만 나타냄 이 경우). 다음 작업을 구현하여 기술을 익히십시오.

* `<body>` 요소의 시작 태그 바로 아래에 문서의 기본 제목을 추가하십시오. `<h1>` 여는 태그와 `</h1>` 닫는 태그 안에 싸야합니다.
* 관심있는 주제에 대한 텍스트를 포함하도록 단락 컨텐츠를 편집하십시오.
* 중요한 단어는 `<strong>` 여는 태그와 `</ strong>` 닫는 태그 안에 넣어 굵게 표시하십시오.
* 이 글의 앞부분에서 설명한대로 단락에 대한 링크를 추가하십시오.
* 문서에 이미지를 추가하십시오. 이 글의 앞부분에서 설명한대로 단락 아래에 배치하십시오. 다른 이미지 (컴퓨터의 로컬 또는 웹의 다른 위치)에 연결하면 보너스 포인트를 얻을 수 있습니다.

만약 실수한 경우 언제든지 *Reset* 버튼을 사용하여 초기화 할 수 있습니다. 문제가 발생하면 *Show solution* 단추를 눌러 답변을 확인하십시오.
```

<h2>Live Output</h2>

<div class="output" style="min-height: 50px"></div>

<h2>Editable code</h2>
<p class="a11y-label">
  코드 영역에서 포커스를 이동하려면 Esc 키를 누르십시오 (탭은 탭 문자를
  삽입합니다).
</p>

<textarea id="code" class="input" style="min-height: 100px; width: 95%">
  <p>This is my page</p>
</textarea>

<div class="playable-buttons">
  <input id="reset" type="button" value="Reset" />
  <input id="solution" type="button" value="Show solution" />
</div>
```

```
html {
  font-family: sans-serif;
}

h1 {
  color: blue;
}

h2 {
  font-size: 16px;
}

.a11y-label {
  margin: 0;
  text-align: right;
  font-size: 0.7rem;
  width: 98%;
}

img {
  max-width: 100%;
}

body {
  margin: 10px;
  background: #f5f9fa;
}
```

```
var textarea = document.getElementById("code");
var reset = document.getElementById("reset");
var solution = document.getElementById("solution");
var output = document.querySelector(".output");
var code = textarea.value;
var userEntry = textarea.value;

function updateCode() {
  output.innerHTML = textarea.value;
}

reset.addEventListener("click", function () {
  textarea.value = code;
  userEntry = textarea.value;
  solutionEntry = htmlSolution;
  solution.value = "Show solution";
  updateCode();
});

solution.addEventListener("click", function () {
  if (solution.value === "Show solution") {
    textarea.value = solutionEntry;
    solution.value = "Hide solution";
  } else {
    textarea.value = userEntry;
    solution.value = "Show solution";
  }
  updateCode();
});

var htmlSolution =
  '<h1>Some music</h1><p>I really enjoy <strong>playing the drums</strong>. One of my favorite drummers is Neal Peart, who plays in the band <a href="https://en.wikipedia.org/wiki/Rush\_%28band%29" title="Rush Wikipedia article">Rush</a>. My favourite Rush album is currently <a href="http://www.deezer.com/album/942295">Moving Pictures</a>.</p> <img src="http://www.cygnus-x1.net/links/rush/images/albums/sectors/sector2-movingpictures-cover-s.jpg">';
var solutionEntry = htmlSolution;

textarea.addEventListener("input", updateCode);
window.addEventListener("load", updateCode);

// stop tab key tabbing out of textarea and
// make it write a tab at the caret position instead

textarea.onkeydown = function (e) {
  if (e.keyCode === 9) {
    e.preventDefault();
    insertAtCaret("\t");
  }

  if (e.keyCode === 27) {
    textarea.blur();
  }
};

function insertAtCaret(text) {
  var scrollPos = textarea.scrollTop;
  var caretPos = textarea.selectionStart;

  var front = textarea.value.substring(0, caretPos);
  var back = textarea.value.substring(
    textarea.selectionEnd,
    textarea.value.length,
  );
  textarea.value = front + text + back;
  caretPos = caretPos + text.length;
  textarea.selectionStart = caretPos;
  textarea.selectionEnd = caretPos;
  textarea.focus();
  textarea.scrollTop = scrollPos;
}

// Update the saved userCode every time the user updates the text area code

textarea.onkeyup = function () {
  // We only want to save the state when the user code is being shown,
  // not the solution, so that solution is not saved over the user code
  if (solution.value === "Show solution") {
    userEntry = textarea.value;
  } else {
    solutionEntry = textarea.value;
  }

  updateCode();
};
```

### HTML 공백

위의 예에서 많은 공백이 코드에 포함되어 있음을 알 수 있습니다. 이것은 선택 사항입니다. 이 두 코드 스니펫은 동일합니다.

```html
<p>Dogs are silly.</p>

<p>Dogs        are
         silly.</p>
```

HTML 요소 내용 내에서 얼마나 많은 공백을 사용하든 (하나 이상의 공백 문자를 포함 하거나 줄 바꿈 포함) HTML 파서는 코드를 렌더링 할 때 각 공백 시퀀스를 단일 공백으로 줄입니다. 왜 그렇게 많은 공백을 사용합니까? 답은 가독성입니다.

코드의 보기 좋게 정리되어 있다면 코드에서 무슨 일이 일어나고 있는지 이해하는 것이 더 쉬울 수 있습니다. HTML에는 중첩 된 각 요소가 내부에있는 것보다 두 칸 더 들여 쓰기되어 있습니다. 서식 스타일 (예 : 각 들여 쓰기 수준에 대한 공백 수)을 선택하는 것은 사용자의 몫이지만 서식을 고려해야합니다.

Entity references: HTML에 특수 문자 포함
---------------------------------

HTML에서 문자 `<`,`>`, `"`및 `&`는 특수 문자입니다. 이들은 HTML 구문 자체의 일부입니다. 그럼 어떻게 이러한 특수 문자 중 하나를 내가 사용하고 싶은 텍스트에 포함할까요? 예를 들어, 앰퍼샌드 또는 이하 기호를 텍스트에 사용하고 HTML 코드로 해석되지 않게 하려는 경우와 같이 말입니다.

표를 참고하여 실습해보세요. 오른쪽의 특별한 코드는 특수 문자를 표현할 때 사용되는 문자 참조 코드입니다. 각 문자 참조는 앰퍼샌드 (&)로 시작하고 세미콜론 (;)으로 끝납니다.

| Literal character | Character reference equivalent |
| --- | --- |
| < | `<` |
| > | `>` |
| " | `"` |
| ' | `'` |
| & | `&` |

문자 참조에 해당하는 문자는 '<'보다 작거나 '"'에 대한 인용 및 기타 문자 참조와 유사하게 볼 수 있기 때문에 쉽게 기억할 수 있습니다. 엔터티 참조에 대한 자세한 내용은 List of XML and HTML character entity references (Wikipedia)을 참조하십시오.

아래 예시는 두 개의 단락이 있습니다.

```html
<p>In HTML, you define a paragraph using the <p> element.</p>

<p>In HTML, you define a paragraph using the <p> element.</p>
```

아래의 라이브 출력에서 첫 번째 단락이 잘못되었음을 알 수 있습니다. 브라우저는 <p>의 두 번째 인스턴스를 새 단락을 시작하는 것으로 해석합니다. 두 번째 단락에는 문자 참조가있는 꺾쇠 괄호가 있으므로 잘 보입니다.

**참고:** HTML의 문자 인코딩이 UTF-8로 설정되어 있기 때문에 최신 브라우저는 실제 기호를 잘 처리하므로 다른 기호에 대해서는 엔티티 참조를 사용할 필요가 없습니다.

HTML 주석
-------

HTML에는 코드에 주석을 작성하는 메커니즘이 있습니다. 브라우저는 주석을 무시하여 사용자가 주석을 보이지 않게합니다. 주석의 목적은 코드에 메모를 포함시켜 논리 또는 코딩을 설명 할 수 있도록하는 것입니다. 이것은 코드를 완전히 기억하지 못할 정도로 오랫동안 멀어진 후 코드베이스로 돌아 오는 경우에 매우 유용합니다. 마찬가지로, 다른 사람들이 변경하고 업데이트함에 따라 의견이 매우 중요합니다.

HTML 주석을 쓰려면 특수 마커 `<!-` 및 `->`로 주석을 묶습니다. 예를 들면 다음과 같습니다.

```html
<p>I'm not inside a comment</p>

<!-- <p>I am!</p> -->
```

아래에서 볼 수 있듯이 첫 번째 단락만 라이브 출력에 표시됩니다.

Summary
-------

HTML 기본 사항을 둘러 보셨기를 바랍니다.

이 글을 읽고나면 HTML의 모양과 기본 수준에서 작동하는 방식을 이해해야합니다. 또한 몇 가지 요소와 속성을 작성할 수 있어야합니다. 이 모듈의 후속 기사에서는 여기에 소개 된 주제 중 일부에 대해 더 설명하고 언어의 다른 개념을 제시합니다.

**참고:** HTML에 대해 더 배우기 시작하면 CSS (Cascading Style Sheets)의 기본 사항을 배우십시오. CSS는 웹 페이지의 스타일을 지정하는데 사용되는 언어입니다. (예 : 글꼴 또는 색상 변경 또는 페이지 레이아웃 변경) HTML과 CSS는 곧 발견 될 것입니다.

* Overview: Introduction to HTML
* 다음


과제: 문서 마크업하기 - Web 개발 학습하기

과제: 문서 마크업하기
============

* 이전  (en-US)
* Overview: Introduction to HTML
* 다음

우리는 모두 글자를 쓰는 법을 금방 배우게 됩니다. 이 페이지에서 텍스트를 꾸미고 조작하는 것을 테스트 해볼 수 있는 유용한 예제들이 있습니다. 이 장에서는 하이퍼링크와 HTML `<head>` 요소뿐만이 아니라, 주어진 글을 HTML 기본/혹은 고급 텍스트 포맷팅 방식에 맞춰 다듬는 연습을 할 예정입니다.

|  |  |
| --- | --- |
| 필요한 사전 지식 |
 이 장에 들어서기에 앞서 필요한 사전 지식에는
 HTML 시작하기,
 head 안에는 무엇이 있나? HTML 메타 데이터,
 HTML 텍스트 기본,
 하이퍼링크 만들기,
 텍스트 조작 고급기법
 등이 있습니다.
  |
| 목표 |
 HTML 기본/고급 텍스트 포맷팅 방법, 하이퍼링크, HTML `<head>` 부분에
 무엇이 들어가는지에 대해 학습합니다.
  |

시작하기에 앞서
--------

프로젝트를 시작하기 위해서는 두 가지가 필요합니다. 마크업을 할 기본 텍스트와 HTML에 스타일을 입힐 CSS 코드입니다. 텍스트 편집기를 이용해 .html 파일을 만들거나 CodePen, jsFiddle 또는 Glitch와 같은 온라인 코딩 도구를 사용하여 작업을 진행합니다.

**참고:** 문제가 해결되지 않으면 이 페이지 하단의 평가 또는 추가 도움말 구획을 참조해 도움을 요청하세요.

프로젝트 요약
-------

이 프로젝트에서 여러분은 대학 인트라넷에 호스팅 되어야하는 편지를 마크업하는 것입니다. 이 문서는 예비 박사 과정 학생들이 보낸 질문에 대한 연구원의 답변입니다.

### 블록/구조적인 의미

* 당신은 전체 문서를 doctype을 비롯해 `<html>`, `<head>`, `<body>` 요소들을 이용하여 문서를 다듬어야 합니다.
* 일반적으로 이 문서는 다음과 같은 예시를 제외하고 단락과 제목의 구조로 마크업 해야합니다. 예시에는 가장 높은 단계의 제목("Re:" 줄) 1개와 두 번째 단계의 제목 3개가 있습니다.
* 적절한 목록 유형을 사용하여 학기 시작 날짜, 학습 과목, 이국적인 춤들을 표시 해야합니다.
* 2개의 주소를 `<address>` 요소 안에 넣어야 합니다. 주소의 각 줄은 새로운 줄에 배치하되, 새 문단에 넣지 않아야 합니다.
### 인라인 구조

* 발신자 및 수신자의 이름, "Tel:", "Email:"은 강조하여 표시해야 합니다.
* 문서의 네 날짜에는 기계가 읽을 수 있는 날짜가 포함된 적절한 요소가 있어야 합니다.
* 문서의 첫 번째 주소와 첫 번째 날짜에는 발신자 열의 클래스 속성 값이 있어야 합니다. 나중에 추가할 CSS는 원본 문서 레이아웃처럼 올바르게 정렬되도록 합니다.
* 문서의 본문에 "PhD", "HTML", "CSS", "BC", "Esq." 등 5가지 약어를 표기하여 각 약어의 확장어를 제공해야 합니다.
* 화학식 및 숫자 103과 104(10의 3과 4 거듭제곱)에 6개의 하위/상위 첨자를 적절하게 표시해야 합니다.
* 본문에서 중요도가 높은 적절한 단어를 두 개 이상 표시해야 합니다.
* 본문에 하이퍼링크가 있어야 하는 위치는 두 곳입니다. 제목과 함께 적절한 링크를 추가합니다. 링크가 가리키는 위치의 URL은 `http://example.com`처럼 기재하면 됩니다.
* 대학 모토 인용문과 인용문에 적절한 요소를 표시합니다.
### 문서의 머리글

* 문서의 문자 집합은 적절한 메타 태그를 사용하여 utf-8로 설정해야 합니다.
* 문서의 작성자는 적절한 메타 태그에 명시해야 합니다.
* 제공된 CSS는 적절한 태그 안에 포함되어야 합니다.
힌트와 팁
-----

* W3C HTML 유효성 검사기를 사용하여 HTML의 유효성을 검사합니다. 유효성 검사를 통과하면 보너스 점수를 받을 수 있습니다.
* 이 프로젝트를 수행하기 위해 CSS를 몰라도 상관없습니다. 제공된 CSS를 HTML 요소 안에 넣기만 하면 됩니다.
예제
--

다음 스크린샷은 마크업 후 문자가 어떻게 보일 수 있는지 보여주는 예시입니다.

![Example](/ko/docs/Learn/HTML/Introduction_to_HTML/Marking_up_a_letter/letter_screengrab_2.png)

평가 또는 추가 도움말
------------

평가를 받고 싶거나 막혀서 도움을 요청하고 싶은 경우에 읽으시면 됩니다.

1. CodePen, jsFiddle, Glitch와 같은 공유 가능한 온라인 편집기에 작성 코드를 넣습니다.
2. MDN 토론 포럼 학습 카테고리에서 평가 또는 도움을 요청하는 게시글을 작성합니다. 게시글에는 다음 내용이 포함되어야 합니다.
    * "문서 마크업에 대한 평가 필요"와 같은 설명이 포함된 제목입니다.
    * 이미 시도한 사항과 바라는 사항(예시: 문제가 발생하여 도움이 필요하거나 평가를 원하는 경우)에 대한 세부 내용을 작성합니다.
    * 평가받고 싶거나 도움이 필요한 경우에 대한 위의 1단계에서 제시한 것 처럼, 온라인 공유 가능 편집기 링크가 있어야합니다. 코드를 볼 수 없다면 코딩에 관한 문제가 있는 사람을 도와주기가 매우 어렵기 때문입니다.
    * 링크는 실제 프로젝트 또는 평가 페이지로 연결되는 링크로, 도움을 받고자 하는 문제를 확인할 수 있습니다.
* 이전  (en-US)
* Overview: Introduction to HTML
* 다음


하이퍼링크 만들기 - Web 개발 학습하기

하이퍼링크 만들기
=========

* 이전
* Overview: Introduction to HTML
* 다음

웹을 웹답게 만든다는 점에서 하이퍼 링크는 중요합니다. 이 글에서는 링크를 만드는데 필요한 구문을 보여주고 링크의 모범 사례를 설명합니다.

|  |  |
| --- | --- |
| 사전 지식 | HTML 시작하기에서 설명하는 기본적인 HTML 숙련도.
 HTML text fundamentals에서 설명하는 HTML 텍스트 포맷팅에 대한 지식.
  |
| 목표 | 하이퍼링크를 효과적으로 다루는 방법과 수많은 파일들을 함께 연결하는 방법을 배웁니다. |

하이퍼링크란
------

하이퍼링크는 웹이 제공하는 가장 흥미로운 혁신 중 하나입니다. 하이퍼링크는 처음부터 웹의 기능이었으며 웹을 웹으로 만드는 요소입니다. 하이퍼링크를 사용하면 문서를 다른 문서나 리소스에 연결하거나, 문서의 특정 부분에 연결하거나, 웹 주소에서 앱을 사용할 수 있습니다. 클릭하거나 다른 방법으로 활성화된 웹 브라우저가 다른 웹 주소(URL)로 이동하도록 거의 모든 웹 콘텐츠를 링크로 변환할 수 있습니다.

**참고:** URL은 HTML 파일, 텍스트 파일, 이미지, 텍스트 문서들, 비디오와 오디오 파일들, 그리고 웹상에서 존재할 수 있는 어느 것이든 연결할 수 있습니다. 웹 브라우저가 파일을 표시하거나 처리하는 방법을 모르는 경우 파일을 열 것인지(이 경우 파일을 열거나 처리해야 할 의무가 장치의 적절한 기본 앱에 전달됨) 또는 파일을 다운로드할 것인지(이 경우 나중에 처리를 시도할 수 있음) 묻는 메시지가 표시됩니다.

예를 들어, BBC 홈페이지에는 여러 뉴스 기사뿐만 아니라 사이트의 다양한 영역(내비게이션 기능), 로그인/등록 페이지(사용자 도구) 등을 가리키는 많은 링크가 포함되어 있습니다.

![많은 뉴스 항목과 탐색 메뉴 기능을 보여주는 bbc.co.uk의 첫 페이지](/ko/docs/Learn/HTML/Introduction_to_HTML/Creating_hyperlinks/updated-bbc-website.png)

링크의 구조
------

기본 링크는 텍스트 또는 기타 내용(Block level links)을 `<a>` 요소 안에 감싸고 웹 주소를 포함하는 `href` 속성(**Hypertext Reference** 또는 **target**)을 사용하여 생성됩니다.

```html
<p>
  나는 <a href="https://www.mozilla.org/en-US/">Mozilla 홈페이지</a>로 향하는
  링크를 만들었습니다.
</p>
```

위 코드의 결과는 다음과 같습니다.

나는 Mozilla 홈페이지로 향하는 링크를 만들었습니다.

### Block level 링크들

이전에 얘기했듯이, 여러분은 어떤 내용이든 link로 바꿀 수 있습니다. block level 요소들 이라고 할지라도요. 만약 링크로 바꾸고 싶은 이미지가 있다면, 다음 코드 스니펫과 같이 ``<a>`` 요소로 이미지를 감싸면 됩니다.

```html
<a href="https://developer.mozilla.org/en-US/">
  <h1>MDN Web Docs</h1>
</a>
<p>
  Documenting web technologies, including CSS, HTML, and JavaScript, since 2005.
</p>
```

 이렇게 하면 헤더를 링크로 바꿀 수 있습니다.

### 이미지 링크들

링크로 만들 이미지가 있는 경우 `<a>` 요소를 사용하여 `<img>` 요소와 함께 참조되는 이미지 파일을 감쌉니다.
```

img {
  height: 100px;
  width: 150px;
  border: 1px solid gray;
}
```

```html
<a href="https://developer.mozilla.org/en-US/">
  <img src="mdn\_logo.svg" alt="MDN Web Docs homepage" />
</a>
```

 그러면 MDN logo가 링크로 연결됩니다.

**참고:** 웹에서 이미지를 사용하는 방법에 대한 자세한 내용은 다음 문서에서 확인할 수 있습니다.

### title 속성에 부가적인 정보를 더하기

링크에 추가할 수 있는 또 다른 속성은 `title`입니다. Title은 페이지에 포함된 정보 또는 웹 사이트에서 주의해야 할 사항 등 링크에 대한 추가 정보를 포함하고 있습니다.

```html
<p>
  I'm creating a link to
  <a
 href="https://www.mozilla.org/en-US/"
 title="The best place to find more information about Mozilla's
 mission and how to contribute">
    the Mozilla homepage</a>.
</p>
```

그러면 다음과 같은 결과가 나오고 링크 위를 마우스를 올리면 제목이 툴팁으로 표시됩니다.

**참고:** 링크 제목은 마우스 호버에만 표시되므로 키보드 컨트롤이나 터치스크린을 사용하여 웹 페이지를 탐색하는 사용자는 제목 정보에 액세스하는 데 어려움을 겪습니다. Title의 정보가 페이지의 사용에 있어서 정말로 중요하다면, 해당하는 정보를 일반 텍스트로 넣어줌으로써 모든 사용자가 접근할 수 있는 방식으로 표시해야 합니다.

### 능동학습: 예제 링크를 만들어봅시다

코드 편집기와 소스코드: 템플릿 시작하기를 사용하여 HTML 문서를 만듭니다.

* HTML body 안에 이미 알고 있는 하나 이상의 단락 또는 다른 유형의 내용을 추가합니다.
* 일부 내용을 링크로 변경합니다.
* title 속성들을 추가해보세요.
URL과 path에 대한 기본 지침
-------------------

link target에 대해 완전히 이해하기 위해서, URL과 파일 path에 대하여 이해할 필요가 있습니다. 이 섹션에서는 이 작업을 수행하는 데 필요한 정보를 제공합니다.

URL, 혹은 Uniform Resource Locator은 단순히 무언가가 웹상의 어디에 위치하는지 결정하는 하나의 텍스트 문자열입니다. 예를 들면, Mozilla 영어 홈페이지는 `https://www.mozilla.org/en-US/`이죠.

URL은 파일들을 찾기위해 path를 이용합니다. path는 당신이 관심있어 하는 파일이 파일 시스템 어디에 있는지 구체적으로 명시하구요. 디렉토리 구조에 대한 예제를 보시죠. (하이퍼링크 만들기를 보세요.)

![A simple directory structure. The parent directory is called creating-hyperlinks and contains two files called index.html and contacts.html, and two directories called projects and pdfs, which contain an index.html and a project-brief.pdf file, respectively](/ko/docs/Learn/HTML/Introduction_to_HTML/Creating_hyperlinks/simple-directory.png)

이 디렉토리 구조의 **root**를 `creating-hyperlinks`라고 부릅니다. 웹사이트를 로컬 단에서 다룰 때에는 전체 웹사이트가 모두 들어갈 수 있는 하나의 디렉토리를 가져야 할 것입니다. Root 안에서 우리는 `index.html` 파일과 `contacts.html` 파일을 갖습니다. 실제 웹사이트에서 `index.html` 는 우리의 홈페이지 또는 랜딩 페이지(웹사이트의 접속 포인트 또는 웹사이트의 특정 부분이 되는 페이지)가 될 것입니다.

또 Root 안에는 `pdfs`와 `projects`라는 두 개의 디렉토리가 있습니다. 이들은 각각 PDF(`project-brief.pdf`)와 `index.html` 파일을 내부에 가지고 있습니다. 두 개의 index.html 파일이 서로 다른 파일 시스템 위치에 있는 한, 하나의 프로젝트에 두 개의 index.html 파일을 포함할 수 있습니다. 두번째 `index.html`는 아마 프로젝트와 관련된 정보의 메인 랜딩 페이지가 될 것입니다.

* **같은 디렉토리(폴더):** `contacts.html`을 가리키는 하이퍼링크를 `index.html`(최상위 레벨 `index.html`) 안에 포함하려면 현재 파일과 동일한 디렉토리에 있으므로 연결하려는 파일의 이름만 지정하면 됩니다. 따라서 사용할 URL은 `contacts.html` 입니다.

```html
<p>
  Want to contact a specific staff member? Find details on our
  <a href="contacts.html">contacts page</a>.
</p>
```

* **하위 디렉토리로 하향 이동:** `projects/index.html`을 가리키는 하이퍼링크를 `index.html`(최상위 레벨 `index.html`)에 포함하려면 연결하려는 파일을 표시하기 전에 프로젝트 디렉토리로 내려가야 합니다. 이 작업은 디렉토리 이름, 그 다음 슬래시, 그 다음 파일 이름을 지정하여 수행되므로 사용할 URL은 `projects/index.html` 입니다.

```html
<p>저의 <a href="projects/index.html">프로젝트 홈페이지</a>에 방문해주세요.</p>
```

* **부모 디렉토리로 상향 이동:** `pdfs/project-brief.pdf`를 가리키는 하이퍼링크를 `projects/index.html` 안에 포함하려면 디렉토리 레벨을 올린 다음 다시 pdf 디렉토리로 내려가야 합니다. "상위 디렉터리 이동"은 두 개의 점(`..`)을 사용하여 표시합니다. 따라서 사용할 URL은 `../pdfs/project-brief.pdf` 입니다.

```html
<p>나의 <a href="../pdfs/project-brief.pdf">프로젝트 개요</a> 링크입니다.</p>
```

**참고:** 필요한 경우 아래와 같이 상향 이동이나 하향 이동 기능을 이용해 여러 인스턴스를 복잡한 URL로 결합할 수 있습니다. `../../../complex/path/to/my/file.html`.

### 문서 조각

문서 상단이 아닌 HTML 문서 내부의 특정 부분(Document fragments(문서 조각)에 연결할 수 있습니다. 그러기 위해 먼저 여러분은 연결하고 싶은 태그에 `id` 속성을 넣어주어야 합니다. 일반적으로는 아래와 같이 특정 헤드라인에 연결하는 것이 타당합니다.

예제

```html
<h2 id="Mailing\_address">Mailing 주소</h2>
```

그런 다음 해당 ID에 연결하려면 아래 예시와 같이 URL 끝에 해시/파운드 기호를 포함하면 됩니다.

```html
<p>
  우리에게 메일을 보내고 싶나요? 그럼
  <a href="contacts.html#Mailing\_address">메일 주소</a>를 확인해주세요.
</p>
```

Document fragments(문서 조각)를 참조하여 현재 문서의 다른 부분에 연결할 수도 있습니다.

```html
<p>
  <a href="#Mailing\_address">회사 메일 주소</a>는 페이지의 하단에서 찾을 수
  있습니다.
</p>
```

### 절대 URL과 상대 URL

웹에서는 절대 URL과 상대 URL 두 가지의 용어를 찾아볼 수 있습니다.

**절대 URL:** protocol과 domain name을 포함한, 웹에서 정의된 절대적인 위치를 가리킵니다. 예를 들어, 만약 `index.html` 페이지가 `projects` 폴더에 업로드 되면 이는 웹 서버의 root 안에 위치하게 되고
 웹 사이트의 도메인이 `http://www.example.com`라면, 해당 페이지는 `http://www.example.com/projects/index.html`
 (혹은 그저 `http://www.example.com/projects/`가 됩니다. 대부분의 웹 서버는 URL에서 명시되지 않은 경우 페이지를 불러오기 위해 `index.html`과 같은 랜딩 페이지를 찾습니다.)

절대 URL은 어디에 사용되든 항상 같은 장소를 가리킵니다.

**상대 URL:** 연결되어 있는 파일(과거 섹션의 파일 같은)로부터 상대적인 위치를 가리킵니다. 예를 들어, 여러분이 예시 파일 `http://www.example.com/projects/index.html`에서 같은 디렉토리에 있는 PDF 파일로 연결하고 싶다면, URL은 `project-brief.pdf` 과 같이 파일이름이어야 할 것입니다. 추가 정보는 필요 없습니다. 만약 PDF 파일이 `projects`의 하위 디렉토리인 `pdfs`에 있다면, 상대 URL은 `pdfs/project-brief.pdf`일 것입니다. (같은 URL이지만 절대 경로로는 `http://www.example.com/projects/pdfs/project-brief.pdf`로 표현할 수 있습니다.)

 상대 URL은 파일의 실제 위치가 어디냐에 따라 다른 장소를 가리킬 것입니다. 예를 들어 여러분이 `index.html` 파일을 `projects` 디렉토리에서 웹사이트의 root로 옮긴다면 (어느 디렉토리에도 포함되지 않는 최상위 디렉토리), `pdfs/project-brief.pdf` 의 상대 URL은 `http://www.example.com/pdfs/project-brief.pdf`를 가리킬 것입니다.
 `http://www.example.com/projects/pdfs/project-brief.pdf`를 가리키지 않습니다.

물론, 여러분이 `index.html` 파일을 옮겼다고 해서 `project-brief.pdf` 파일과 `pdfs` 폴더의 위치가 갑자기 바뀌지는 않을 것입니다. 이것은 당신의 링크가 잘못된 곳을 가리키게 할 것이므로 클릭을 해도 제대로 작동하지 않을 것입니다. 주의하세요!

Link 실습
-------

링크를 작성할 때 따라야 할 몇 가지 좋은 관습이 있습니다. 지금부터 살펴보겠습니다.

### 링크 명을 명확하게

여러분의 페이지에 링크를 올리는 것은 쉽습니다. 하지만 그것만으로는 충분하지 않습니다. 여러분은 모든 독자들에게 현재 상황과 선호하는 도구와 관계없이 링크에 접근할 수 있도록 해야 합니다.

예를 들면

* 스크린 리더 사용자들은 페이지의 링크에서 링크로 이동하거나 문맥을 벗어난 링크를 읽는 것을 좋아합니다.
* 검색 엔진은 링크 텍스트를 사용하여 대상 파일을 인덱싱하므로 링크 텍스트에 키워드를 포함하여 링크되는 내용을 효과적으로 설명하는 것이 좋습니다.
* 시각적 독자들은 모든 단어를 읽는 것보다 페이지를 훑어보고, 링크와 같이 눈에 띄는 페이지 특징에 끌릴 것입니다. 그들은 설명적인 링크 텍스트가 유용하다고 생각할 것입니다.

구체적인 예제를 한번 살펴봅시다.

**좋은** link text: Download Firefox

```html
<p><a href="https://www.mozilla.org/firefox/">Download Firefox</a></p>
```

**나쁜** link text: Click here to download Firefox

```html
<p>
  <a href="https://www.mozilla.org/firefox/">Click here</a> to download Firefox
</p>
```

다른 팁들

* URL을 링크 텍스트의 일부로 반복하지 마십시오. URL이 보기 흉하며, 화면을 보는 사람들이 글자로 URL을 볼 때 이상하게 보입니다.
* 링크 텍스트에 "link"나 "links to"라고 쓰지마세요. 잡음이 될 뿐입니다. 화면 판독기는 사용자에게 링크가 있다고 말합니다. 링크는 일반적으로 다른 색상으로 스타일링되고 밑줄이 그어져 있기 때문에 시각적으로 브라우저를 보는 사용자들도 링크가 있다는 것을 알 것입니다. (사용자들이 익숙하기 때문에 일반적으로 이 규칙을 어기면 안 됩니다.)
* 링크 텍스트를 가능한 짧게 유지하십시오. 화면 판독기는 전체 링크 텍스트를 해석해야 하므로 유용합니다.
* 동일한 텍스트의 여러 복사본이 서로 다른 장소에 연결되는 경우를 최소화합니다. "여기 클릭", "여기 클릭", "여기 클릭"이라는 라벨이 붙어 있는 링크 목록이 있는 경우, 화면 판독기 사용자에게 문제가 발생할 수 있습니다.
### 비 HTML 리소스 연결 시 명확한 표식 남기기

다운로드될 리소스(예: PDF 또는 Word 문서), 스트리밍될 리소스(예: 비디오 또는 오디오), 또는 다른 잠재적으로 예기치 않은 효과(팝업 창 열기)에 연결할 경우, 혼동을 줄이기 위해 명확한 문구를 추가해야 합니다.

예를 들면

* 저대역폭 연결 중인 경우 링크를 클릭하면 예기치 않게 여러 메가바이트 다운로드가 시작됩니다.

여기서 사용할 수 있는 텍스트의 종류를 알아보기 위해 몇 가지 예를 살펴보겠습니다.

```html
<p>
  <a href="https://www.example.com/large-report.pdf">
    Download the sales report (PDF, 10MB)
  </a>
</p>

<p>
  <a href="https://www.example.com/video-stream/" target="\_blank">
    Watch the video (stream opens in separate tab, HD quality)
  </a>
</p>
```

### 다운로드 연결 시 download 속성 사용

브라우저에서 열지 않고 다운로드할 리소스에 연결하는 경우 `다운로드` 속성을 사용하여 기본 저장 파일 이름을 제공할 수 있습니다. 다음은 최신 Windows 버전의 Firefox 다운로드 링크의 예입니다.

```html
<a
 href="https://download.mozilla.org/?product=firefox-latest-ssl&os=win64&lang=en-US"
 download="firefox-latest-64bit-installer.exe">
  Download Latest Firefox for Windows (64-bit) (English, US)
</a>
```

활동적인 학습: 탐색 메뉴 만들기
------------------

이 연습을 위해 일부 페이지를 탐색 메뉴와 함께 연결하여 다중 페이지 웹 사이트를 만들었으면 합니다. 이것은 웹 사이트를 만드는 일반적인 방법 중 하나입니다. 동일한 탐색 메뉴를 포함하여 모든 페이지에서 동일한 페이지 구조가 사용되므로 링크를 클릭하면 사용자가 같은 장소에 있고 다른 내용이 표시됩니다.

다음 네 페이지의 로컬 복사본을 모두 같은 디렉토리에 만들어야 합니다. (전체 목록을 보려면 navigation-menu-start 디렉토리를 참조하세요.)

* index.html
* projects.html
* pictures.html
* social.html

여러분이 해야할 것

1. 연결할 페이지의 이름이 포함된 한 페이지의 표시된 위치에 순서 없는 목록을 추가합니다. 탐색 메뉴는 일반적으로 링크의 목록이므로 의미론적으로 좋습니다.
2. 각 페이지 이름을 해당 페이지에 대한 링크로 변경합니다.
3. 탐색 메뉴를 각 페이지에 복사합니다.
4. 각 페이지에서 동일한 페이지에 대한 링크만 제거합니다. 페이지가 자신에 대한 링크를 포함하는 것은 혼란스럽고 불필요합니다. 또한 링크가 없으면 현재 사용 중인 페이지를 시각적으로 확인할 수 있습니다.

완성된 예는 다음과 같습니다.

![An example of a simple HTML navigation menu, with home, pictures, projects, and social menu items](/ko/docs/Learn/HTML/Introduction_to_HTML/Creating_hyperlinks/navigation-example.png)

**참고:** 문제가 발생하거나 문제가 제대로 해결되었는지 확신할 수 없는 경우 navigation-menu-marked-up 디렉토리를 확인하여 정답을 확인할 수 있습니다.

이메일 링크
------

클릭하면 리소스 또는 페이지에 연결하는 대신 새 발신 전자 메일 메시지를 여는 링크 또는 단추를 만들 수 있습니다. 이것은 `<a>` 태그안에 `mailto:` URL 스키마를 사용하여 구현할 수 있습니다.

가장 기본적이고 일반적으로 사용되는 형태의 `mailto:` 링크는 단순히 대상 수신인의 이메일 주소를 표시합니다.

예를 들면

```html
<a href="mailto:nowhere@mozilla.org">아무데나 전자 메일 보내기</a>
```

이렇게 되면 다음과 같은 링크가 생성됩니다. 아무데나 전자 메일 보내기.

사실, 이메일 주소는 심지어 선택사항입니다. 그것을 생략하면(즉, 당신의 `href` 아직 목적지 주소가 지정되지 않은 사용자의 메일 클라이언트에 의해 새로운 발신 이메일 창이 열립니다. 이것은 종종 사용자가 선택한 주소로 이메일을 보내기 위해 클릭할 수 있는 "공유" 링크로서 유용합니다.

### 세부 사항 지정하기

이메일 주소 외에도 다른 정보를 제공할 수 있습니다. 실제로 표준 메일 헤더 필드는 사용자가 제공하는 `mailto` URL에 추가할 수 있습니다. 이 중 가장 일반적으로 사용되는 것은 "subject", "cc" 및 "body"(실제 헤더 필드는 아니지만 새 전자 메일에 대한 짧은 내용 메시지를 지정할 수 있습니다.)입니다. 각 필드와 해당 값은 쿼리 단위로 지정됩니다.

다음은 cc, bcc, subject 및 body를 포함하는 예입니다.

```html
<a
 href="mailto:nowhere@mozilla.org?cc=name2@rapidtables.com&bcc=name3@rapidtables.com&subject=The%20subject%20of%20the%20email&body=The%20body%20of%20the%20email">
  Send mail with cc, bcc, subject and body
</a>
```

**참고:** 각 필드의 값은 인쇄되지 않는 문자(탭, 캐리지 리턴, 페이지 구분과 같은 보이지 않는 문자 percent-escaped)와 공백을 사용하여 URL로 인코딩해야 합니다.
 또한 물음표(`?`)를 사용하여 필드 값에서 기본 URL을 구분하고, `mailto:` URL의 각 필드를 구분하는 `&`를 사용합니다.
 이것은 표준 URL 쿼리 표기법입니다.
 어떤 URL 쿼리 표기법이 더 일반적으로 사용되는지 이해하기 위해 The GET method (en-US) 문서를 읽어보세요.

여기 다른 몇 가지 `mailto` URL 샘플들이 있습니다.

* mailto:
* mailto:nowhere@mozilla.org
* mailto:nowhere@mozilla.org,nobody@mozilla.org
* mailto:nowhere@mozilla.org?cc=nobody@mozilla.org
* mailto:nowhere@mozilla.org?cc=nobody@mozilla.org&subject=This%20is%20the%20subject
실력을 시험해 보세요
-----------

이 글의 끝에 도달한 여러분은 가장 중요했던 정보들을 기억하고 계신가요? 다음 단계로 넘어가기 전에 이 정보를 알고있는지 확인하기 위한 추가 테스트 해볼 수 있습니다. 자세한 내용은 Test your skills: Links (en-US) 링크를 참조하세요.

요약
--

이제 링크는 여기까지입니다. 어쨌든! 스타일링을 시작하면 나중에 이 과정의 링크로 돌아올 것입니다. 다음 HTML에서는 텍스트 의미론(Text Semantics)으로 돌아가서 유용하게 사용할 수 있는 고급의 다른 기능들을 살펴보도록 하겠습니다. 다음에 알아볼 내용은 Advanced text formatting입니다.

* 이전
* Overview: Introduction to HTML
* 다음


콘텐츠 페이지 구조화 - Web 개발 학습하기

콘텐츠 페이지 구조화
===========

* 이전
* Overview: Introduction to HTML

CSS를 사용하여 콘텐츠 페이지를 레이아웃할 수 있도록 구조화하는 것은 숙달해야 할 매우 중요한 기술이므로 이 장에서는 페이지가 어떻게 보일지 고려하고 그 위에 레이아웃을 구축할 적절한 구조적 의미론(Structural Semantics)을 선택하는 능력을 테스트합니다.

|  |  |
| --- | --- |
| 필요한 사전 지식: |
 이 장에 참여하기 전에
 문서 및 웹사이트 구조 (en-US)에 특히 중점을 두고 나머지 과정을 먼저 완료 해주시기 바랍니다.
  |
| 목표: | 웹 페이지 구조에 대한 지식과 예비 레이아웃 디자인을 마크업으로 표현하는 방법을 테스트합니다. |

시작 지점
-----

이 장을 시작하기 위해, 시작 에셋(asset)들을 담고 있는 zip 파일을 다운로드 해주시기 바랍니다.

zip 파일에는 다음이 포함되어 있습니다:

* 구조적 마크업을 추가하는 데 필요한 HTML.
* 마크업에 적용할 CSS.
* 페이지에서 사용되는 이미지들.

로컬 컴퓨터에서 예제를 만들거나, 또는 CodePen, jsFiddle, 또는 Glitch와 같은 온라인 도구를 사용하여 작업을 수행합니다.

**참고:** 만약 막히면, 도움을 요청하세요 — 이 페이지 아래의 Assessment or further help 섹션을 보세요.

프로젝트 개요
-------

이 프로젝트의 과제는 조류 관찰 웹사이트의 홈페이지 콘텐츠를 가져와 페이지 레이아웃을 적용할 수 있도록 구조적인 요소를 추가하는 것입니다. 다음과 같은 요소들이 필요합니다:

* 페이지의 주요 제목(main title), 사이트 로고 및 탐색 메뉴가 포함된 사이트의 전체 너비에 걸친 헤더(header). 스타일이 적용되면 제목과 로고가 옆에 나란히, 그리고 탐색 메뉴는 이 두 항목 아래에 표시됩니다.
* 두 개의 열로 이루어진 메인 콘텐츠 영역 — 환영하는 텍스트를 담을 주요 블록(main block)과 이미지 썸네일을 담을 사이드바(sidebar).
* 저작권 정보 및 크레딧이 포함된 푸터(footer).

다음에 적합한 래퍼(wrapper)를 추가 해주시기 바랍니다:

* 헤더
* 탐색 메뉴
* 메인 콘텐츠
* 환영하는 텍스트
* 이미지 사이드바
* 푸터

또한 다음을 수행 해주시기 바랍니다:

* 시작 부분에서 제공된 기존 요소 바로 아래에 다른 `<link>` 요소를 추가하여 제공된 CSS를 페이지에 적용합니다.
힌트 및 팁
------

* W3C Nu HTML Checker를 사용하면 HTML, CSS, SVG에서 의도하지 않은 실수 — 다른 방법으로는 놓쳤을 수 있는 실수 — 를 찾아내어 수정할 수 있습니다.
* 이 장을 수행하기 위해 CSS를 알 필요 없이 제공된 CSS를 HTML 요소 안에 넣어주시기만 하면 됩니다.
* 제공된 CSS는 올바른 구조적인 요소들이 마크업에 추가되면 렌더링된 페이지에서 녹색으로 표시되도록 설계되었습니다.
* 만약 어떤 요소를 어디에 넣어야 할지 막히신다면 페이지 레이아웃의 간단한 블록 다이어그램을 그려서 각 블록을 감싸고 있어야 한다고 생각하는 요소를 적어보시기를 바랍니다. 이 방법은 매우 유용합니다.
예제
--

다음 스크린샷은 마크업이 적용된 후 홈페이지가 어떻게 보일 수 있는지 보여주는 예제입니다.

![The finished example for the assessment; a simple webpage about birdwatching, including a heading of "Birdwatching", bird photos, and a welcome message](/ko/docs/Learn/HTML/Introduction_to_HTML/Structuring_a_page_of_content/example-page.png)

평가 혹은 추가적인 도움
-------------

만약 여러분의 작업을 평가받고 싶으시거나 막혀서 도움을 요청하기를 원하신다면:

1. 여러분의 작업을 CodePen, jsFiddle, 또는 Glitch와 같은 온라인에서 공유 가능한 에디터에 올리세요. 여러분은 코드를 직접 작성할 수도 있고, 혹은 위 섹션에 링크된 시작 파일을 사용할 수도 있습니다.
2. MDN Discourse forum Learning category에 평가 및/또는 도움을 요청하는 글을 작성하세요. 여러분의 글은 다음을 포함해야만 합니다:
    * "콘텐츠 페이지 구조화를 위한 평가 원함"과 같은 서술적인 제목.
    * 여러분이 이미 무엇을 시도해 봤는지, 그리고 우리가 무엇을 하기를 원하는지에 대한 설명. 예를 들자면, 막혀서 도움이 필요하다거나, 평가를 원한다거나 하는 설명을 포함해야 합니다.
    * (위의 단계 1에서 언급된) 온라인에서 공유 가능한 에디터에 있는, 여러분이 평가를 원하거나 도움이 필요한 예제의 링크. 이것은 익숙해지기에 좋은 습관입니다. 코딩 문제가 있는 누군가를 도울 때, 그들의 코드를 보지 못한다면 그들을 돕는 것은 몹시 힘듭니다.
    * 우리가 여러분이 도움을 원하는 문제를 찾을 수 있도록, 실제 과제나 평가 페이지의 링크.
* 이전
* Overview: Introduction to HTML


HTML table advanced features and accessibility - Web 개발 학습하기

HTML table advanced features and accessibility
==============================================

* 이전
* Overview: Tables
* 다음

이 과정의 두 번째 기사에서, 우리는 HTML 테이블의 좀 더 고급 기능들을 살펴볼 것입니다. 예를 들어, 캡션/요약과 행을 테이블 헤드, 바디, 푸터 섹션으로 그룹화하는 것과 시각 장애인을 위한 테이블의 접근성을 살펴볼 것입니다.

|  |  |
| --- | --- |
| 필요한 사전 지식: |
 HTML 기초
 (HTML 소개를 확인하세요).
  |
| 목표: | HTML 테이블의 고급 기능들과 테이블의 접근성에 대해 학습합니다. |

<caption>을 사용해서 테이블에 캡션 추가하기
----------------------------

테이블에 캡션을 추가하려면 `<caption>` 요소 안에 내용을 넣고, 이를 `<table>` (en-US) 요소 안에 중첩시키면 됩니다. `<table>` 태그 바로 아래에 넣어야 합니다.

```html
<table>
  <caption>
    Dinosaurs in the Jurassic period
  </caption>

  …
</table>
```

위의 간단한 예시에서 유추할 수 있듯, 캡션은 테이블 내용에 대한 설명을 포함해야 합니다. 이는 페이지를 스캔하는 동안 테이블이 자신에게 유용한지 빠르게 파악하고자 하는 모든 독자들에게 유용하지만, 특히 시각 장애인들에게 유용합니다. 테이블이 무엇에 대한 것인지 알아내기 위해 많은 셀의 내용을 스크린 리더가 읽어주는 대신 사용자는 캡션에 의존할 수 있고, 그 후에 테이블을 자세히 읽을지 여부를 결정할 수 있습니다.

캡션은 `<table>` 태그 바로 아래에 위치합니다.

**참고:** `summary` (en-US) 속성은 `<table>` 요소에도 사용할 수 있습니다. 이는 스크린 리더에 의해 읽힙니다. 하지만 `summary`는 더 이상 사용되지 않고, 시각 장애인이 아닌 사용자에게는 보이지 않기 때문에 `<caption>` 요소를 사용하는 것을 권장합니다.

### 능동적으로 학습하기: 캡션 추가하기

이전 기사에서 처음 만났던 예제를 다시 살펴보면서 이를 실습해 보겠습니다.

1. HTML 테이블 기초의 끝에서 만났던 언어 교사의 학교 시간표를 열거나, timetable-fixed.html 파일을 로컬로 복사하세요.
2. 테이블에 맞는 적절한 캡션을 추가하세요.
3. 코드를 저장하고 브라우저에서 열어보세요.

**참고:** 우리의 버전을 GitHub에서 찾을 수 있습니다. timetable-caption.html (라이브 보기).

<thead>, <tfoot> 및 <tbody> 요소를 사용해서 구조를 추가하기
--------------------------------------------

테이블의 구조가 조금 더 복잡해지면, 테이블에 구조적인 정의를 추가하는 것이 유용합니다. 이를 위해 `<thead>`, `<tfoot>`, `<tbody>` (en-US)를 사용할 수 있습니다. 이는 테이블의 헤더, 푸터, 바디 섹션을 표시할 수 있게 해줍니다.

이러한 요소들은 스크린 리더 사용자에게 테이블을 더 잘 이해할 수 있게 해주지 않으며, 스크린 리더 사용자에게 어떠한 시각적인 향상도 제공하지 않습니다. 하지만 이는 스타일링과 레이아웃에 매우 유용합니다. 몇 가지 흥미로운 예를 들자면, 긴 테이블의 경우 인쇄된 모든 페이지에서 테이블 헤더와 푸터가 반복되도록 하고 테이블 본문은 한 페이지에 표시하고 위아래로 스크롤 하여 내용을 볼 수 있도록 할 수 있습니다.

3가지 요소를 사용하기

* `<thead>` 요소는 테이블에서 헤더가 되는 부분을 감싸야 합니다. 이는 보통 열 제목을 포함하는 첫 번째 행이지만, 항상 그렇지는 않습니다. `<col>` (en-US)/`<colgroup>` (en-US) 요소를 사용하는 경우, 테이블 헤더는 그 아래에 위치해야 합니다.
* `<tfoot>` 요소는 테이블의 푸터가 되는 부분을 감싸야 합니다. 이는 예를 들어 이전 행의 항목들을 합산한 마지막 행일 수 있습니다. 테이블 푸터를 테이블의 맨 아래에 포함시킬 수도 있고, 테이블 헤더 바로 아래에 포함시킬 수도 있습니다. (브라우저는 테이블의 맨 아래에 렌더링합니다.)
* `<tbody>` 요소는 테이블 헤더나 푸터에 포함되지 않는 테이블의 다른 부분을 감싸야 합니다. 이는 테이블 헤더 아래에 표시되거나 때로는 푸터에 표시될 수 있습니다.

**참고:** `<tbody>`는 항상 테이블에 포함되어 있습니다. 코드에서 명시적으로 지정하지 않으면 암시적으로 포함됩니다. 이를 확인하기 위해 `<tbody>`를 포함하지 않는 이전 예제를 열고 브라우저 개발자 도구 (en-US)에서 HTML 코드를 확인하세요. 브라우저가 이 요소를 자동으로 추가했을 것입니다. 이것을 왜 포함해야 하는지 궁금할 것입니다. 하지만 이 요소를 포함하는 것이 테이블 구조와 스타일링을 더 잘 제어할 수 있기 때문에 포함하는 것이 좋습니다.

### 능동적으로 학습하기: 테이블 구조 추가하기

위에서 학습한 새로운 요소들을 실습해 보겠습니다.

1. 우선 spending-record.html 및 minimal-table.css을 새 폴더에 로컬로 복사하세요.
2. 브라우저에서 열어보세요. 괜찮아 보이지만, 개선할 수 있습니다. 지출 금액의 합계를 포함하는 "SUM" 행이 잘못된 위치에 있는 것 같고, 코드에 일부 세부 정보가 누락되어 있습니다.
3. 명확한 헤더 행을 `<thead>` 요소로 감싸고, "SUM" 행을 `<tfoot>` 요소로 감싸고, 나머지 내용을 `<tbody>` 요소로 감싸세요.
4. 저장하고 새로 고침하면, `<tfoot>` 요소를 추가하여 "SUM" 행이 테이블의 맨 아래로 이동한 것을 확인할 수 있습니다.
5. 다음으로, "SUM" 셀이 첫 번째 4개 열을 가로지르도록 `colspan` (en-US) 속성을 추가하여 실제 숫자가 "Cost" 열의 맨 아래에 표시되도록 하세요.
6. 테이블에 추가적인 간단한 스타일링을 추가하여 이 요소들이 CSS를 적용하는 데 얼마나 유용한지 알아보겠습니다. HTML 문서의 head에 빈 `<style>` 요소가 있습니다. 이 요소 안에 다음 CSS 코드를 추가하세요.

```css
tbody {
  font-size: 95%;
  font-style: italic;
}

tfoot {
  font-weight: bold;
}
```

7. 저장하고 새로 고침하면 결과를 확인할 수 있습니다. `<tbody>`와 `<tfoot>` 요소가 없었다면, 동일한 스타일링을 적용하기 위해 훨씬 복잡한 선택자와 규칙을 작성해야 했을 것입니다.

**참고:** 당신이 아직 CSS를 완전히 이해한 것으로 예상하지 않습니다. CSS 학습을 통해 더 많은 것을 배우게 될 것입니다. (CSS 소개는 시작하기에 좋은 장소입니다. 또한 테이블 스타일링에 관한 문서도 있습니다.)

완성된 테이블은 다음과 같아야 합니다.

**참고:** GitHub에서 또한 확인할 수 있습니다. spending-record-finished.html.

중첩 테이블
------

테이블을 다른 테이블에 중첩할 수 있습니다. `<table>` 요소를 포함하여 완전한 구조를 포함한다면 가능합니다. 이는 일반적으로 권장되지 않습니다. 이는 마크업을 더 혼란스럽게 만들고 스크린 리더 사용자에게 접근성을 떨어뜨리기 때문입니다. 또한 많은 경우 기존 테이블에 추가 셀/행/열을 삽입하는 것이 더 좋습니다. 그러나 다른 소스에서 콘텐츠를 쉽게 가져오려는 경우가 있습니다.

다음 마크업은 간단한 중첩 테이블을 보여줍니다.

```html
<table id="table1">
  <tr>
    <th>title1</th>
    <th>title2</th>
    <th>title3</th>
  </tr>
  <tr>
    <td id="nested">
      <table id="table2">
        <tr>
          <td>cell1</td>
          <td>cell2</td>
          <td>cell3</td>
        </tr>
      </table>
    </td>
    <td>cell2</td>
    <td>cell3</td>
  </tr>
  <tr>
    <td>cell4</td>
    <td>cell5</td>
    <td>cell6</td>
  </tr>
</table>
```

출력은 다음과 같습니다.
```

table {
  border-collapse: collapse;
}
td,
th {
  border: 1px solid black;
  padding: 10px 20px;
}
```

시각 장애가 있는 사용자를 위한 테이블
---------------------

데이터 테이블을 어떻게 사용하는지 간단히 다시 설명해 보겠습니다. 테이블은 데이터에 빠르게 접근하고 다른 값을 조회하는 데 유용한 도구입니다. 예를 들어, 아래 테이블을 살펴보면 2016년 8월에 Gent에서 몇 개의 반지가 판매되었는지 쉽게 알 수 있습니다. 이 테이블의 정보를 이해하기 위해, 이 테이블의 데이터와 열/행 헤더 사이의 시각적 연관성을 만듭니다.

Items Sold August 2016|  | Clothes | Accessories |
| Trousers | Skirts | Dresses | Bracelets | Rings |
| Belgium | Antwerp | 56 | 22 | 43 | 72 | 23 |
| Gent | 46 | 18 | 50 | 61 | 15 |
| Brussels | 51 | 27 | 38 | 69 | 28 |
| The Netherlands | Amsterdam | 89 | 34 | 69 | 85 | 38 |
| Utrecht | 80 | 12 | 43 | 36 | 19 |

그러나 시각적 연관성을 만들 수 없는 경우는 어떻게 해야 할까요? 그런 경우에는 어떻게 테이블을 읽어야 할까요? 시각 장애가 있는 사람들은 종종 웹 페이지의 정보를 읽어주는 스크린 리더를 사용합니다. 이것은 일반 텍스트를 읽을 때는 문제가 되지 않지만, 테이블을 해석하는 것은 시각 장애가 있는 사람에게는 꽤 어려운 일입니다. 그러나 적절한 마크업을 사용하면 시각적 연관성을 프로그램적 연관성으로 대체할 수 있습니다.

**참고:** 2017년 WHO 데이터에 따르면 시각 장애가 있는 사람은 약 2억 5천 3백만 명입니다.

기사의 이 부분에서는 테이블을 가능한 한 접근성 있게 만드는 데 필요한 기술을 제공합니다.

### 열 및 행 헤더 사용하기

스크린 리더는 모든 헤더를 식별하고 헤더와 관련된 셀 사이의 프로그램적 연관성을 만들어 사용합니다. 열과 행 헤더의 조합은 각 셀의 데이터를 식별하고 해석하여 시각 장애가 있는 사용자가 시각적으로 사용자가 하는 것과 유사하게 테이블을 해석할 수 있습니다.

우리는 이미 이전 기사에서 헤더를 다루었습니다. <th> 요소로 헤더 추가하기를 참고하세요.

### scope 속성

이 기사의 새로운 주제는 `<th>` 요소에 추가할 수 있는 `scope` (en-US) 속성입니다. 이 속성은 스크린 리더에게 헤더가 어떤 셀의 헤더인지 정확하게 알려줍니다. 예를 들어, 그것이 있는 행의 헤더인지, 아니면 열의 헤더인지를 알려줍니다. 이전에 사용한 지출 기록 예제를 다시 한번 살펴보겠습니다. 열 헤더를 다음과 같이 열 헤더로 정의할 수 있습니다.

```html
<thead>
  <tr>
    <th scope="col">Purchase</th>
    <th scope="col">Location</th>
    <th scope="col">Date</th>
    <th scope="col">Evaluation</th>
    <th scope="col">Cost (€)</th>
  </tr>
</thead>
```

열 헤더와 함께 행 헤더를 추가한다면 각각의 행은 다음과 같이 헤더를 정의할 수 있습니다.

```html
<tr>
  <th scope="row">Haircut</th>
  <td>Hairdresser</td>
  <td>12/09</td>
  <td>Great idea</td>
  <td>30</td>
</tr>
```

스크린 리더는 이와 같이 구조화된 마크업을 인식하고, 사용자가 한 번에 전체 열 또는 행을 읽을 수 있도록 해줍니다.

`scope`는 `colgroup`과 `rowgroup`이라는 두 가지 추가 가능한 값을 가지고 있습니다. 이것들은 여러 열 또는 행 위에 있는 헤더에 사용됩니다. 이 기사의 이 부분의 시작 부분에 있는 "2016년 8월 판매 품목" 테이블을 다시 한번 살펴보면 "의류" 셀이 "바지", "치마", "드레스" 셀 위에 있음을 알 수 있습니다. 이 셀들은 모두 헤더(`<th>`)로 표시되어야 하지만 "의류"는 다른 세 가지 하위 헤더를 정의하는 위에 있는 헤더입니다. 따라서 "의류"는 `scope="colgroup"` 속성을 가져야 하고, 다른 것들은 `scope="col"` 속성을 가져야 합니다.

### id 및 headers 속성

`scope`를 사용하는 대신 `id`와 `headers` (en-US) 속성을 사용하여 헤더와 셀 사이의 연관성을 만들 수 있습니다. 사용 방법은 다음과 같습니다.

1. 고유한 `id`를 각 `<th>` 요소에 추가합니다.
2. 각 `<td>` 요소에 `headers` 속성을 추가합니다. 각 `headers` 속성은 해당 셀의 헤더로 작동하는 모든 `<th>` 요소의 `id` 목록을 공백으로 구분하여 포함해야 합니다.

이렇게 하면 스프레드시트처럼 표에 포함된 각 열과 행의 헤더로 정의된 표의 각 셀의 위치에 대한 명시적인 정의가 제공됩니다. 잘 작동하려면 표에 열 헤더와 행 헤더가 모두 있어야 합니다.

우리의 지출 비용 예제로 돌아가서, 이전 두 개의 스니펫은 다음과 같이 다시 작성될 수 있습니다.

```html
<thead>
  <tr>
    <th id="purchase">Purchase</th>
    <th id="location">Location</th>
    <th id="date">Date</th>
    <th id="evaluation">Evaluation</th>
    <th id="cost">Cost (€)</th>
  </tr>
</thead>
<tbody>
  <tr>
    <th id="haircut">Haircut</th>
    <td headers="location haircut">Hairdresser</td>
    <td headers="date haircut">12/09</td>
    <td headers="evaluation haircut">Great idea</td>
    <td headers="cost haircut">30</td>
  </tr>

  …
</tbody>
```

**참고:** 이 방법은 헤더와 데이터 셀 사이의 매우 정확한 연관성을 만들지만, **많은** 마크업을 사용하며 오류를 남길 여지가 없습니다. `scope` 접근 방식은 대부분의 표에 대해 충분합니다.

### 능동적으로 학습하기: scope와 headers로 놀아보기

1. 마지막 연습을 위해 items-sold.html and minimal-table.css를 새 디렉토리에 복사합니다.
2. 이제 `scope` 속성을 추가하여 이 표를 더 적절하게 만들어 보세요.
3. 마지막으로, 시작 파일을 또 다른 복사본으로 만들고, 이번에는 `id`와 `headers` 속성을 사용하여 표를 더 접근성 있게 만들어 보세요.

**참고:** 당신의 완성된 내용을 우리의 마지막 예제와 비교해 보세요. items-sold-scope.html (라이브 보기) 및 items-sold-headers.html를 참고하세요. (라이브 보기).

요약
--

HTML에서 테이블에 대해 알아야 할 몇 가지 다른 것들이 있지만, 지금은 이것만 알면 됩니다. 다음으로, HTML 테이블 평가로 테스트해 보세요. 즐거운 시간 되세요!

만약 당신이 이미 CSS를 배우고 평가에서 잘했다면, HTML 테이블에 스타일을 입히는 것에 대해 배울 수 있습니다. 테이블 스타일링을 참고하세요.

만약 CSS를 배우고 싶다면, CSS 학습 영역을 확인하세요!

* 이전
* Overview: Tables
* 다음


행성 데이터 구조화 - Web 개발 학습하기

행성 데이터 구조화
==========

* 이전
* Overview: Tables

테이블 평가에서 우리는 태양계의 행성에 대한 일부 데이터를 제공하고, 이를 HTML 테이블로 구조화하도록 요청합니다.

|  |  |
| --- | --- |
| 사전 요구 사항: | 이 평가를 시도하기 전에 이 모듈의 모든 문서를 이미 읽어야 합니다. |
| 목표: | HTML 테이블 및 관련 기능에 대한 이해를 테스트합니다. |

시작점
---

평가를 시작하려면 blank-template.html, minimal-table.css, planets-data.txt의 로컬 복사본을 새 디렉토리에 만듭니다.

또는 JSBin 또는 Glitch와 같은 사이트를 사용하여 HTML, CSS 및 JavaScript를 붙여넣어 평가를 수행할 수 있습니다. 별도의 JavaScript/CSS 패널이 없는 온라인 편집기를 사용하는 경우, HTML 문서 내에 인라인 `<script>` 또는 `<style>` 요소로 넣을 수 있습니다.

**참고:** 궁금한 점이 있거나 도움이 필요하면 문의하세요. 이 페이지 하단의 평가 또는 추가 도움 섹션을 참조하세요.

프로젝트 개요
-------

당신은 학교에서 일하고 있습니다. 현재 학생들은 태양계의 행성을 공부하고 있으며, 행성에 대한 사실과 숫자를 쉽게 찾을 수 있는 데이터 세트를 제공하려고 합니다. 이 경우에는 HTML 데이터 테이블이 좋습니다. 사용 가능한 원시 데이터를 가져와서 아래의 단계를 따라 테이블로 변환해야 합니다.

### 완료해야 할 단계

다음 단계는 테이블 예제를 완료하기 위해 수행해야 할 작업을 설명합니다. 필요한 모든 데이터는 `planets-data.txt` 파일에 포함되어 있습니다. 데이터를 시각화하는 데 어려움이 있다면 아래의 실시간 예제를 참조하거나 다이어그램을 그려보십시오.

1. `blank-template.html`의 복사본을 열고, 외부 컨테이너, 테이블 헤더, 테이블 바디로 테이블을 시작합니다. 이 예제에는 테이블 푸터가 필요하지 않습니다.
2. 제공된 캡션을 테이블에 추가합니다.
3. 모든 열 헤더를 포함하는 행을 테이블 헤더에 추가합니다.
4. 모든 행 헤더를 의미론적으로 제목으로 만들어야 함을 기억하면서 테이블 바디 내에 모든 콘텐츠 행을 생성합니다.
5. 모든 콘텐츠가 관련 행성 옆에 표시된 원시 데이터와 동일한 셀에 배치되도록 합니다.
6. 행 및 열 헤더를 그들이 헤딩으로 작동하는 행, 열 또는 행 그룹과 명확하게 연결하기 위해 속성을 추가합니다.
7. 모든 행성 이름 행 헤더를 포함하는 열 주위에 검은색 테두리를 추가합니다.
힌트와 팁
-----

* 헤더 행의 첫 번째 셀은 비워 두어야 하며 두 열을 병합해야 합니다.
* 행성 이름 행 헤더(예: Saturn) 옆에 있는 그룹 행 헤더(예: Jovian planets)는 조금 까다롭습니다 — 각 항목이 올바른 수의 행과 열에 걸쳐 있는지 확인해야 합니다.
* 헤더를 행/열과 연결하는 한 가지 방법은 다른 방법보다 훨씬 쉽습니다.
예제
--

완성된 테이블은 다음과 같아야 합니다.

![복잡한 테이블에는 위에 캡션이 있습니다. 상단 행 셀은 열 헤더입니다. 헤더의 세 열이 있습니다. 첫 두 열은 병합된 셀을 가지며, 세 번째 열은 각 행에 대한 개별 헤더입니다. 모든 텍스트는 가운데 정렬됩니다. 헤더와 다른 모든 행에는 약간의 배경색이 있습니다.](/ko/docs/Learn/HTML/Tables/Structuring_planet_data/assessment-table.png)

또한 여기에서 실시간 예제를 확인할 수 있습니다(소스 코드를 보지 마세요 — 속임수를 쓰지 마세요!)

평가 또는 추가 도움
-----------

작업을 평가받고 싶거나 궁금한 점이 있거나 도움이 필요하면,

1. CodePen, jsFiddle, Glitch와 같은 온라인 공유 편집기에 작업을 넣습니다.
2. MDN Discourse 포럼 학습 카테고리에서 평가 및/또는 도움을 요청하는 게시물을 작성합니다. 게시물에는 다음이 포함되어야 합니다.
    * "행성 데이터 구조화에 대한 평가 원함"과 같은 설명적인 제목
    * 이미 시도한 것의 세부 사항과 우리에게 원하는 것; 예를 들어, 궁금한 점이 있거나 도움이 필요하거나 평가를 원한다고 알려주세요.
    * 평가하거나 도움이 필요한 예제의 링크를 온라인 공유 편집기에 제공합니다(위의 1단계에서 언급한 대로). 이것은 좋은 습관입니다 — 코드를 볼 수 없다면 코딩 문제에 도움을 주기가 매우 어렵습니다.
    * 도움을 원하는 질문이나 평가 페이지의 링크를 제공하여 해당 질문을 찾을 수 있도록 합니다.
* 이전
* Overview: Tables


HTML 테이블 기초 - Web 개발 학습하기

HTML 테이블 기초
===========

* Overview: Tables
* 다음

이 문서에서는 행, 셀, 제목, 여러 열과 행에 걸쳐 셀을 만드는 방법, 스타일 지정 목적으로 열의 모든 셀을 그룹화하는 방법과 같은 기본 사항을 다루며 HTML 테이블을 시작하는 방법을 안내합니다.

|  |  |
| --- | --- |
| 필요한 사전 지식: |
 HTML의 기초 (
 HTML 소개를 봐주시기 바랍니다).
  |
| 목표: | HTML 테이블에 기본적으로 익숙해지는 것 |

테이블이란 무엇인가요?
------------

테이블은 행과 열로 구성된 구조화된 데이터 집합(**표 형식의 데이터**)입니다. 테이블을 사용하면 사람과 나이, 요일, 지역 수영장 시간표 등 다양한 유형의 데이터 간에 어떤 종류의 연관성을 나타내는 값을 빠르고 쉽게 조회할 수 있습니다.

![A sample table showing names and ages of some people - Chris 38, Dennis 45, Sarah 29, Karen 47.](/ko/docs/Learn/HTML/Tables/Basics/numbers-table.png)

![A swimming timetable showing a sample data table](/ko/docs/Learn/HTML/Tables/Basics/swimming-timetable.png)

1800년에 작성된 미국 인구조사 문서에서 알 수 있듯이 표는 인간 사회에서 매우 일반적으로 사용되며 오랫동안 사용되어 왔습니다.

![A very old parchment document; the data is not easily readable, but it clearly shows a data table being used.](/ko/docs/Learn/HTML/Tables/Basics/1800-census.jpg)

따라서 HTML 제작자가 웹에서 표 형식의 데이터를 구조화하고 표시할 수 있는 수단을 제공한 것은 당연한 일입니다.

### 테이블은 어떻게 작동하나요?

테이블의 핵심은 딱딱하다는 점입니다. 행과 열 헤더를 시각적으로 연결하여 정보를 쉽게 해석할 수 있습니다. 예를 들어 아래 테이블을 보고 62개의 위성을 가진 목성 가스 거성을 찾아보시기 바랍니다. 관련 행과 열 헤더를 연결하면 답을 찾을 수 있습니다.
```

<table>
  <caption>
    Data about the planets of our solar system (Planetary facts taken from
    <a href="https://nssdc.gsfc.nasa.gov/planetary/factsheet/"
 >Nasa's Planetary Fact Sheet - Metric</a
 >).
  </caption>
  <thead>
    <tr>
      <td colspan="2"></td>
      <th scope="col">Name</th>
      <th scope="col">Mass (10<sup>24</sup>kg)</th>
      <th scope="col">Diameter (km)</th>
      <th scope="col">Density (kg/m<sup>3</sup>)</th>
      <th scope="col">Gravity (m/s<sup>2</sup>)</th>
      <th scope="col">Length of day (hours)</th>
      <th scope="col">Distance from Sun (10<sup>6</sup>km)</th>
      <th scope="col">Mean temperature (°C)</th>
      <th scope="col">Number of moons</th>
      <th scope="col">Notes</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th colspan="2" rowspan="4" scope="rowgroup">Terrestrial planets</th>
      <th scope="row">Mercury</th>
      <td>0.330</td>
      <td>4,879</td>
      <td>5427</td>
      <td>3.7</td>
      <td>4222.6</td>
      <td>57.9</td>
      <td>167</td>
      <td>0</td>
      <td>Closest to the Sun</td>
    </tr>
    <tr>
      <th scope="row">Venus</th>
      <td>4.87</td>
      <td>12,104</td>
      <td>5243</td>
      <td>8.9</td>
      <td>2802.0</td>
      <td>108.2</td>
      <td>464</td>
      <td>0</td>
      <td></td>
    </tr>
    <tr>
      <th scope="row">Earth</th>
      <td>5.97</td>
      <td>12,756</td>
      <td>5514</td>
      <td>9.8</td>
      <td>24.0</td>
      <td>149.6</td>
      <td>15</td>
      <td>1</td>
      <td>Our world</td>
    </tr>
    <tr>
      <th scope="row">Mars</th>
      <td>0.642</td>
      <td>6,792</td>
      <td>3933</td>
      <td>3.7</td>
      <td>24.7</td>
      <td>227.9</td>
      <td>-65</td>
      <td>2</td>
      <td>The red planet</td>
    </tr>
    <tr>
      <th rowspan="4" scope="rowgroup">Jovian planets</th>
      <th rowspan="2" scope="rowgroup">Gas giants</th>
      <th scope="row">Jupiter</th>
      <td>1898</td>
      <td>142,984</td>
      <td>1326</td>
      <td>23.1</td>
      <td>9.9</td>
      <td>778.6</td>
      <td>-110</td>
      <td>67</td>
      <td>The largest planet</td>
    </tr>
    <tr>
      <th scope="row">Saturn</th>
      <td>568</td>
      <td>120,536</td>
      <td>687</td>
      <td>9.0</td>
      <td>10.7</td>
      <td>1433.5</td>
      <td>-140</td>
      <td>62</td>
      <td></td>
    </tr>
    <tr>
      <th rowspan="2" scope="rowgroup">Ice giants</th>
      <th scope="row">Uranus</th>
      <td>86.8</td>
      <td>51,118</td>
      <td>1271</td>
      <td>8.7</td>
      <td>17.2</td>
      <td>2872.5</td>
      <td>-195</td>
      <td>27</td>
      <td></td>
    </tr>
    <tr>
      <th scope="row">Neptune</th>
      <td>102</td>
      <td>49,528</td>
      <td>1638</td>
      <td>11.0</td>
      <td>16.1</td>
      <td>4495.1</td>
      <td>-200</td>
      <td>14</td>
      <td></td>
    </tr>
    <tr>
      <th colspan="2" scope="rowgroup">Dwarf planets</th>
      <th scope="row">Pluto</th>
      <td>0.0146</td>
      <td>2,370</td>
      <td>2095</td>
      <td>0.7</td>
      <td>153.3</td>
      <td>5906.4</td>
      <td>-225</td>
      <td>5</td>
      <td>
        Declassified as a planet in 2006, but this
        <a
 href="https://www.usatoday.com/story/tech/2014/10/02/pluto-planet-solar-system/16578959/"
 >remains controversial</a
 >.
      </td>
    </tr>
  </tbody>
</table>
```

```
table {
  border-collapse: collapse;
  border: 2px solid black;
}

th,
td {
  padding: 5px;
  border: 1px solid black;
}
```

올바르게 구현된 HTML 테이블은 스크린 리더와 같은 접근성 도구에서 잘 처리되므로 성공적인 HTML 테이블은 시각 장애가 있는 사용자와 그렇지 않은 사용자 모두의 경험을 향상시켜야 합니다.

### 테이블 스타일링

GitHub에서 라이브 예제를 살펴보실 수도 있습니다! 한 가지 눈에 띄는 점은 표가 좀 더 가독성이 높아졌다는 것입니다. 이 페이지의 위 테이블에는 최소한의 스타일링이 적용된 반면, GitHub 버전에는 더 중요한 CSS가 적용되었기 때문입니다.

웹에서 표를 효과적으로 사용하려면 CSS로 스타일링 정보를 제공하고 HTML로 견고한 구조를 갖추셔야 합니다. 이번 과정에서는 HTML 부분에 초점을 맞추고 있으므로 CSS 부분에 대해 알아보시려면 이 과정을 마치신 후 표 스타일링 문서를 방문하시기 바랍니다.

이번 과정에서는 CSS에 초점을 맞추지는 않겠지만, 스타일링 없이 제공되는 기본값보다 테이블을 더 가독성 있게 만들 수 있는 최소한의 CSS 스타일시트를 제공했습니다. 여기에서 스타일시트를 찾으실 수 있으며, 스타일시트를 적용하는 HTML 템플릿도 찾을 수 있습니다.

### 언제 HTML 테이블을 사용하지 말아야 하나요?

HTML 테이블은 표 형식의 데이터에 사용하셔야 합니다. 이것이 바로 HTML 테이블의 설계 목적입니다. 안타깝게도 많은 사람들이 웹 페이지를 레이아웃할 때 HTML 테이블을 사용하곤 했습니다. 예를 들어 한 행은 헤더를, 한 행은 콘텐츠 열을, 한 행은 푸터를 포함하는 식입니다. 자세한 내용과 예제는 접근성 학습 과정의 페이지 레이아웃에서 확인하실 수 있습니다. 예전에는 브라우저 전반의 CSS 지원이 형편없었기 때문에 테이블 레이아웃이 일반적으로 사용되었습니다. 요즘에는 테이블 레이아웃이 훨씬 덜 일반적이지만 웹의 일부 구석에서 여전히 볼 수 있습니다.

요컨대, CSS 레이아웃 기법 대신 테이블을 레이아웃에 사용하시는 것은 좋지 않습니다. 주된 이유는 다음과 같습니다:

1. **레이아웃 테이블은 시각 장애가 있는 사용자의 접근성을 떨어뜨립니다:** 시각 장애인이 사용하는 스크린 리더 (en-US)는 HTML 페이지에 존재하는 태그를 해석하여 사용자에게 내용을 읽어줍니다. 테이블은 레이아웃에 적합한 도구가 아니며 마크업이 CSS 레이아웃 기술보다 더 복잡하기 때문에 스크린 리더의 출력은 사용자에게 혼란을 줄 수 있습니다.
2. **테이블에서 태그 수프 생성**: 위에서 언급했듯이 테이블 레이아웃은 일반적으로 적절한 레이아웃 기술보다 더 복잡한 마크업 구조를 포함합니다. 이로 인해 코드 작성, 유지 관리 및 디버깅이 더 어려워질 수 있습니다.
3. **테이블이 자동으로 반응하지 않습니다**: 적절한 레이아웃 컨테이너(예: `<header>`, `<section>`, `<article>` 또는 `<div>` (en-US))를 사용하는 경우 너비는 기본적으로 상위 요소의 100%가 됩니다. 반면에 테이블은 기본적으로 콘텐츠에 따라 크기가 조정되므로 다양한 기기에서 효과적으로 작동하는 테이블 레이아웃 스타일을 얻으려면 추가 조치가 필요합니다.
활동적인 학습: 첫 번째 테이블 만들기
---------------------

테이블 이론은 충분히 설명했으니 이제 실제 예제를 살펴보고 간단한 테이블을 만들어 보겠습니다.

1. 먼저 로컬 컴퓨터의 새 디렉터리에 blank-template.html 및 minimal-table.css의 로컬 복사본을 만듭니다.
2. 모든 테이블의 콘텐츠는 이 두 태그로 둘러싸여 있습니다: **`<table></table>` (en-US)**. HTML 본문 안에 추가하세요.
3. 테이블 안의 가장 작은 컨테이너는 **`<td>` (en-US)** 요소('td'는 '테이블 데이터'를 의미)로 생성되는 테이블 셀입니다. 테이블 태그 안에 다음을 추가합니다.

```html
<td>Hi, I'm your first cell.</td>
```

4. 4개의 셀로 이루어진 행을 원하신다면 이 태그를 세 번 복사해야 합니다. 테이블의 내용을 다음과 같이 업데이트합니다.

```html
<td>Hi, I'm your first cell.</td>
<td>I'm your second cell.</td>
<td>I'm your third cell.</td>
<td>I'm your fourth cell.</td>
```

보시다시피 테이블은 서로 아래에 배치되지 않고 같은 행에서 서로 자동으로 정렬됩니다. 각 `<td>` 요소는 하나의 셀을 생성하고 함께 첫 번째 행을 구성합니다. 셀을 추가할 때마다 행이 길어집니다.

이 행이 커지는 것을 막고 두 번째 행에 후속 셀을 배치하려면 **`<tr>` (en-US)** 요소('tr'은 '테이블 행'을 의미)를 사용해야 합니다. 이제 이에 대해 알아보겠습니다.

1. 이미 만든 4개의 셀을 다음과 같이 `<tr>` 태그 안에 배치합니다.

```html
<tr>
  <td>Hi, I'm your first cell.</td>
  <td>I'm your second cell.</td>
  <td>I'm your third cell.</td>
  <td>I'm your fourth cell.</td>
</tr>
```

2. 이제 하나의 행을 만들었으니 한두 개를 더 만들어 보세요. 각 행을 추가 `<tr>` 요소로 감싸고 각 셀을 `<td>`에 포함시켜야 합니다.
### 결과

이렇게 하면 다음과 같은 테이블이 생성됩니다.
```

<table>
  <tr>
    <td>Hi, I'm your first cell.</td>
    <td>I'm your second cell.</td>
    <td>I'm your third cell.</td>
    <td>I'm your fourth cell.</td>
  </tr>

  <tr>
    <td>Second row, first cell.</td>
    <td>Cell 2.</td>
    <td>Cell 3.</td>
    <td>Cell 4.</td>
  </tr>
</table>
```

```
table {
  border-collapse: collapse;
}
td,
th {
  border: 1px solid black;
  padding: 10px 20px;
}
```

**참고:** 이 자료는 GitHub에서 simple-table.html로 확인할 수도 있습니다(라이브 버전도 참조하세요).

<th> 요소로 헤더 추가하기
----------------

이제 행이나 열의 시작 부분에 위치하며 해당 행이나 열에 포함된 데이터 유형을 정의하는 특수 셀인 테이블 헤더에 대해 살펴보겠습니다(예: 이 문서에 표시된 첫 번째 예의 "Person" 및 "Age" 셀 참조). 이 기능이 유용한 이유를 설명하기 위해 다음 테이블 예시를 살펴보십시오. 먼저 소스 코드입니다.

```html
<table>
  <tr>
    <td> </td>
    <td>Knocky</td>
    <td>Flor</td>
    <td>Ella</td>
    <td>Juan</td>
  </tr>
  <tr>
    <td>Breed</td>
    <td>Jack Russell</td>
    <td>Poodle</td>
    <td>Streetdog</td>
    <td>Cocker Spaniel</td>
  </tr>
  <tr>
    <td>Age</td>
    <td>16</td>
    <td>9</td>
    <td>10</td>
    <td>5</td>
  </tr>
  <tr>
    <td>Owner</td>
    <td>Mother-in-law</td>
    <td>Me</td>
    <td>Me</td>
    <td>Sister-in-law</td>
  </tr>
  <tr>
    <td>Eating Habits</td>
    <td>Eats everyone's leftovers</td>
    <td>Nibbles at food</td>
    <td>Hearty eater</td>
    <td>Will eat till he explodes</td>
  </tr>
</table>
```

```
table {
  border-collapse: collapse;
}
td,
th {
  border: 1px solid black;
  padding: 10px 20px;
}
```

이제 실제 렌더링된 테이블입니다.

여기서 문제는 무슨 일이 일어나고 있는지 어느 정도는 파악할 수 있지만 데이터를 상호 참조하기가 쉽지 않다는 것입니다. 열과 행의 제목이 어떤 식으로든 눈에 띄면 훨씬 더 좋을 것입니다.

### 활동적인 학습: 테이블 헤더

이 테이블을 개선해 보겠습니다.

1. 먼저 로컬 컴퓨터의 새 디렉터리에 dogs-table.html 및 minimal-table.css 파일의 로컬 복사본을 만듭니다. HTML에는 위에서 본 것과 동일한 Dogs 예제가 포함되어 있습니다.
2. 테이블 헤더를 시각적으로나 의미적으로 헤더로 인식하려면 **`<th>` (en-US)** 요소('th'는 '테이블 헤더'를 의미)를 사용하시면 됩니다. 이는 일반 셀이 아닌 헤더를 나타낸다는 점을 제외하면 `<td>`와 완전히 동일한 방식으로 작동합니다. HTML로 이동하여 테이블 헤더를 둘러싼 모든 `<td>` 요소를 `<th>` 요소로 변경합니다.
3. HTML을 저장하고 브라우저에서 로드하면 이제 헤더가 헤더처럼 보이는 것을 볼 수 있습니다.

**참고:** 완성된 예제는 GitHub의 dogs-table-fixed.html에서 확인할 수 있습니다(라이브 버전도 참조하세요).

### 헤더가 유용한 이유는 무엇인가요?

이미 이 질문에 부분적으로 답변해 드렸습니다. 헤더가 명확하게 눈에 띄고 디자인이 일반적으로 더 보기 좋으면 원하는 데이터를 더 쉽게 찾을 수 있습니다.

**참고:** 테이블 제목에는 몇 가지 기본 스타일이 제공됩니다. 테이블에 나만의 스타일링을 더하지 않아도 대담하고 중심을 잡아주어 테이블을 돋보이게 해줍니다.

테이블 헤더에는 다음과 같은 추가 이점도 있습니다. `scope` 특성 (다음 장에서 자세히 알아보겠습니다)과 함께 사용하시면 각 헤더를 동일한 행 또는 열의 모든 데이터와 연결하여 테이블에 대한 접근성을 높일 수 있습니다. 그러면 스크린 리더가 데이터의 전체 행이나 열을 한 번에 읽을 수 있으므로 매우 유용합니다.

셀이 여러 행과 열에 걸쳐 있도록 허용하기
-----------------------

셀이 여러 행이나 열에 걸쳐 있어야 할 때가 있습니다. 일반적인 동물의 이름을 보여주는 다음의 간단한 예시를 살펴보겠습니다. 어떤 경우에는 동물 이름 옆에 수컷과 암컷의 이름을 표시하고 싶을 수 있습니다. 그렇지 않은 경우도 있는데, 이런 경우 동물 이름만 전체 표에 걸쳐 표시하고 싶을 때가 있습니다.

초기 마크업은 다음과 같습니다.

```html
<table>
  <tr>
    <th>Animals</th>
  </tr>
  <tr>
    <th>Hippopotamus</th>
  </tr>
  <tr>
    <th>Horse</th>
    <td>Mare</td>
  </tr>
  <tr>
    <td>Stallion</td>
  </tr>
  <tr>
    <th>Crocodile</th>
  </tr>
  <tr>
    <th>Chicken</th>
    <td>Hen</td>
  </tr>
  <tr>
    <td>Rooster</td>
  </tr>
</table>
```

```
table {
  border-collapse: collapse;
}
td,
th {
  border: 1px solid black;
  padding: 10px 20px;
}
```

하지만 결과물은 우리가 원하는 대로 나오지 않습니다.

"Animals", "Hippopotamus", "Crocodile"은 두 열에 걸쳐, "Horse"와 "Chicken"은 두 행에 걸쳐 아래로 내려가도록 하는 방법이 필요합니다. 다행히 테이블 헤더와 셀에는 이러한 작업을 수행할 수 있는 `colspan` 및 `rowspan` 특성이 있습니다. 두 특성 모두 스팬하려는 행 또는 열의 수와 같은 단위가 없는 숫자 값을 허용합니다. 예를 들어, `colspan="2"`는 셀을 두 열에 걸쳐 표시합니다.

`colspan` 및 `rowspan`을 사용하여 이 테이블을 개선해 보겠습니다.

1. 먼저 로컬 컴퓨터의 새 디렉터리에 animals-table.html 및 minimal-table.css 파일의 로컬 복사본을 만듭니다. HTML에는 위에서 본 것과 동일한 동물 예제가 포함되어 있습니다.
2. 그런 다음 `colspan`을 사용하여 "Animals", "Hippopotamus", "Crocodile"을 두 열에 걸쳐 스팬합니다.
3. 마지막으로 `rowspan`을 사용하여 'Horse'와 'Chicken'이 두 행에 걸쳐 있도록 합니다.
4. 코드를 저장하고 브라우저에서 열어 개선 사항을 확인하세요.

**참고:** 완성된 예제는 GitHub의 animals-table-fixed.html에서 확인할 수 있습니다(라이브 버전도 참조하세요).

열에 공통 스타일 제공
------------

### <col> 없이 스타일링하기

계속 진행하기 전에 이 글에서 마지막으로 소개할 기능이 하나 더 있습니다. HTML에는 데이터 열 전체에 대한 스타일 정보를 한 곳에서 정의하는 방법, 즉 **`<col>` (en-US)** 및 **`<colgroup>` (en-US)** 요소가 있습니다. 열에 스타일을 지정하는 것이 다소 번거롭고 비효율적일 수 있기 때문에 이러한 기능이 존재합니다. 일반적으로 열의 "모든" `<td>` 또는 `<th>`에 스타일링 정보를 지정하거나 `:nth-child`와 같은 복잡한 선택기를 사용해야 합니다.

**참고:** 이와 같은 열 스타일링은 `border`, `background`, `width` 및 `visibility`와 같은 몇 가지 속성으로 제한됩니다. 다른 속성을 설정하려면 열의 모든 `<td>` 또는 `<th>`에 스타일을 지정하거나 `:nth-child`와 같은 복잡한 선택기를 사용해야 합니다.

다음의 간단한 예를 들어보겠습니다.

```html
<table>
  <tr>
    <th>Data 1</th>
    <th style="background-color: yellow">Data 2</th>
  </tr>
  <tr>
    <td>Calcutta</td>
    <td style="background-color: yellow">Orange</td>
  </tr>
  <tr>
    <td>Robots</td>
    <td style="background-color: yellow">Jazz</td>
  </tr>
</table>
```

```
table {
  border-collapse: collapse;
}
td,
th {
  border: 1px solid black;
  padding: 10px 20px;
}
```

다음과 같은 결과를 얻을 수 있습니다.

열의 세 셀 모두에 스타일링 정보를 반복해야 하므로 이상적이지 않습니다(실제 프로젝트에서는 세 셀 모두에 `class`를 설정하고 별도의 스타일시트에서 스타일링을 지정할 것입니다).

### <col>을 사용한 스타일링

이렇게 하는 대신 `<col>` 요소에 정보를 한 번에 지정할 수 있습니다. `<col>` 요소는 여는 `<table>` 태그 바로 아래의 `<colgroup>` 컨테이너 안에 지정됩니다. 다음과 같이 테이블을 지정하면 위와 동일한 효과를 낼 수 있습니다.

```html
<table>
  <colgroup>
    <col />
    <col style="background-color: yellow" />
  </colgroup>
  <tr>
    <th>Data 1</th>
    <th>Data 2</th>
  </tr>
  <tr>
    <td>Calcutta</td>
    <td>Orange</td>
  </tr>
  <tr>
    <td>Robots</td>
    <td>Jazz</td>
  </tr>
</table>
```

사실상 두 개의 "스타일 열"을 정의하고 있는데, 하나는 각 열에 대한 스타일 정보를 지정합니다. 첫 번째 열에는 스타일을 지정하지 않지만 빈 `<col>` 요소를 포함해야 합니다. 그렇지 않으면 첫 번째 열에만 스타일이 적용될 수 있습니다.

두 열 모두에 스타일링 정보를 적용하려면 다음과 같이 스팬 특성이 있는 `<col>` 요소를 하나만 포함하면 됩니다.

```html
<colgroup>
  <col style="background-color: yellow" span="2" />
</colgroup>
```

`colspan` 및 `rowspan`과 마찬가지로 `span`은 스타일을 적용할 열의 개수를 지정하는 단위가 없는 숫자 값을 받습니다.

### 활동적인 학습: colgroup과 col

이제 직접 해볼 차례입니다.

아래에서 한 언어 교사의 시간표를 볼 수 있습니다. 금요일에는 하루 종일 네덜란드어를 가르치는 새로운 수업이 있지만 화요일과 목요일에는 몇 시간 동안 독일어를 가르치기도 합니다. 그녀는 자신이 가르치는 요일이 포함된 열을 강조 표시하고 싶습니다.

아래 단계에 따라 표를 다시 만듭니다.

1. 먼저 로컬 컴퓨터의 새 디렉터리에 timetable.html 파일의 로컬 복사본을 만듭니다. HTML에는 위에서 본 것과 동일한 테이블이 열 스타일링 정보를 제외하고 포함됩니다.
2. `<table>` 태그 바로 아래의 테이블 상단에 `<colgroup>` 요소를 추가하여 `<col>` 요소를 추가할 수 있습니다(아래의 나머지 단계 참조).
3. 처음 두 열은 스타일을 지정하지 않은 상태로 두어야 합니다.
4. 세 번째 열에 배경색을 추가합니다. `style` 특성의 값은 `background-color:#97DB9A;`입니다.
5. 네 번째 열에 별도의 너비를 설정합니다. `style` 특성의 값은 `width: 42px;`입니다.
6. 다섯 번째 열에 배경색을 추가합니다. `style` 특성의 값은 `background-color: #97DB9A;`입니다.
7. 여섯 번째 열에 다른 배경색과 테두리를 추가하여 오늘이 특별한 날이고 새로운 수업을 가르친다는 것을 나타냅니다. `style` 특성의 값은 `background-color:#DCC48E; border:4px solid #C1437A;`입니다.
8. 마지막 이틀은 자유 일이므로 배경색을 사용하지 않고 너비만 설정하고 `style` 특성의 값은 `width: 42px;`로 설정하시면 됩니다.

예제를 따라 해보세요. 막히는 부분이 있거나 작업 내용을 확인하고 싶으시다면 GitHub에서 timetable-fixed.html로 버전을 확인하실 수 있습니다(라이브 버전도 참조하세요).

요약
--

이것으로 HTML 테이블의 기본 사항을 마무리했습니다. 다음 장에서는 조금 더 고급 테이블 기능을 살펴보고 시각 장애인이 테이블에 얼마나 쉽게 접근할 수 있는지 생각해 보겠습니다.

* Overview: Tables
* 다음


반응형 이미지 - Web 개발 학습하기

반응형 이미지
=======

* 이전
* Overview: Multimedia and embedding
* 다음  (en-US)

이 글에서는 화면 크기, 해상도 및 기타 기능이 매우 다양한 기기에서 잘 작동하는 이미지인 반응형 이미지의 개념에 대해 알아보고 이를 구현하는 데 도움이 되는 HTML이 제공하는 도구를 살펴봅니다. 이를 통해 다양한 기기에서 성능을 개선할 수 있습니다. 반응형 이미지는 반응형 디자인의 한 부분일 뿐이며, 향후 학습해야 할 CSS 주제입니다.

|  |  |
| --- | --- |
| 전제조건 | HTML의 기본 사항과
 웹 페이지에 정적 이미지를 추가하는 방법을 이미 알고 있어야 합니다.
  |
| 목표 | `srcset`및 `<picture>` (en-US) 요소와 같은 기능을 사용하여 웹사이트에 반응형 이미지 솔루션을 구현하는 방법을 알아보세요. |

왜 반응형 이미지를 사용해야 할까요?
--------------------

일반적인 시나리오를 살펴봅시다. 일반적인 웹사이트에는 헤더 이미지와 헤더 아래에 일부 콘텐츠 이미지가 포함될 수 있습니다. 헤더 이미지는 헤더 너비 전체에 걸쳐 있고 콘텐츠 이미지는 콘텐츠 열 안쪽 어딘가에 위치할 가능성이 높습니다. 다음은 간단한 예입니다.

![와이드 스크린 화면에서 보았을 때 예제 사이트. 여기서는 첫번째 이미지는 화면이 크기 때문에 중앙의 얼굴을 볼 수 있을 정도로 크게 보여주기 때문에 잘 작동한다.](/ko/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images/picture-element-wide.png)

노트북이나 데스크톱과 같은 와이드 스크린 장치에서 잘 작동합니다(실제 예시는 여기에 있고, Github에서 소스코드를 볼 수 있습니다.) 이 단원에서는 CSS에 대해 자세히 설명하지 않지만, 다음 내용들은 알아둡시다.

* 본문 콘텐츠는 최대 너비가 1200픽셀로 설정되어 있으며, 이 너비를 초과하는 뷰포트에서는 본문이 1200픽셀로 유지되고 사용 가능한 공간의 중앙에 배치됩니다. 이 너비보다 작은 뷰포트에서는 본문이 뷰포트 너비의 100%로 유지됩니다.
* 헤더 이미지가 설정된 너비에 관계없이 항상 헤더의 중앙에 위치하도록 설정되었습니다. 좁은 화면에서 사이트를 보는 경우 이미지 중앙의 중요한 세부 사항(사람)은 여전히 볼 수 있으며 초과분은 양쪽에서 손실됩니다. 높이는 200픽셀입니다.
* 콘텐츠 이미지는 본문 요소가 이미지보다 작아지면 이미지가 축소되기 시작하여 이미지가 넘치지 않고 항상 본문 안에 유지되도록 설정되었습니다.

하지만 화면이 좁은 기기에서 사이트를 보기 시작하면 문제가 발생합니다. 아래 헤더는 괜찮아 보이지만 모바일 기기에서 화면 높이를 많이 차지하기 시작합니다. 그리고 이 크기에서는 첫 번째 콘텐츠 이미지에서 두 사람의 얼굴을 보기가 어렵습니다.

![좁은 화면에서 예제 사이트를 보았을 때. 여기서는 첫번째 이미지가 중앙의 얼굴을 보지 힘들 정도로 줄어들었다.](/ko/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images/non-responsive-narrow.png)

좁은 화면에서 사이트를 볼 때 이미지의 중요한 세부 정보를 표시하는 이미지의 잘린 버전을 표시하는 것도 개선할 수 있습니다. 태블릿과 같은 중간 너비의 화면 장치에는 두 번째 잘린 이미지를 표시할 수 있습니다. 다양한 레이아웃에 대해 이러한 방식으로 서로 다른 자른 이미지를 제공하려는 일반적인 문제를 일반적으로 **아트 디렉션 문제(art direction problem)** 라고 합니다.

또한 모바일 화면에서 페이지를 보는 경우 페이지에 이렇게 큰 이미지를 삽입할 필요가 없습니다. 특히 모바일 사용자는 자신의 디바이스에 작은 이미지로 충분할 텐데 데스크톱 사용자용으로 큰 이미지를 다운로드하여 대역폭을 낭비하고 싶지 않을 것입니다. 반대로 작은 래스터 이미지는 원래 크기보다 크게 표시되면 거칠게 보이기 시작합니다 (래스터 이미지는 벡터 그래픽에서 보았듯이 가로와 세로가 정해진 픽셀 수로 이루어진 이미지입니다). 이상적으로는 사용자의 웹 브라우저에서 여러 해상도를 사용할 수 있어야 합니다. 그러면 브라우저는 사용자 디바이스의 화면 크기에 따라 로드할 최적의 해상도를 결정할 수 있습니다. 이를 **해상도 전환 문제(resolution wsitching problem)** 라고 합니다.

상황을 더 복잡하게 생각하자면, 일부 기기에는 이미지를 제대로 보여주기 위해 예상보다 더 고해상도의 이미지가 필요한 고해상도 화면도 있습니다. 이것은 본질적으로 동일한 문제이지만 약간 다른 맥락에서 발생합니다.

벡터 이미지가 이러한 문제를 해결해 줄 것이라고 생각할 수도 있고, 실제로 어느 정도는 파일 크기가 작고 크기가 잘 조정되므로 가능한 한 벡터 이미지를 사용하는 것이 좋습니다. 하지만 모든 이미지 유형에 적합한 것은 아닙니다. 벡터 이미지는 단순한 그래픽, 패턴, 인터페이스 요소 등에는 적합하지만 사진에서 볼 수 있는 디테일이 있는 벡터 기반 이미지를 만들려면 매우 복잡해집니다. JPEG와 같은 래스터 이미지 형식은 위의 예시에서 볼 수 있는 종류의 이미지에 더 적합합니다.

웹이 처음 등장한 90년대 초중반에는 이러한 문제가 존재하지 않았습니다. 당시에는 웹을 탐색할 수 있는 기기가 데스크톱과 노트북뿐이었기 때문에 브라우저 엔지니어와 사양 작성자는 해결책을 구현할 생각조차 하지 못했죠. 반응형 이미지 기술은 위에서 언급한 문제를 해결하기 위해 최근에 구현된 기술로, 동일한 내용을 표시하지만 픽셀 수가 다른 여러 이미지 파일을 브라우저에 제공하거나(해상도 전환), 공간 할당에 적합한 다른 이미지를 제공(아트 디렉션)할 수 있도록 합니다.

**참고:** 이 문서에서 설명하는 새로운 기능인 srcset/sizes/`<picture>` (en-US) 은 최신 데스크톱 및 모바일 브라우저에서 모두 지원됩니다.

반응형 이미지를 어떻게 만드나요?
------------------

이 섹션에서는 위에 예시된 두 가지 문제를 살펴보고 HTML의 반응형 이미지 기능을 사용하여 해결하는 방법을 보여드리겠습니다. 이 섹션에서는 위 예시의 콘텐츠 영역에서 볼 수 있듯이 사이트 헤더의 이미지는 장식용이므로 CSS 배경 이미지를 사용하여 구현된 `<img>` 요소에 초점을 맞출 것입니다. CSS에는 HTML보다 반응형 디자인을 위한 더 나은 도구가 있으며, 이에 대해서는 향후 CSS 모듈에서 다룰 예정입니다.

### 해상도 전환: 다양한 크기

그렇다면 해상도 전환을 통해 해결하고자 하는 문제는 무엇일까요? 동일한 이미지 콘텐츠를 기기에 따라 더 크게 또는 더 작게 표시하고 싶을 때, 예시의 두 번째 콘텐츠 이미지가 이러한 상황입니다. 표준 `<img>` 요소는 일반적으로 브라우저에서 단일 소스 파일만 가리킬 수 있습니다.

```html
<img src="elva-fairy-800w.jpg" alt="요정 옷을 입은 엘바" />
```

그러나 두 가지 속성(`srcset` 및 `sizes`)을 사용하여 브라우저가 올바른 이미지를 선택하는 데 도움이 되는 힌트와 함께 여러 개의 추가 소스 이미지를 제공할 수 있습니다. 이에 대한 예제는 GitHub의 responsive.html 예제에서 확인할 수 있습니다(소스 코드 참조).

```html
<img
 srcset="elva-fairy-480w.jpg 480w, elva-fairy-800w.jpg 800w"
 sizes="(max-width: 600px) 480px,
 800px"
 src="elva-fairy-800w.jpg"
 alt="요정 옷을 입은 엘바" />
```

`srcset` 및 `sizes` 속성은 복잡해 보이지만 위와 같이 각 줄에 속성 값의 다른 부분을 사용하여 형식을 지정하면 이해하기가 그리 어렵지 않습니다. 각 값은 쉼표로 구분된 목록을 포함하며, 각 목록의 각 부분은 세 개의 하위 부분으로 구성됩니다. 이제 각각의 내용을 살펴보겠습니다.

**`srcset`** 은 브라우저에서 선택할 수 있는 이미지 세트와 각 이미지의 크기를 정의합니다. 각 이미지 정보 세트는 쉼표로 이전 이미지와 구분됩니다. 각각에 대해 다음과 같이 작성합니다.

1. **이미지 파일 이름** (`elva-fairy-480w.jpg`.)
2. 공백
3. 이미지의 **고유 픽셀 너비** (`480w`). 예상하는 것처럼 `px` 단위가 아닌 `w` 단위를 사용한다는 점에 유의하세요. 이미지의 고유 크기는 컴퓨터에서 이미지 파일을 검사하여 확인할 수 있는 실제 크기입니다. 예를 들어 Mac의 경우 Finder에서 이미지를 선택한 다음 `Cmd` + `I` 를 눌러 정보 화면을 불러올 수 있습니다.

**`sizes`** 는 일련의 미디어 조건(예: 화면 너비)을 정의하고 특정 미디어 조건에 해당할 때 어떤 이미지 크기를 선택하는 것이 가장 좋을지 알려주는데, 이는 앞서 설명한 힌트입니다. 이 경우 각 쉼표 앞에 다음과 같이 작성합니다.

1. **미디어 조건** (`(max-width:600px)`). 이에 대한 자세한 내용은 CSS 주제에서 배우겠지만, 지금은 미디어 조건이 화면이 될 수 있는 가능한 상태를 설명한다고 가정해 보겠습니다. 이 경우 "뷰포트 너비가 600픽셀 이하일 때"라고 말합니다.
2. 공백
3. 미디어 조건이 참(`480px`)일 때 이미지가 채울 **슬롯의 너비**입니다.

**참고:** 슬롯 너비의 경우 절대 너비(예: `480px`)를 제공하는 대신 뷰포트에 대한 상대 너비(예: `50vw`)를 제공할 수 있지만 백분율은 제공하지 않습니다. 마지막 슬롯 너비에 미디어 조건이 없는 것을 보셨을 것입니다(미디어 조건이 모두 참일 때 선택되는 기본값입니다). 브라우저는 첫 번째 일치하는 조건 이후의 모든 것을 무시하므로 미디어 조건 순서에 주의해야 합니다.

따라서 이러한 속성을 설정하면 브라우저는 다음과 같이 작동합니다.

1. 기기 너비를 확인합니다.
2. `sizes` 목록에서 어떤 미디어 조건이 가장 먼저 참인지 알아냅니다.
3. 해당 미디어 쿼리에 지정된 슬롯 크기를 확인합니다.
4. 슬롯과 크기가 같은 `srcset` 목록에 참조된 이미지 또는 이미지가 없는 경우 선택한 슬롯 크기보다 큰 첫 번째 이미지를 로드합니다.

이제 끝입니다! 이 시점에서 뷰포트 너비가 480px인 지원 브라우저가 페이지를 로드하면 `(max-width: 600px)` 미디어 조건이 참이 되므로 브라우저는 `480px` 슬롯을 선택합니다. 고유의 너비(`480w`)가 슬롯 크기에 가장 가깝기 때문에 `elva-fairy-480w.jpg`가 로드됩니다. 800px 사진은 디스크에서 128KB인 반면 480px 버전은 63KB에 불과하므로 65KB를 절약할 수 있습니다. 이제 이 페이지에 많은 사진이 있다고 상상해 보세요. 이 기술을 사용하면 모바일 사용자의 대역폭을 크게 절약할 수 있습니다.

**참고:** 데스크톱 브라우저에서 테스트할 때 창 너비를 가장 좁게 설정했는데도 브라우저에서 더 좁은 이미지를 로드하지 못하면 뷰포트의 크기를 살펴보세요. 브라우저의 JavaScript 콘솔로 이동하여 `document.querySelector('html').clientWidth`를 입력하면 대략적인 크기를 알 수 있습니다. 브라우저마다 창 너비를 줄일 수 있는 최소 크기가 있으며, 생각보다 더 넓을 수도 있습니다. 모바일 브라우저로 테스트할 때는 Firefox의 `about:debugging` 페이지와 같은 도구를 사용하여 데스크톱 개발자 도구를 사용하여 모바일에 로드된 페이지를 검사할 수 있습니다.

어떤 이미지가 로드되었는지 확인하려면 Firefox 개발자 도구의 네트워크 모니터 탭 또는 Chrome 개발자 도구의 네트워크 패널을 사용하면 됩니다. Chrome의 경우 캐시를 비활성화하여 이미 다운로드한 이미지를 선택하지 못하도록 할 수도 있습니다.

이러한 기능을 지원하지 않는 구형 브라우저는 이를 무시합니다. 대신 해당 브라우저는 `src` 속성에 참조된 이미지를 정상적으로 로드합니다.

**참고:** 위에 링크된 예제의 `<head>`에 `<meta name="viewport" content="width=device-width">`라는 줄이 있는데, 이는 모바일 브라우저가 웹 페이지를 로드할 때 실제 뷰포트 너비를 적용하도록 합니다. 일부 모바일 브라우저는 뷰포트 너비를 속이고 더 큰 뷰포트 너비로 페이지를 로드한 다음 로드한 페이지를 축소하므로 반응형 이미지나 디자인에 도움이 되지 않습니다.

### 해상도 전환: 동일한 크기, 다른 해상도

여러 디스플레이 해상도를 지원하지만 모든 사람이 화면에서 동일한 실제 크기로 이미지를 보는 경우, 다소 쉬운 구문인 X-서술자 `sizes` 없이 `srcset`을 사용하여 브라우저가 적절한 해상도 이미지를 선택하도록 할 수 있습니다! srcset-resolutions.html에서 그 예시를 확인할 수 있습니다(소스 코드 참조).

```html
<img
 srcset="elva-fairy-320w.jpg, elva-fairy-480w.jpg 1.5x, elva-fairy-640w.jpg 2x"
 src="elva-fairy-640w.jpg"
 alt="요정 옷을 입은 엘바" />
```

![A picture of a little girl dressed up as a fairy, with an old camera film effect applied to the image](/ko/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images/resolution-example.png)

이 예제에서는 이미지에 다음 CSS를 적용하여 화면 너비가 320픽셀(CSS 픽셀이라고도 합니다)이 되도록 합니다.

```css
img {
  width: 320px;
}
```

이 경우 `sizes`는 필요하지 않습니다. 브라우저는 표시되는 디스플레이의 해상도를 파악하여 `srcset`에 참조된 가장 적합한 이미지를 제공합니다. 따라서 페이지에 액세스하는 디바이스의 디스플레이 해상도가 표준/저해상도이고 각 CSS 픽셀당 디바이스 픽셀이 1개인 경우 `elva-fairy-320w.jpg` 이미지가 로드됩니다. 1x는 암시적이므로 포함할 필요가 없습니다. 디바이스의 해상도가 CSS 픽셀당 디바이스 픽셀이 2개 이상인 고해상도인 경우 `elva-fairy-640w.jpg` 이미지가 로드됩니다. 640픽셀 이미지는 93KB인 반면 320픽셀 이미지는 39KB에 불과합니다.

### 아트 디렉션

요약하자면, **아트 디렉션 문제**는 다양한 이미지 디스플레이 크기에 맞게 표시되는 이미지를 변경하려는 경우입니다. 예를 들어, 데스크톱 브라우저에서 볼 때 웹 페이지에 사람이 가운데에 있는 큰 풍경 사진이 포함되어 있다고 가정해 보겠습니다. 모바일 브라우저에서 볼 때는 동일한 이미지가 축소되어 이미지 속 사람이 매우 작아지고 잘 보이지 않습니다. 모바일에서는 인물을 확대하여 더 작은 세로형 이미지를 표시하는 것이 더 좋을 것입니다. `<picture>` (en-US) 요소를 사용하면 이러한 종류의 솔루션을 구현할 수 있습니다.

원래의 not-responsive.html 예제로 돌아가서 아트 디렉션이 절실히 필요한 이미지가 있습니다.

```html
<img src="elva-800w.jpg" alt="딸 엘바를 안고 서 있는 크리스" />
```

`<picture>` (en-US)으로 해결해 봅시다! `<video>` 및 `<audio>` (en-US)와 마찬가지로 `<picture>` 요소는 브라우저가 선택할 수 있는 다양한 소스를 제공하는 여러 `<source>` (en-US) 요소를 포함하는 래퍼이며, 그 뒤에 가장 중요한 `<img>` 요소가 있습니다. responsive.html의 코드는 다음과 같습니다.

```html
<picture>
  <source media="(max-width: 799px)" srcset="elva-480w-close-portrait.jpg" />
  <source media="(min-width: 800px)" srcset="elva-800w.jpg" />
  <img src="elva-800w.jpg" alt="딸 엘바를 안고 서 있는 크리스" />
</picture>
```

* `<source>` 요소에는 미디어 조건이 포함된 `media` 속성이 포함되어 있습니다. 첫 번째 `srcset` 예제와 마찬가지로 이러한 조건은 표시할 이미지를 결정하는 테스트이며, 참을 반환하는 첫 번째 이미지가 표시됩니다. 이 경우 뷰포트 너비가 799px 이하인 경우 첫 번째 `<source>` 요소의 이미지가 표시됩니다. 뷰포트 너비가 800px 이상이면 두 번째 이미지가 표시됩니다.
* `srcset` 속성에는 표시할 이미지의 경로가 포함됩니다. 위의 `<img>`에서 살펴본 것처럼, `<source>`는 여러 이미지가 참조된 `srcset` 속성과 `sizes` 속성을 사용할 수 있습니다. 따라서 `<picture>` 요소를 통해 여러 이미지를 제공하면서 각 이미지의 해상도도 여러 개 제공할 수 있습니다. 현실적으로 이런 종류의 작업을 자주 수행하지는 않을 것입니다.
* 모든 경우에 `</picture>` 바로 앞에 `src` 및 `alt`와 함께 `<img>` 요소를 제공해야 하며, 그렇지 않으면 이미지가 표시되지 않습니다. 이는 미디어 조건 중 어느 것도 참을 반환하지 않을 때 적용되는 기본 사례와 `<picture>` 요소를 지원하지 않는 브라우저를 위한 폴백을 제공합니다. 이 예제에서는 실제로 두 번째 `<source>` 요소를 제거할 수 있습니다.

이 코드를 사용하면 아래와 같이 와이드 스크린과 좁은 스크린 디스플레이 모두에 적합한 이미지를 표시할 수 있습니다.

![Our example site as viewed on a wide screen - here the first image works ok, as it is big enough to see the detail in the center.](/ko/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images/picture-element-wide.png)
![Our example site as viewed on a narrow screen with the picture element used to switch the first image to a portrait close up of the detail, making it a lot more useful on a narrow screen](/ko/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images/picture-element-narrow.png)

**참고:** `media` 속성은 아트 디렉션 시나리오에서만 사용해야 하며, `media`를 사용하는 경우 `sizes` 속성 내에 미디어 조건도 제공하지 마세요.

### CSS나 JavaScript를 사용하면 안 되는 이유는 무엇인가요?

브라우저가 페이지 로드를 시작하면 기본 구문 분석기가 페이지의 CSS와 JavaScript를 로드하고 해석하기 전에 이미지를 다운로드(사전 로드)하기 시작합니다. 이 메커니즘은 일반적으로 페이지 로드 시간을 단축하는 데 유용하지만 반응형 이미지에는 도움이 되지 않으므로 `srcset`과 같은 솔루션을 구현해야 합니다. 예를 들어, `<img>` 요소를 로드한 다음 JavaScript를 사용하여 뷰포트 너비를 감지한 다음 원하는 경우 소스 이미지를 더 작은 이미지로 동적으로 변경할 수 없습니다. 그러면 원본 이미지가 이미 로드되어 작은 이미지도 함께 로드되므로 반응형 이미지 측면에서 더욱 좋지 않습니다.

능동적 학습: 나만의 반응형 이미지 구현하기
------------------------

능동적인 학습을 위해서는 대부분 혼자서 용기를 내서 해보시기 바랍니다. `<picture>`을 사용하여 자신만의 적절한 아트 연출이 가능한 좁은 화면/넓은 화면 스크린샷을 구현해 보시고, `srcset`을 사용한 해상도 전환 예제도 구현해 보시기 바랍니다.

1. 코드를 포함할 간단한 HTML을 작성합니다. 원하는 경우 `not-responsive.html`을 시작점으로 사용합니다.
2. 어딘가에 디테일이 포함된 멋진 와이드 스크린 풍경 이미지를 찾습니다. 그래픽 편집기를 사용하여 웹 크기 버전을 만든 다음 세부 사항을 확대하여 더 작은 부분을 표시하도록 자르고 두 번째 이미지를 만듭니다. 약 480px 너비가 적당합니다.
3. `<picture>` 요소를 사용하여 아트 디렉션 사진 전환기를 구현하세요!
4. 크기가 다른 여러 개의 이미지 파일을 만들어 각각 동일한 사진을 표시합니다.
5. 장치 해상도에 따라 동일한 크기의 이미지를 다른 해상도로 제공하거나 뷰포트 너비에 따라 다른 이미지 크기를 제공하는 해상도 전환기 예제를 만들려면 `srcset`/`sizes`를 사용하세요.
요약
--

여기까지 반응형 이미지에 대해 알아보았습니다. 새로운 기술을 사용해 보셨기를 바랍니다. 요약하자면, 여기서 논의한 문제는 크게 두 가지입니다.

* **아트 디렉션**: 데스크톱 레이아웃에는 전체 장면을 보여주는 가로 이미지를, 모바일 레이아웃에는 주요 피사체를 확대하여 보여주는 세로 이미지를 제공하는 등 다양한 레이아웃에 맞게 잘린 이미지를 제공하려는 경우 문제가 발생할 수 있습니다. 이 문제는 `<picture>` (en-US) 요소를 사용하여 해결할 수 있습니다.
* **해상도 전환**: 데스크톱 디스플레이처럼 큰 이미지가 필요하지 않은 좁은 화면 기기에는 작은 이미지 파일을 제공하고, 고밀도/저밀도 화면에는 서로 다른 해상도의 이미지를 제공하려는 경우 문제가 발생할 수 있습니다. `벡터 그래픽`(SVG 이미지)과 `sizes` 속성이 있는 `srcset`을 사용하여 이 문제를 해결할 수 있습니다.

이것으로 멀티미디어 및 임베딩 모듈 전체가 끝났습니다! 이제 다음 단계로 넘어가기 전에 해야 할 일은 멀티미디어 및 임베딩 평가 (en-US)에 도전해보고 여러분의 실력을 확인하는 것입니다. 즐거운 시간 보내세요!

같이 보기
-----

* 제이슨 그릭스비의 반응형 이미지에 대한 훌륭한 소개
* 반응형 이미지: 해상도를 변경하는 경우에는, srcset을 사용하세요. 브라우저가 어떤 이미지를 사용할지 고르는 방법에 대한 더 상세한 설명이 포함되어 있습니다.
* `<img>`
* `<picture>` (en-US)
* `<source>` (en-US)
* 이전
* Overview: Multimedia and embedding
* 다음  (en-US)