Markup guide

September 08, 2021

마크업 작성은 책(글)을 쓰는일과 비슷합니다

HTML(Hyper Text Markup Language)은 원래 제목, 본문, 단락, 목록 등 필요한 정보를 정리된 구조로 인터넷상에서 보기 위해 만들어진 기술입니다. 마치 도서관에서 원하는 정보를 얻기 위해 책을 찾고 책의 내용을 찾는 것과 비슷하죠

정보를 찾는데 책의 목차가 잘 정리 되어있고 큰 제목, 소제목 까지 관계적으로 잘 구분 되어있다면 원하는 정보를 더욱 빨리 찾을 수 있을것입니다. Google검색엔진 등 대부분의 검색엔진은 사람이 책에서 정보를 찾는 방법과 비슷하게 인터넷상의 사이트를 방문, 데이터를 수집하고 모아놓은 데이터를 검색결과로 보여주는데, 만약 개발자가 위처럼 정보의 관계를 잘 정리하지 못하고 중구난방으로 정보들을 흩트려 놨다면 애써 열심히 만들어놓은 자료를 밖에 보여주기 힘들어집니다. 따라서 웹표준을 지키고 의미론적으로 마크업을 작성하는 일은 매우 중요하다고 할 수 있습니다.

1. Meta Data 잘 작성하기

Google검색엔진은 아래와 같이 압도적으로 시장을 점유하고 있고 검색이 되면 안되는 사이트를 제외하고는 대부분의 개발자들이 google검색을 신경쓰면서 개발합니다.

1. Google 92.54 %
2. Bing 2.44 %
3. Yahoo! 1.64 %
4. Baidu 1.08 %
5. Yandex 0.54 %
6. DuckDuckGo 0.45 %
7. Sogou 0.44 %
8. Ecosia 0.14 %
9. Shenma 0.08 %
10. NAVER 0.07 %

출처: https://www.interad.com/category/insights/searchengine-marketshare.html

Google검색에 우리가 만든 홈페이지를 잘 보이게 하기 위해서진행하는 작업을 SEO(Search Engine Optimization)라고 부르는데, 마크업 작성외에 SEO를 최적화 하기 위한 방법은 이전에도 원티드 블로그 SEO 그것을 알려드림에 소개된적이 있습니다.

Meta Data는 책의 표지와 같은 역할을 합니다. Meta Data를 통해 검색엔진은 해당 페이지에서 전반적으로 어떤 내용을 담고 있는지 한번에 파악할 수 있고 다음처럼 수집한 정보를 검색결과 화면에서 보여줄 수 있습니다.

아래처럼 Meta Data(Meta Tag)는<head> </head> 에 포함됩니다.

<html lang="ko">
  <head>
    <meta charset="utf-8" />
    <meta name="description" content="커리어 성장과 행복을 위한 여정,..." />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>커리어 여정을 행복하게, 원티드</title>
  </head>
</html>
google-search
구글 검색페이지에 메타테그가 잘 표시됩니다

html태그 lang속성 — ko, en 등 어떤 언어 사이트가 구성되어있는지 명시합니다. 이 속성은 에디터의 자동완성 또는 create-react-app 같은 부트스트랩 빌드 도구에 의해서 자동으로 en 으로 설정되는 경우가 많고, 실제로 명시되어 있는 언어와 구성언어가 다른 경우가 많아서 구글엔진에서도 신뢰하지 않는다고 합니다.

meta태그 charset속성 — 사이트에서 사용되는 문자가 utf-8 로 인코딩됨을 의미합니다. 유니코드를 위한 문자셋인 utf-8 이 가장 많이 사용됩니다.

title 태그 — 책의 제목과 같은 역할을 합니다. 검색엔진이 가장 먼저 접하게 되는 메타정보로 브라우저의 탭에도 표시됩니다.

  • Page title | Site name
  • Page title - Site name
  • Page title : Site name
samsung
갤럭시S | Samsung 대한민국

등으로 많이 표시하며 위와 같이 페이지의 내용과 도메인을 함께 보여주는 주는 것이 가장 좋은 작성 방법입니다.

meta태그 name=“description” content=“내용”— 타이틀을 부연 설명하는 문장입니다. 검색화면에서 타이틀 밑에 같이 노출될 수 있고, 검색에 잘 노출 될 수 있는 키워드를 노출시키기 용이합니다.

meta태그 name=“viewport” content=“width=device-width”, initial-scale=1” — 뷰포트는 브라우저 안 우리가 보는 화면의 범위를 말합니다. 이 속성을 통해 검색엔진은 해당 페이지가 반응형웹(모바일웹)을 지원하는지 판단 할 수 있습니다.

