이번 편의 결과물: 세 페이지의 html 태그에 lang이 지정되고, 뒤 과목(CSS·JS)이 훅으로 쓸 id/data-*가 정리됩니다. · 다루는 개념: id/class, lang/dir, hidden, data-*
이 편에서 만드는 파일
web-practice/portfolio/
├ index.html ~ (html lang, 섹션 id, data-* 추가)
├ projects.html ~ (html lang, 카드 data-project-id 추가)
└ contact.html ~ (html lang, 폼 영역 id 추가)개념 정리
전역 속성(global attribute)은 어떤 요소에든 붙일 수 있는 속성입니다. 지금까지 href(a 전용)·src(img 전용)처럼 요소마다 정해진 속성을 써 왔다면, 전역 속성은 div든 button이든 table이든 똑같이 붙습니다.
| 속성 | 역할 | 값 |
|---|---|---|
id | 문서 안에서 유일한 식별자. 앵커 링크·label 연결·CSS/JS 훅 | 문서 전체에서 중복 금지 |
class | 같은 스타일·동작을 묶는 이름표. 중복 허용 | 공백으로 여러 개 나열 가능 |
lang | 콘텐츠의 자연어. 스크린 리더 발음, 검색 엔진 판단에 사용 | ko, en 등 BCP 47 언어 코드 |
dir | 텍스트 방향 | ltr(기본) | rtl |
hidden | 렌더링에서 완전히 제외 | 불리언(속성 존재 자체가 참) |
data-* | 표준에 없는 커스텀 데이터를 요소에 저장 | data-project-id처럼 자유 명명 |
id와 class의 차이는 “몇 번 쓰이는가” 로 구분합니다. id="main-nav"처럼 페이지에 하나뿐인 대상은 id, class="tag"처럼 여러 요소에 반복되는 스타일 단위는 class입니다. 지금까지 05편의 <nav>, 07편의 표에도 class를 미리 붙여 두었다면 이 편에서 CSS 과목이 그대로 이어받습니다.
lang은 html 요소에 한 번 지정하면 문서 전체에 적용됩니다. 스크린 리더는 lang="ko"를 보고 한국어 발음 규칙으로 읽습니다. lang 없이 방치하면 스크린 리더가 기본 언어(대개 영어) 규칙으로 한국어 텍스트를 잘못 읽습니다.
data-*는 표준 속성이 없는 정보를 요소에 붙일 때 씁니다. 예를 들어 프로젝트 카드마다 고유 번호를 붙여 두면, 나중에 JavaScript가 querySelector('[data-project-id="3"]')로 정확히 찾아낼 수 있습니다. data- 뒤에는 원하는 이름을 자유롭게 붙이되, 하이픈으로 이어 쓰는 케밥 표기(data-project-id)가 관례입니다.
자주 하는 오해: class를 스타일 전용으로만 생각하기 쉽지만, JavaScript가 요소를 선택하는 훅으로도 씁니다. 이 과목에서는 CSS·JS 과목이 이어받을 것을 고려해 의미가 드러나는 이름(project-card, contact-form)을 붙입니다.
실습
1. 세 파일의 html 태그에 lang 지정하기
index.html·projects.html·contact.html 세 파일의 최상단 <html> 태그를 확인합니다. 02편에서 뼈대를 만들 때 이미 lang="ko"를 넣었다면 그대로 두고, 빠졌다면 지금 추가합니다.
<!-- index.html (상단 일부) -->
<!doctype html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<title>Zeno Kim — 소개</title>
</head>
<body>
...
</body>
</html>2. index.html에 섹션 id와 data-* 추가하기
지금까지 만든 히어로·소개·기술 스택·경력 섹션에 id를 붙입니다. 이 id는 05편의 페이지 내 이동 링크나 뒤 과목의 CSS 선택자로 쓰입니다.
<!-- index.html (main 내부 일부) -->
<main>
<section class="hero" id="hero">
<h1>웹을 만드는 개발자, Zeno Kim입니다.</h1>
<p>HTML·CSS·JavaScript로 누구나 쓸 수 있는 화면을 만듭니다.</p>
<a class="button" href="projects.html">프로젝트 보기</a>
<a class="button" href="contact.html">연락하기</a>
</section>
<section class="about" id="about">
<h2>소개</h2>
<img src="images/profile.svg" alt="Zeno Kim의 프로필 사진" width="400" height="400" />
<p>저는 3년째 프론트엔드를 공부하고 만들고 있습니다. 화면이 예뻐 보이는 것보다 <strong>누가 봐도 쓸 수 있는가</strong>를 먼저 생각합니다.</p>
<p>처음에는 디자인 툴로 화면을 그리다가, 직접 만들어 보고 싶어서 HTML과 CSS를 배웠습니다. 지금은 React로 서비스 화면을 만들고 있습니다.</p>
<p>접근성과 웹 표준을 좋아합니다. 스크린 리더로 제 사이트를 읽어 보는 일이 습관이 됐습니다.</p>
</section>
<section class="skills" id="skills">
<h2>기술 스택</h2>
<!-- 07편에서 만든 리스트가 이 자리에 있습니다 -->
</section>
<section class="career" id="career">
<h2>경력</h2>
<!-- 07편에서 만든 표가 이 자리에 있습니다 -->
</section>
</main>3. projects.html 카드에 data-project-id 추가하기
프로젝트 카드마다 data-project-id를 붙입니다. class="project-card"는 여섯 장 모두 공통이고, data-project-id만 카드마다 다릅니다.
<!-- projects.html (카드 그리드 일부) -->
<div class="project-grid">
<article class="project-card" data-project-id="1">
<img src="images/project-01.svg" alt="오늘의 날씨 카드 썸네일" width="1200" height="800" />
<h2>오늘의 날씨</h2>
<p>위치 기반 날씨를 카드로 보여주는 웹앱. 오프라인에서도 마지막 데이터를 보여줍니다.</p>
</article>
<article class="project-card" data-project-id="2">
<img src="images/project-02.svg" alt="독서 기록 bookshelf 카드 썸네일" width="1200" height="800" />
<h2>독서 기록 bookshelf</h2>
<p>읽은 책과 별점을 기록하고 통계를 보는 React 앱.</p>
</article>
</div>나머지 4장(메모 앱, 접근성 체크리스트, 디자인 토큰 미리보기, todo-cli)도 data-project-id를 3~6으로 이어서 붙입니다.
4. contact.html 폼 영역에 id 추가하기
10편에서 만들 폼 컨테이너에 미리 id="contact-form"을 정해 둡니다.
<!-- contact.html (main 내부 예고) -->
<main>
<h1>연락</h1>
<p>협업·채용 제안은 아래 폼으로 보내 주세요. 보통 2일 안에 답합니다.</p>
<div class="contact-form" id="contact-form">
<!-- 10편에서 form 태그와 필드를 채웁니다 -->
</div>
<aside class="faq">
<!-- modern_html: FAQ 아코디언 -->
</aside>
</main>5. 확인
- 세 파일 모두 브라우저 개발자 도구에서
document.documentElement.lang을 콘솔에 입력하면"ko"가 출력됩니다. index.html의 섹션 4개(#hero,#about,#skills,#career)가 개발자 도구 요소 탭에서id로 확인됩니다.projects.html의 카드 6개가data-project-id="1"부터"6"까지 순서대로 붙어 있습니다.
직접 해보기
footer에data-*속성으로 사이트 최초 배포 연도를 저장해 봅니다(data-launch-year="2026"). CSS·JS 없이도 개발자 도구 요소 탭에서 값이 보이는지 확인합니다.hidden속성을contact.html의 FAQ 섹션 중 하나에 임시로 붙여 보고, 페이지에서 사라지는지 확인한 뒤 다시 제거합니다.
답 보기
<footer class="site-footer" data-launch-year="2026">
<p>© 2026 Zeno Kim. 이 사이트는 학습용으로 제작되었습니다.</p>
</footer><!-- 확인용 임시 실습. 확인 후 hidden 제거 -->
<section class="faq" hidden>
...
</section>자주 하는 실수
| 증상 | 원인 | 고치는 법 |
|---|---|---|
같은 id가 한 페이지에 두 번 나온다 | id는 유일해야 하는데 복사·붙여넣기로 중복됨 | 반복되는 대상은 id 대신 class로 바꾼다 |
lang 없이 방치 | 02편 뼈대에서 깜빡함 | html 태그에 lang="ko" 확인 |
data- 뒤에 카멜케이스(data-projectId)를 씀 | JS 관례(camelCase)와 혼동 | HTML 속성은 케밥 표기(data-project-id)로 쓴다 |