누군가가 들러서 구경하게 될 포트폴리오 사이트를 만들면서, '사람들이 실제로 사용하는' 웹이라는 매체에 대해 다시 생각해보았다. 웹에 접속하는 환경은 매우 다양하고, 그 환경에서 정보는 최대한 같은 모습과 맥락으로 보이고 전달되어야 한다. 그를 실현하기 위한 약속이 웹표준이고, 더불어서 웹표준을 지키는 일이 웹접근성을 지키는 일과 밀접한 관련이 있다는 것도 알게 되었다. 그래서 웹표준에 대해 잘 알기 위해 프로그래밍 강의 사이트 인프런에서 관련 강의를 수강 중이다. 우선 HTML에 관련된 사항들 중 인상 깊은 내용과 추가로 알아본 정보를 정리한다.
웹에 접속하는 환경, 브라우저는 다양하다. 사용하는 렌더링 엔진 역시 마찬가지다. 이때 웹 브라우저 제조사와 웹 서비스 작성자가 공통된 약속을 마련하고 지킨다면, 사용자가 어떤 환경에서 접속하든 같은 화면을 보여주고 정보와 의미를 전달할 수 있다. 그 약속이 웹표준이다. 웹표준은 월드 와이드 웹 컨소시움(W3C)에서 관리하며, 현재 최신 웹표준 버전은 HTML5, CSS3이다.
HTML5 TEST에서 현재 사용하는 브라우저와 기타 다른 브라우저가 HTML5 표준을 얼마나 서포트하고 있는지 자세한 항목들과 함께 살펴볼 수 있다.
HTML 파일이란 단순하게 말하면 '작성한 내용을 웹 브라우저로 확인할 수 있고, 코드 편집기를 이용해서 작성하는, 확장자가 html인 파일'이다. 웹브라우저에 내용을 표시하기 위해 사용한다.
<!DOCTYPE html>
HTML 파일 최상단에 위치하는 태그. DOCTYPE은 어떤 버전의 HTML로 작성된 문서인지를 브라우저에 알려준다. <!DOCTYPE html>
은 문서가 HTML5 버전을 지켜 작성된 문서임을 뜻한다.
사용한 버전과 다른 DOCTYPE을 기재하면 웹페이지가 '호환모드'로 렌더 될 가능성이 있다. 호환모드는 일반적인 표준모드와는 동작방식이 다른 점이 있어 문서가 제대로 렌더되지 않을 수 있기 때문에, 표준 모드로 작성한 문서를 브라우저가 표준 모드로 읽도록 올바른 DOCTYPE을 항상 명시해야 한다.
<meta charset="utf-8">
charset
은 HTML 파일의 <head>
태그 안에 작성하는 메타 태그 요소다. 해당 HTML 문서를 어떤 방식으로 인코딩할지 브라우저에 알리는 역할을 한다. charset="utf-8"
이라고 명시한 경우 브라우저는 문서를 UTF-8 방식으로 인코딩한다.
UTF-8은 유니코드를 어떻게 컴퓨터가 알아듣도록 이진법으로 해석할지(인코딩할지) 정한 국제적인 약속이다. 유니코드는 아스키코드로 표현할 수 없는(로마자 알파벳이 아닌) 여러 가지 언어들을 컴퓨터에 표시하기 위해서, 언어를 구성하는 글자마다 정해놓은 이름으로, 이 역시 국제적인 약속이다.
시멘틱이란 어떤 코드의 외형보다는, 그 코드가 존재하는 의미와 목적을 이른다. 시멘틱 태그는, 그 태그가 가지고 있는 콘텐츠가 문서 내에서 어떤 의미를 지니는지 알려주는 태그다. 예를 들어 <h1>
태그는 현재 문서의 제목을 담고 있음을 의미한다. 그에 맞게 브라우저에서는 기본적으로 <h1>
으로 감싸진 텍스트를 크고 굵게 표시한다.
<span>
태그로 감싸진 글자라도 <h1>
과 마찬가지로 글자를 크고 굵게 표시하여 제목처럼 보이도록 스타일링 할 수 있다. 하지만 '이 문서의 제목'이라는 의미에 맞는 태그 <h1>
을 사용할 때의 장점은 누릴 수 없다.
<h1>~<h6>
제목을 표시할 때 사용한다. <h1>
부터 <h6>
까지 존재한다. 스크린 리더 사용자가 사용하는 탐색 기법은 제목에서 제목으로 옮겨가는 방식이기에, 제목 단계를 뛰어넘으면 문서의 층위를 파악하는데 혼란스러울 수 있다. 그래서 제목 단계는 순차적으로 늘어나야 한다. 즉, <h1>
후에 <h3>
이 오지 않도록 한다. 그리고 페이지당 하나의 <h1>
태그만을 사용하자.
<hr>
수평줄이 생긴다. '주제가 바뀔 때' 분위기 전환을 위해서 넣는다. '이 글의 주제가 여기서 바뀌었다'를 알리는 역할이다.
<pre>
표시한 공백(스페이스바로 띄운 공간)이 그대로 표시된다. 여담으로 CSS에서 지정할 수 있는 white-space 속성의 'pre' 값이 같은 의미를 갖는다.
<blockquote>
태그 안쪽 텍스트가 인용문임을 알리는 태그. 본문보다 전체적으로 들여쓰기 된다. <blockquote cite="https://www.sample.com/sample.html/">
처럼 속성 cite
로 인용문의 출처 문서나 URL을 입력할 수 있다. cite
속성값은 화면에 나타나지 않는다.
<strong>
태그 안쪽 텍스트가 '중요한 내용'임을 의미하며, 글자를 굵게 표시한다.
<b>
중요하다는 의미를 가지지 않으면서, 글자를 굵게 표시한다.
<em>
'강조하고자 하는 내용'임을 의미하며, 글자를 기울여 표시한다.
<i>
특정한 의미를 담지 않고, 단순히 글자를 기울여 표시하고 싶을 때 사용한다.
<q>
단락과 문장 중간에 줄바꿈 없이 '인용문'을 표시할 때 사용한다. 태그로 묶은 내용 앞뒤에 따옴표가 붙는다.
<mark>
문장에 형광펜을 긋는 것처럼, 강조하고 싶은 부분을 태그로 묶으면 안쪽 텍스트 배경색이 노란색으로 표시된다. 텍스트의 중요성보다는, 검색 결과 표시 등 현재 맥락과 연관성이 있는 텍스트를 강조할 때 사용한다.
<body>
<h2><mark>"웹표준"</mark>의 검색결과</h2>
<p>웹에 접속하는 환경, 브라우저는 다양하다. 사용하는 렌더링 엔진 역시 마찬가지다. 이때 웹 브라우저 제조사와 웹 서비스 작성자가 공통된 약속을 마련하고 지킨다면, 사용자가 어떤 환경에서 접속하든 같은 화면을 보여주고 정보와 의미를 전달할 수 있다. 그 약속이 <mark>웹표준</mark>이다. <mark>웹표준</mark>은 월드 와이드 웹 컨소시움(W3C)에서 관리하며, 현재 최신 <mark>웹표준</mark> 버전은 HTML5, CSS3이다.</p>
</body>
<ruby>
동아시아 문자의 발음을 글자 상단에 작게 표시할 때 사용한다.
<ruby>
漢 <rp>(</rp><rt>Kan</rt><rp>)</rp>
字 <rp>(</rp><rt>ji</rt><rp>)</rp>
</ruby>
<figure>
<figure>
는 이미지, 비디오, 코드 블록, 표 등을 하나의 독립적인 콘텐츠로 묶는 태그이다. 내부에 <figcaption>
태그를 이용하여 해당 콘텐츠에 대한 설명이나 제목 등을 기입한다. 설명을 <p>
태그 등으로 적을 수도 있지만, 이 경우 콘텐츠와 설명이 서로 연관되어 있음을 명확하게 알리기 어렵다. 그러나 <figure>
태그 안에 <figcaption>
을 사용하여 콘텐츠에 대한 설명, 제목을 적는다면 콘텐츠와 설명이 서로 연관 있음을 명확하게 나타낼 수 있다. 이는 검색엔진 최적화나 접근성을 높이는 데에도 효과적이다.
<figure>
<img src="new_html5_logo.img" alt="육각형과 초록색을 사용해 새로 만들어 본 HTML5 로고 이미지">
<figcaption>HTML5 로고 이미지를 만들어 보았다.</figcaption>
</figure>
<figure>
| MDN ]<ul>
항목에 순서가 없는 목록을 만든다.
<ol>
항목에 순서가 있는 목록을 만든다. type
속성은 항목 앞에 표시되는 카운터 스타일을 조정하고, start
는 카운터의 시작 번호 설정, reserved
속성은 카운터를 역순으로 표시할지 여부를 정할 수 있다.
<!-- 카운터가 없는 리스트 ul -->
<ul>
<li>1일차
<!-- 카운터가 있는 리스트 ol -->
<ol type="a">
<li>해녀박물관</li>
<li>낚시체험</li>
</ol>
</li>
<li>2일차
<!-- type으로 앞에 들어가는 카운터 스타일 설정, start로 카운터를 몇번부터 시작할지 설정 -->
<ol type="A" start="3">
<li>용눈이오름</li>
<li>만장굴</li>
<li>카약체험</li>
</ol>
</li>
</ul>
// 렌더된 목록
* 1일차
a.해녀박물관
b.낚시체험
* 2일차
C.용눈이오름
D.만장굴
E.카약체험
<table>
태그로 작성하는 표는 어떤 정보를 일목요연하게 보여주는 용도, 정리된 정보를 전달하는 용도로 사용한다. 마케팅용 이메일을 작성하는 등, <div>
태그를 제대로 지원하지 않는 예전 버전 브라우저 환경에 맞춰 문서를 작성해야 하는 몇몇 경우를 제외하고는 페이지 레이아웃을 짜기 위해서 표를 사용하지 말자.
<caption>
표에 제목을 지정할 때 사용한다.<table>
태그 바로 아래에 기입한다.
<table>
<caption>표 제목</caption>
<tr>
<th>1행 1열(제목)</th>
<td>1행 2열</td>
<td>1행 3열</td>
</tr>
<tr>
<th>2행 1열(제목)</th>
<td>2행 2열</td>
<td>2행 3열</td>
</tr>
</table>
<figcaption>
<table>
을 <figure>
태그로 감싸고 <figcaption>
태그를 사용하여 제목을 적는다. 이미지와 동영상, 코드 블록 등 <figure>
태그로 감싸는 독립적인 콘텐츠에는 모두 같은 방법으로 제목을 달 수 있다.
<figure>
<figcaption>표 제목</figcaption>
<table>
<tr>
<th>1행 1열(제목)</th>
<td>1행 2열</td>
<td>1행 3열</td>
</tr>
<tr>
<th>2행 1열(제목)</th>
<td>2행 2열</td>
<td>2행 3열</td>
</tr>
</table>
</figure>
<thead>
, <tbody>
, <tfoot>
테이블 구조를 헤드, 바디, 푸터로 나누어 각각 <thead>
, <tbody>
, <tfoot>
으로 묶을 수 있다. <thead>
는 표의 항목, <tbody>
는 내용, <tfoot>
는 표 내용을 요약하는 부분이다.
스크린 리더기 등을 통해 화면 정보를 읽어내려가는 경우, 표의 구조를 정확히 파악하기 어려울 수 있다. 이때 이 태그들을 사용하면 표의 구조를 알려주는 데 도움이 된다. 그리고 표가 아주 긴 경우에도 유용하다. 표 항목을 나타내는 <thead>
의 위치를 화면에 고정하고, 표 본문인 <tbody>
부분만 스크롤 되도록 구현하면 표 내용을 알아보기 편리하다. 또한 표 구조를 나눔으로써 각 부분에 대한 스타일을 지정하기도 쉬워진다.
<table>
<caption>제주도 학교현황</caption>
<thead>
<tr>
<th>구분</th>
<th>학교수</th>
<th>학급수</th>
</tr>
</thead>
<tbody>
<tr>
<th>중학교</th>
<td>44</td>
<td>699</td>
</tr>
<tr>
<th>고등학교</th>
<td>29</td>
<td>676</td>
</tr>
</tbody>
<tfoot>
<tr>
<th>합계</th>
<td>300</td>
<td>3,437</td>
</tr>
</tfoot>
</table>
이미지 속 표의 <thead>
, <tfoot>
의 회색 배경은 스타일로 지정했다.
<col>
, <colgroup>
<colgroup>
은 표의 열을 묶어서 조정할 수 있는 태그다. 내부에 <col>
태그와 span
속성으로 열을 묶는다. 원하는 스타일을 지정하고자 할 때 사용하면 편리하다. <colgroup>
은 <caption>
태그 아래, <tr>
태그 위에 넣는다.
<col>
은 태그 하나당 열 하나를 의미하며, span
속성으로 1보다 큰 숫자를 지정하면 그 숫자만큼의 열을 차지하게 된다.
여담으로 UI 라이브러리인 Ant-design등에서 그리드를 지정할 때 사용한 <Col />
컴포넌트와 span
속성이 여기에서 비롯되었음을 짐작할 수 있었다.
<figcaption>표 제목</figcaption>
<table>
<colgroup>
<col>
<col span="2" style="background: coral;">
<col style="background: dodgerblue;">
</colgroup>
<tr>
<th>1행 1열(제목)</th>
<td>1행 2열</td>
<td>1행 3열</td>
<td>1행 4열</td>
</tr>
<tr>
<th>2행 1열(제목)</th>
<td>2행 2열</td>
<td>2행 3열</td>
<td>1행 4열</td>
</tr>
</table>
</figure>
<form>
태그를 이용해 만드는 서식은 사용자가 웹사이트에서 정보를 입력하여 서버로 보내는 데 사용되는 모든 유형의 요소를 지닌 영역이다.
method
속성은 서식에 입력된 정보를 서버로 어떻게 보낼지 브라우저에 알리는 역할을 한다. 속성값은 GET과 POST 두 가지다.
GET 방식은 사용자가 입력한 사항을 URL에 쿼리 문자열과 함께 붙여 HTTP 요청을 보낸다. 그러므로 주소 표시줄에는 입력 사항이 모두 표시된다. 구글에서 검색어를 입력해 검색하면 검색 결과 페이지의 주소가 https://www.google.com/search?q=검색어
로 보이는 상황이다.
브라우저가 값을 캐싱할 수 있고, 주소에 입력한 사항이 모두 포함되어 있으므로 사용자가 입력창을 통하지 않고 바로 결과 페이지에 접속하거나, 결과 페이지를 즐겨찾기에 추가할 수도 있다. 하지만 전송 가능한 글자의 길이가 주소 부분을 포함하여 URL의 최대길이인 2,048자로 제한된다. 그래서 길이가 길지 않고 비교적 보안을 유지하지 않아도 되는 내용을 서버에 전송할 때 GET 방식을 사용한다.
POST 방식은 입력된 사항을 쿼리 문자열과는 별도로 body로 묶어 HTTP 요청 시 함께 전송한다. 데이터 길이에 제한이 없고, 브라우저에 캐싱되지 않는다. GET 방식보다는 보안상 이점이 있다. 그래서 비밀번호 등 보다 민감한 정보를 전송할 때 POST 방식을 사용한다.
<input>
<input>
은 사용자의 데이터를 받을 수 있는 다양한 유형의 컨트롤러이다. 지정한 type
속성에 따라서 다양한 외관과 양식으로 나타나기에 알아둘 사항이 많다.
type="hidden"
을 지정하면 요소가 화면에 나타나지 않는다. 이를 이용해서 사용자에겐 보이지 않지만, 사용자가 데이터를 보낼 때 함께 서버로 전송되었으면 하는 정보를 사이트 작성자가 입력해 놓기도 한다.type="password"
는 입력한 텍스트가 화면에서 '*'이나 점 등으로 보인다. value
속성이 없다.type="search"
는 텍스트가 입력되면 입력창 왼쪽에 x 버튼이 나타난다. 버튼을 누르면 입력한 내용이 한 번에 지워진다.type="email"
, type="url"
등은 입력된 값이 해당 형식에 맞는지 검사한다. 맞지 않으면 입력창에 빨간 테두리가 생기는 등 오류가 있음을 알린다.<form>
<fieldset>
<legend>로그인 정보</legend>
<ul>
<li>
<label for="user-id">아이디 </label>
<input type="text" id="user-id">
</li>
<li>
<label for="pwd1">비밀번호 </label>
<input type="password" id="pwd1">
</li>
</ul>
</fieldset>
<fieldset>
<legend>개인 정보</legend>
<ul>
<li>
<label for="mail">메일 주소</label>
<input type="email" id="mail">
</li>
<li>
<label for="homep">블로그/홈페이지</label>
<input type="url" id="homep">
</li>
</ul>
</fieldset>
<input type="submit" value="가입하기">
</form>
메일주소와 홈페이지를 지정된 형식에 맞추지 않으면 입력창 테두리가 빨간색으로 표시된다. 그 상태에서 가입하기 버튼을 누르면 '형식에 맞춰 입력해달라'는 문구가 뜬다. 그리고 Firefox 브라우저에서 type="password"
로 설정한 <input>
의 입력값은 점으로 표시된다.
지정된 형식에 맞춰 필드 입력값을 고치면 빨간색 테두리가 사라진다.
<button>
HTML5 이전에는 일반적인 태그에 링크를 걸거나, <input>
태그의 type
을 submit
으로 지정하여 버튼으로 사용했으나 HTML5에서 버튼을 의미하는 <button>
태그가 등장했다. 사용자 에이전트에서 명확하게 해당 요소가 버튼임을 알 수 있다. 버튼으로 사용하는 모든 요소에 적용하면 된다.
<output>
태그 속 내용이 사용자가 조작한 움직임의 결과, 계산 결과임을 나타낸다. 계산기로 계산한 값 등이 일반적이고, 사용자가 버튼을 눌러 나타나는 작은 팝업 메시지까지 <output>
에 포함하는 경우도 목격했다. 화면에 표시될 때 일반 텍스트, 엘리먼트와의 차이점은 없지만, 해당 내용이 어떤 계산의 결과 혹은 사용자의 조작에 따른 결과물임을 사용자 에이전트가 명확히 알 수 있다.
콘텐츠 구획 태그를 사용해 페이지 내용을 그 역할과 의미에 근거해 나누고, 큰 틀을 잡을 수 있다.
<header>
사이트 전체 혹은 본문의 제목이 되는 부분이다. <form>
으로 묶인 검색창이나 <nav>
로 묶인 사이트 메뉴, 로고 마크 등을 넣는다.
<section>
문서에서 주제별로 콘텐츠를 묶을 때 사용한다. 대부분 해당 구획에는 제목이 달려 있다(제목 태그가 함께 사용된다).
<article>
본문과는 상관없이, 태그 안의 내용을 떼어내어 보더라도 완전한 하나의 콘텐츠일 때 사용한다. 게시판과 블로그 글, 잡지와 뉴스 기사 등이 일례다. <section>
과 <article>
은 아주 명확하게 구분 지어 사용되지 않는다.
<aside>
목차를 담은 사이드바, 광고 등 문서의 주요 내용과 간접적으로만 연관된 내용을 담는다.
<footer>
페이지를 작성한 사람의 연락처, 저작권 정보, 관련 문서 등을 표시한다.
<address>
제작자 정보와 연락처 정보를 나타낸다. 쇼핑몰 사이트의 <footer>
안 사업자 주소가 일례다.
낮은 버전의 구형 브라우저는 HTML5 버전 웹표준을 온전히 해석할 수 없기에 대응이 필요하다.
Internet Explorer 6-9, Safari 4.x (iPhone 3.x) 그리고 Firefox 3.x 버전 브라우저는<header>
, <section>
, <footer>
등의 콘텐츠 구획 태그를 읽지 못한다. html5shiv는 해당 브라우저에서 콘텐츠 구획 태그가 사용된 문서를 읽을 수 있도록 만들어주는 자바스크립트 라이브러리이다.
아래와 같이 라이브러리 파일을 주석으로 <head>
태그 내에 삽입하면 된다.
<head>
<!--[if lt IE 9]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
안그래도 요즘에 웹표준에 대한 관심이 많아졌는데, 일목요연하게 정리해주셔서 감사합니다 (__)