meta태그 name=“keywords” content=“연봉, 이력서…” — 위에서 설명하지는 않은 keywords라는 name도 사용할 수 있습니다. 최근에는 무분별한 키워드 사용(어뷰징) 으로 google검색엔진은 해당 데이터를 수집하지 않는다고합니다.

다음은 og태그(open graph)에 대한 설명입니다. og태그 역시 <head> </head> 안에 포함됩니다.

<meta property="og:url" content="https://..." />
<meta property="og:title" content="..." />
<meta property="og:description" content="..." />
<meta property="og:image" content="https://..." />

아래 그림처럼 카카오톡, 페이스북에서 내가 사이트의 정보를 이쁘게 보여줄 수 있는 이유도 모두 og태그가 있기 때문에 가능합니다.

kakao
카카오톡에서 보여지는 원티드 aiscore페이지의 메타정보
facebook
페이스북 담벼락에 보이는 미디엄글의 메타정보

propetry=“og:url” content=”https://…” — 링크를 눌렀을 때 이동되는 실제 주소

property=“og:titie” content=“내용” — 보여지는 화면에서 가장 강조되거나 타이틀처럼 보일 수 있는 내용을 작성합니다. 표현하는 방식은 각 서비스(카카오, 페이스북, 슬랙 등)에서 어떻게 구현했느냐에 따라 달라질 수 있습니다.

property=“og:description” content=“내용” — 타이틀을 부연 설명하는 내용을 작성합니다. 이 역시 표현하는 방식은 각 서비스(카카오, 페이스북, 슬랙 등)에서 어떻게 구현했느냐에 따라 달라질 수 있습니다.

property=“og:image” content=“https:…” — 보여주고 싶은 이미지 url을 작성합니다. 시각적으로 가장 큰 부분을 차지하기 때문에 어떤 이미지를 보여줄지 신중하게 고를 필요가 있습니다.

참고로 페이스북에서 제공하는 og태그 디버거 를 사용하면 실제 공유전에 어떻게 담벼락에 보여지는지 테스트 할 수 있습니다.

위에서는 대표적인 og태그 속성을 했지만 더 많은 og태그가 사용될 수 있으며 트위터 같은 경우는 자신들이 분석하고 표현할 수 있는 og태그 속성을 다음 문서에서 추가로 정리해놨습니다.

네이버에 최적화된 메타 데이터도 추가할 수 있습니다. (연관채널)

naver
출처: https://searchadvisor.naver.com/(네이버 서치어드바이저)

네이버가 원하는 연관채널(인스타그램, 페이스북 등) 메타 데이터는 <head></head> 태그가 아닌 <body></body> 태그 맨 아래 정해진 형식으로 추가하는 것이 좋습니다.

<body>
  ....
  <script type="application/ld+json">
    {...}
  </script>
</body>
facebook2
페이스북에서 추가한 연관채널들

FYI: 원티드, 리멤버와 같이 일반명사를 쓰는 회사는 위에서 설명하는 연관채널을 추가할 수 없습니다.

2. outline/heading 잘 구성하기

표지를 눈에 띄게 만들었으니 다음으로는 책의 내용를 잘 정리해보겠습니다. 글을 쓸때 맥락과 주제에 따라 단락을 구분하는것이 중요하듯 마크업을 작성할때도 시맨틱한 섹션과 heading 을 통해 내용을 구분하는 것이 중요합니다.

Sectioning Content

<section> — section태그는 이름처럼 내용을 주제별로 나누거나 묶을 때 사용하는 태그입니다.

지금까지 글을 작성하면서 “마크업 작성은 책(글)을 쓰는일과 비슷합니다”, “1. Meta Data 잘 작성하기”, “2. outline/heading 잘 구성하기” 총 3개의 소주제가 쓰였는데 이는 모두 html문서 상에서 <section></section> 태그로 나눌 수 있습니다.

<body>
  <section>
    <h2>마크업 작성은 책(글)을 쓰는일과 비슷합니다</h2>
    ...
  </section>
  <section>
    <h2>1. Meta Data 잘 작성하기</h2>
    ...
  </section>
  <section>
    <h2>2. outline/heading 잘 구성하기</h2>
    ...
  </section>
</body>

<nav> — nav태그는 사이트의 주된 탐색 메뉴를 나눌 때 사용되는 태그입니다. 보통 GNB라고 불리는 화면 구성요소에 많이 사용되고 길게 나열되는 형태를 보이기 때문에 <li> </li> 와 많이 사용됩니다.

wanted-gnb
Wanted GNB
<nav>
  <ul>
    <li>탐색</li>
    <li>커리어 성장</li>
    <li>직군별 연봉</li>
    <li>이력서</li>
    ...
  </ul>
