본문으로 건너뛰기

요소 안의 요소

HTML·CSS 목차글을 담는 태그레슨 8 / 93

목차

요소 안에는 다른 요소를 넣을 수 있습니다. 바로 감싼 요소를 부모, 바로 안에 든 요소를 자식이라고 부르고, 나중에 연 요소를 먼저 닫아 안쪽부터 차례로 닫습니다. 닫는 차례가 엇갈리면 브라우저는 오류를 내지 않고 나무를 고쳐 짓습니다.

문장 속 한 낱말만 굵게 하거나 목록 안에 목록을 넣으려면 요소 안에 요소를 넣어야 합니다. 이때 닫는 차례를 틀려도 화면에는 오류 메시지가 뜨지 않습니다. 브라우저가 제 규칙대로 나무를 고쳐 짓고 그대로 그려서, 글 일부가 엉뚱한 자리로 옮겨 가도 알려 주지 않습니다. 이 레슨에서는 요소가 겹겹이 드는 차례, 부모와 자식, 엇갈린 태그와 닫는 태그가 빠진 줄을 브라우저가 어떻게 고쳐 짓는지 봅니다.

5단계 중 1단계. 1번 줄: p를 열고, p가 열린 채로 strong을 엽니다. strong은 p의 자식입니다.

1나중에 연 요소를 먼저 닫는다

<p><strong>김치</strong>볶음밥</p>
결과 화면
잰 값개발자 도구에서 본 값
  • p의 나무<strong>김치</strong>볶음밥
  • strong의 font-weight700

strong은 중요한 글을 표시하는 요소로, 굵게 그려집니다. 뜻은 문단과 강조에서 자세히 봅니다. 브라우저는 이 줄을 왼쪽부터 읽으며 나무를 짓습니다.

  1. <p>에서 p를 엽니다.
  2. <strong>에서 p 안에 strong을 엽니다.
  3. '김치'를 strong 안에 넣고, </strong>에서 strong을 닫습니다.
  4. '볶음밥'은 아직 열려 있는 p 안에 넣고, </p>에서 p를 닫습니다.

나중에 연 strong을 먼저 닫았습니다. 안쪽 요소를 닫은 뒤에 바깥 요소를 닫으면, 요소들이 서로 엇갈리지 않고 겹겹이 듭니다.

2부모 · 자식 · 조상

<p>
  <strong>김치</strong>를 먼저 볶고
  <em>밥</em>을 넣습니다.
</p>
결과 화면
잰 값개발자 도구에서 본 값
  • p의 보이는 글김치를 먼저 볶고 밥을 넣습니다.

em은 힘주어 읽을 곳을 표시하는 요소로, 기울여 그려집니다. strong과 em을 바로 감싼 요소는 p입니다. 바로 감싼 요소를 부모(parent), 바로 안에 든 요소를 자식(child)이라고 부릅니다.

요소부모자식
pbodystrong · em
strongp없음(글 '김치'만)
emp없음(글 '밥'만)

결과 화면의 페이지에서 이 p는 body 안에, body는 html 안에 듭니다(문서 뼈대). body와 html도 strong을 감싸고 있지만 부모가 아닙니다. 몇 겹 바깥이든 감싸고 있는 요소는 조상(ancestor)이라고 하고, 부모는 바로 감싼 요소 하나뿐입니다. 2~3번 줄을 두 칸 들여 쓴 것은 사람이 안에 든 차례를 한눈에 보게 한 것입니다. 나무를 짓는 것은 태그입니다. 줄을 바꾼 자리가 화면에서 빈칸 하나가 되는 까닭은 공백 규칙과 특수 문자에서 봅니다.

3엇갈린 태그는 고쳐 짓는다

<p><strong>김치</p>볶음밥</strong>
결과 화면
잰 값개발자 도구에서 본 값
  • body의 나무<p><strong>김치</strong></p><strong>볶음밥</strong>

1절의 줄에서 </strong>과 </p>의 차례만 바꿨습니다. strong이 아직 열려 있는데 </p>가 먼저 왔습니다. 브라우저는 오류를 내지 않습니다. </p>에서 안의 strong까지 함께 닫고, 남은 '볶음밥'을 새 strong으로 다시 감쌌습니다. 새 strong은 문단 밖에 있어, '볶음밥'이 다음 줄로 떨어졌습니다.

브라우저 규칙 2. 틀린 태그도 오류 없이 고쳐 나무를 짓습니다. 화면은 고쳐 지은 나무로 그립니다.

엇갈린 태그 뒤에 글이 없으면 고친 나무가 바른 코드의 나무와 같아져, 틀린 줄도 모르고 지나갑니다.

<p><strong>김치볶음밥</p></strong>
결과 화면
잰 값개발자 도구에서 본 값
  • body의 나무<p><strong>김치볶음밥</strong></p>

4닫는 태그가 없으면 저절로 닫힌다