</nav>

<article><section>태그와 비슷하지만 이와는 다르게 독립적으로 출판될 수 있는 내용을 포함하고 있다면 <section>태그보다는 <article>태그가 더 적절합니다. 주로 기사내용이나 페이스북(인스타그램) feed 글, 댓글등도 <article>안에 포함될 수 있습니다.

instagram
인스타그램은 각각의 feed를 article로 사용하고 있네요 (갑자기 인스타 홍보…)

<header>, <footer><header><footer>는 문법적으로 섹션을 나눌 때 사용하는 태그는 아니며 각 섹션마다 사용될 수도 있습니다. 보통 문서 전체의 GNB를 header 의 자손으로 포함하고, 회사정보(주소, 연락처)등은 footer 안에 포함합니다.

  1. header: 도입부, 헤딩그룹, 목차 등을 표시
  2. footer: 저자, 저작권, 연락처, 관련문서 등을 표시
<section>
 <header>
 </header>
   ...
 <footer>
 </footer>
</section>

<section>
 <header>
 </header>
   ...
 <footer>
 </footer>
</section>
// 여러번 사용 될 수 있는 header와 footer

<main>- <main> 태그는문서의 핵심 주제 또는 핵심 기능과 직접 관련있는 콘텐츠를 작성할 때 사용합니다. 핵심주제를 설명하는 영역인만큼 하나의 페이지에는 하나의 <main> 태그만 사용될 수 있습니다. 또한 위에서 설명한 Sectioning Content의 자손 태그로 사용될 수 없습니다.

html5
출처: https://forum.freecodecamp.org/t/what-is-html5-main-tag/313409

Heading

섹션을 의미있게 잘 나눴다면 섹션안에서 heading 을 통해 문서의 개요를 완성할 수 있습니다.

w3org
https://www.w3.org/

chrome HeadingMap extension을 사용하면 그림처럼 각 섹션안에 어떤 heading tag(h1, h2, h3…)가 사용되고 어떤식으로 구조화 되어있는지 확인 할 수 있는데, 사이트가 여러 내용을 포함하고 있고 아래와 같은 문제가 있다면 적절한 heading 을 통해 문서의 개요를 다시 작성할 필요가 있습니다.

  • h1 ,h2태그 등 태그는 들어가있지만 내용이 누락되었다.
no-h2
h2태그는 있지만 내용이 누락
  • heading의 상하관계가 모호하고 불분명하다. (h3를 소주제의 타이틀로 사용하다가 하위 내용을 h2로 명시하는 등)
  • 모두 같은 태그로 heading이 되어있다 (모두 h1으로 작성)
  • h 태그의 용도를 이해하지 못하고 단순히 blocking의 용도로 사용하였다.
  • heading 자체를 고려하지 않아 h 태그를 쓰지 않았다.

보통 h1 태그는 html파일에서 한번만 사용 되어야 한다고 알고 있지만 여러개의 섹션안에서 독립적인 사용은 문법적 오류가 아닙니다.

토스팀의 테크 블로그를 보면 heading 요소가 잘 사용 되고 있는것을 확인할 수 있네요

toss
잘 짜여진 heading 요소들

3. 자주 사용될 수 있는 시맨틱 태그들

마크업을 작성하다 보면 고민하지 않고 divspan 을 많이 사용하게 되는데 divspan 은 시맨틱한 의미를 포함하지 않기 때문에 각각inline과 block display를 대체할 시맨틱 요소를 사용함으로써 사용빈도를 줄이는 것이 좋습니다.

<dialog><dialog> 요소는 닫을 수 있는 경고, 검사기, 창 등 대화 상자 및 기타 다른 상호작용 가능한 컴포넌트를 나타냅니다.

<dialog open>
  <p>
    입력하신 내용으로는 서류합격률 계산이 어려워요.\n정확한 문구로 작성 후, 다시
    시도해주세요
  </p>
</dialog>
dialog
합격예측 화면에서 보이는 경고창

<figure>,<figcaption><figure> 요소는 독립적인 콘텐츠를 표현합니다. <figcaption> 요소를 사용해 설명을 붙일 수 있습니다. 피규어, 설명, 콘텐츠는 하나의 단위로 참조됩니다.

<figure>
  <img src="/media/cc0-images/elephant-660-480.jpg" alt="Elephant at sunset" />
  <figcaption>An elephant at sunset</figcaption>
</figure>
figout
output

<mark><mark> 요소는 현재 맥락에 관련이 깊거나 중요해 표시 또는 하이라이트한 부분을 나타냅니다

<p>html에서 <mark>markup</mark>은 굉장이 중요한 요소입니다.</p>
mark
output

<address><address> 요소는 가까운 HTML 요소의 사람, 단체, 조직 등에 대한 연락처 정보를 나타냅니다.

<footer>
  <p>이 페이지의 저자에게 연락하세요:</p>
  <address>
    <a href="mailto:jim@rock.com">jim@rock.com</a><br />
    <a href="tel:+13115552368">(311) 555-2368</a>
  </address>
</footer>

<progress><progress> 요소는 어느 작업의 완료 정도를 나타내며, 주로 진행 표시줄의 형태를 띕니다.

<progress id="file" max="100" value="70">70%</progress>
progress
output

<strong><strong> 요소는 중대하거나 긴급한 콘텐츠를 나타냅니다. 보통 브라우저는 굵은 글씨로 표시합니다. 보통 p태그 안에 특정 단어나 문장을 따로 css로 스타일링 해야할 경우 사용하는 것을 추천합니다. 그리고 <b>태그 대신 <strong>태그를 통해 원하는 콘텐츠를 강조하는 것이 더 적절합니다.

<p>Wanted AI가 <strong>합격률을 예측해 드려요!</strong></p>
strong
output

<em><em> 요소는 텍스트의 강세를 나타냅니다. <em> 요소를 중첩하면 더 큰 강세를 뜻하게 됩니다. 역시 p태그 안에 특정 단어나 문장을 따로 css로 스타일링 해야할 경우 사용하는 것을 추천합니다.

<p>이 기회를 놓치지 말고 <em>지금 당장</em> 신청하세요!</p>
em
output

4. <button> vs <a>

button 태그 a 태그 모두는 유저와 상호작용 하는 요소로 클릭하거나 터치했을 때 화면의 변화를 기대할 수 있습니다.

<a> 요소(앵커 요소)는 href 특성을 통해 다른 페이지나 같은 페이지의 어느 위치, 파일, 이메일 주소와 그 외 다른 URL로 연결할 수 있는 하이퍼링크를 만듭니다. <a> 안의 콘텐츠는 링크 목적지의 설명을 나타내야 합니다. (https://developer.mozilla.org/ko/docs/Web/HTML/Element/a)

즉, 구성요소를 클릭하거나 터치했을 때 현재 url이 변경되거나 현재 url 뒤 querystring 이 변경되어야 한다면 <a> 태그로 작성해야 합니다. Next.js 를 사용할 경우 next/linkreact-router 를 사용한다면 Link 컴포넌트를 활용할 수 있습니다. (의도에 맞게 모두 a link로 만들어져 있습니다)

<button>요소는 클릭 가능한 버튼을 나타냅니다. 버튼은 양식 내부는 물론 간단한 표준 버튼 기능이 필요한 곳이라면 문서 어디에나 배치할 수 있습니다. 기본값의 HTML 버튼은 사용자 에이전트의 호스트 플랫폼과 비슷한 디자인을 따라가지만, 외형은 CSS로 변경할 수 있습니다. (https://developer.mozilla.org/ko/docs/Web/HTML/Element/button)

MDN문서의 설명과 같이 button 태그는 type="submit" 을 이용한 현재의 실행컨텍스트를 변경하는 일 외엔 현재 보여지는 화면안에서 동적으로 dom을 변경한다거나 javascript를 실행시켜 원하는 인터랙션을 보여주는데 활용 할 수 있습니다

button
url변경없이 같은화면에서 인터랙션이 일어납니다
// BAD!
const ButtonComponent = () => {
  const { router } = useRouter()
  return <button onClick={() => router.push("/home")} type="button">
}
// GOOD!
<Link to="/home" />

마치며

시맨틱 요소를 잘 지켜 웹을 개발하는 것은 웹 표준(Web Standards)과 웹 접근성 (Web Accessibillity)을 잘 준수했다는 결과로 이어집니다. 웹표준을 잘 지켜서만들어진 사이트는 브라우저의 업데이트 또는 HTML5스펙의 업데이트에 따른 사이드이팩트(Side Effect)없이 적절히 대응 할 수 있으며, 인터넷을 사용하는 모든 사람들이 차별받지 않고 인터넷상의 정보를 습득할 수 있도록 합니다.(웹 접근성에 대한 설명)

참고

위 내용은 팀원들에게 공유하고 싶은 내용을 추려 패스트캠퍼스 온라인 강의 The RED: 견고한 UI를 위한 마크업 가이드 를 참고하여 정리했습니다. 더 자세하고 많은 내용을 학습하기 원하신다면 강의신청을 추천드립니다 :D

그 외 참고한 사이트들

이전 - Test Coverage를 유지하는 방법