<p>밥 2공기
<p>김치 1컵
결과 화면
잰 값개발자 도구에서 본 값
  • body의 나무<p>밥 2공기 </p><p>김치 1컵</p>

두 줄 모두 </p>가 없습니다. 브라우저는 다음 문단 <p>가 시작되는 자리에서 앞 문단을 저절로 닫아, 문단 둘을 지었습니다. 잰 값의 나무에서 '2공기' 뒤 빈칸은 줄바꿈이 글로 남은 것입니다. 목록의 한 줄 li도 다음 li가 시작되면 저절로 닫힙니다. 그래도 이 과목은 닫는 태그를 빼지 않습니다. 어디서 닫히는지 코드만 보고 알 수 있게 하려는 것입니다.

예제

조리 순서 두 줄을 문단으로 썼습니다. 줄마다 em의 부모가 무엇인지 짚어 보고, 화면에 몇 줄로 보일지 먼저 적어 본 뒤 결과 화면을 펴 보세요.

<p><em>먼저</em> 김치를 볶기</p>
<p>그다음 <em>밥</em>을 넣기</p>
결과 화면 보기
결과 화면
잰 값개발자 도구에서 본 값
  • body의 나무<p><em>먼저</em> 김치를 볶기</p><p>그다음 <em>밥</em>을 넣기</p>
  • body의 보이는 글먼저 김치를 볶기 / 그다음 밥을 넣기

두 줄입니다. 두 em의 부모는 저마다 제 줄의 p이고, em은 p가 닫히기 전에 닫혀 문단 안에 머뭅니다. '먼저'와 '밥'만 기울여 그려지고, 나머지 글은 p에 바로 든 글이라 보통 글자입니다.

자주 틀리는 곳

틀린 생각: 태그가 틀리면 브라우저가 오류를 내거나 화면을 그리지 않는다.

프로그램은 틀리면 멈춘다고 배웠으니, HTML도 틀린 곳에서 멈출 것 같습니다. 브라우저는 멈추지 않습니다.

<p><strong>김치</p>
<p>밥 2공기</p>
결과 화면
잰 값개발자 도구에서 본 값
  • body의 나무<p><strong>김치</strong></p><strong><p>밥 2공기</p></strong>

strong을 닫지 않았습니다. 브라우저는 첫 </p>에서 strong을 함께 닫은 뒤, 닫지 않은 strong을 다시 열어 아래 문단까지 감쌌습니다. 그래서 '밥 2공기'도 굵게 그려지고, 오류 메시지는 없습니다.

맞는 규칙: HTML은 틀려도 멈추지 않습니다. 브라우저는 틀린 태그도 오류 없이 고쳐 나무를 짓고, 그 나무로 그립니다(브라우저 규칙 2). 화면이 이상하면 닫는 태그와 그 차례부터 봅니다.

틀린 생각: 문단 안에 문단을 넣을 수 있다.

strong을 p 안에 넣듯, 문단 안에도 작은 문단을 넣을 수 있을 것 같습니다.

<p>가<p>나</p>다</p>
결과 화면
잰 값개발자 도구에서 본 값
  • body의 나무<p>가</p><p>나</p>다<p></p>
  • body의 보이는 글가 / 나 / 다

브라우저는 둘째 <p>에서 첫 문단을 닫았습니다. 그래서 문단은 안에 들지 않고 나란히 섰고, '다'는 문단 밖 글이 됐습니다. 끝의 </p>는 짝이 없어 빈 문단 하나가 생겼습니다.

맞는 규칙: p 안에는 문단을 넣을 수 없습니다. 새 p가 시작되면 앞 문단이 저절로 닫힙니다(브라우저 규칙 2). 문단 둘은 <p>…</p> 둘을 나란히 씁니다.

틀린 생각: 부모와 조상은 같은 말이다.

밖에서 감싸고 있으면 모두 부모처럼 보입니다.

<p>재료: <em>김치</em></p>
결과 화면

em을 감싼 요소는 p · body · html 셋이지만, 부모는 바로 감싼 p 하나입니다. body와 html은 em의 조상입니다. html은 문서의 모든 요소의 조상이지만, 부모인 것은 head · body 둘뿐입니다.

맞는 규칙: 부모는 바로 감싼 요소 하나이고, 그보다 바깥에서 감싼 요소는 모두 조상입니다. 자식도 바로 안에 든 요소만 가리킵니다.

틀린 생각: 편집기가 붙여 준 닫는 태그는 늘 맞는 자리에 있다.

VS Code는 여는 태그의 끝 꺾쇠 >를 치면 닫는 태그를 바로 뒤에 붙여 줍니다. 이미 쓴 글 앞에 여는 태그를 넣으면, 닫는 태그가 글 앞에 붙습니다.

<p><strong></strong>김치 1컵</p>
결과 화면
잰 값개발자 도구에서 본 값
  • p의 나무<strong></strong>김치 1컵

strong이 비어 있어 굵게 그려지는 글이 없습니다. 오류 메시지도 없습니다.

맞는 규칙: 편집기가 붙여 준 닫는 태그도 내가 감싸려던 글 뒤로 옮겨야 합니다. 여는 태그와 닫는 태그 사이에 무엇이 들었는지 보고 저장합니다.

확인 문제

1. 예제 1번 줄에서 </em>과 </p>의 차례를 바꾸면, '김치를 볶기'는 화면 어디에 그려질까요?

<p><em>먼저</em> 김치를 볶기</p>
<p>그다음 <em>밥</em>을 넣기</p>
결과 화면
  • ① 첫 문단 안, '먼저' 바로 뒤에 이어서 그려진다
  • ② 첫 문단 밖 새 줄에, 기울인 글로 그려진다
  • ③ 그려지지 않는다
힌트

</p>가 올 때 아직 닫히지 않은 요소가 무엇인지 보고, 그다음에 오는 글이 어느 요소 안에 들지 생각합니다.

정답

② — 첫 문단 밖 새 줄에, 기울인 글로 그려집니다. 차례를 바꾼 코드와 그 결과 화면입니다.

<p><em>먼저</p> 김치를 볶기</em>
<p>그다음 <em>밥</em>을 넣기</p>
결과 화면
잰 값개발자 도구에서 본 값
  • body의 나무<p><em>먼저</em></p><em> 김치를 볶기</em><p>그다음 <em>밥</em>을 넣기</p>
  • body의 보이는 글먼저 / 김치를 볶기 / 그다음 밥을 넣기
  • </p>가 em보다 먼저 와서, 브라우저는 p를 닫으며 안의 em도 함께 닫았습니다. 남은 '김치를 볶기'는 새 em으로 다시 감싸 문단 밖에 두었습니다(브라우저 규칙 2).
  • ①은 브라우저가 친 사람의 뜻을 짐작해 바르게 고친다고 본 것입니다. 브라우저는 정해진 규칙대로만 고쳐 짓습니다.
  • ③은 틀린 태그가 있으면 그리지 않는다고 본 것입니다(틀리면 멈춘다는 생각).

1번 줄의 </em>과 </p>의 차례를 바꿔 보세요. '김치를 볶기'를 보세요.

2. '꼭 볶기'를 strong과 em으로 함께 감쌌습니다. ____ 자리에 닫는 태그 </p> · </strong> · </em>을 바른 차례로 이어 쓰세요.

<p><strong><em>꼭 볶기____
힌트

세 여는 태그가 열린 차례를 먼저 적어 봅니다.

힌트 둘

여는 태그를 연 차례를 거꾸로 따라갑니다.

정답

</em></strong></p> — 나중에 연 요소부터 닫습니다. 줄을 나눠 들여 쓰면 안에 든 차례가 보입니다(한 줄로 이어 쓴 것과 같은 나무).

<p>
  <strong>
    <em>꼭 볶기</em>
  </strong>
</p>
결과 화면
잰 값개발자 도구에서 본 값
  • p의 나무<strong><em>꼭 볶기</em></strong>

em이 strong 안에, strong이 p 안에 듭니다. </strong></em></p>처럼 차례를 바꾸면 브라우저가 엇갈린 태그로 보고 나무를 고쳐 짓습니다.

3. 여행 일정의 한 문단입니다. em의 부모는 무엇인가요? 그리고 strong의 자식 요소는 몇 개인가요?

<p>
  1일: <strong>경주</strong>의
  <em>불국사</em> 걷기
</p>
힌트

em의 바로 앞 줄이 아니라, em을 바로 감싼 여는 태그와 닫는 태그 짝을 찾습니다.

정답

em의 부모는 p이고, strong의 자식 요소는 0개입니다(strong 안에는 글 '경주'만 있습니다).

결과 화면
잰 값개발자 도구에서 본 값
  • p의 나무1일: <strong>경주</strong>의 <em>불국사</em> 걷기
  • strong은 2번 줄에서 이미 닫혔습니다. 그래서 3번 줄의 em은 strong 밖, p 바로 안에 듭니다. strong과 em은 같은 p의 자식입니다.
  • 흔한 오답은 em의 부모를 strong으로 쓴 답입니다. 바로 위 줄에 있는 요소가 부모라고 본 것입니다. 부모는 줄의 차례가 아니라 여는 태그 · 닫는 태그의 짝으로 정해집니다.

컴퓨터에서 해 보기(선택) — 점수에 들지 않습니다. 폰으로만 보고 있다면 건너뛰세요. 1절 코드를 hello.html의 body 안에 붙여 저장하고 엽니다. 그다음 </strong>과 </p>의 자리를 바꿔 저장 · 새로고침하고, 개발자 도구 Elements 패널에서 브라우저가 고쳐 지은 나무를 찾아봅니다. 개발자 도구를 여는 법은 개발자 도구로 요소 나무 보기에 있습니다.

끝까지 내려오면 저절로 표시됩니다. 이 기기에만 저장합니다.

HTML·CSS 목차로