[Project] 시맨틱 태그

SEONDY·2024년 7월 22일

Project

목록 보기
1/9
post-thumbnail

시맨틱 태그

  • 해커톤에 참가하여 진행했던 프로젝트를 더욱 발전시키고자 현재 지속적인 회의와 개발 시간을 가지고 있다.
    해커톤 당시에는 문제가 생겼을 때, 왜 발생했는가 / 이유가 무엇인가 / 해결 방법은? 에 대해서 완벽히 이해하지 못했다. 내가 그 문제를 이해하지 못했더라도, 해결 방법을 찾고 적용을 하는 것이 끝이었다. (빠르게 서비스를 구현하는 것이 더 중요했기 때문이다...)
  • 그래서 더 다양한 페이지 및 기능 구현 + 리팩토링을 진행하기로 한 지금, 프로젝트에서 발생한 문제 / 더 고민해보고자 한 부분 등을 정리해두려고 한다.

1. 시맨틱 태그

프로젝트를 진행하면서 사실... 마크업 작업을 할 때, 세세하게 나누지 않고 진행했다. 기껏해야 img, button, div 정도...?! 특히 의미없는 div 태그를 굉장히 많이 사용했다.
p 태그나 span 태그를 사용할 경우에 생기는 불편함(개인적인 불편함!!! display가 block이 아닌 태그를 스타일링하는 것에 익숙하지 않다는 점) 때문에 굳이 사용하지 않았는데, 이런 것을 잘 지키는 것이 중요하다는 것을 알게 되었다.
프론트엔드 팀 회의에서 디벨롭 & 리팩토링 과정은 이 부분을 고려하며 진행하기로 결정했다!🤤

시맨틱 태그란?

  • 프로그래밍에서 시맨틱은 코드 조각의 의미를 나타냄
    태그 내용에 의미를 부여하는 태그! (웹 페이지에 보이는 것 이상의 정보 제공)
  • 포함된 콘텐츠의 특정 의미를 정의하고 목적을 갖는 태그
    <header>, <nav>, <article>, <section>, <footer>, <main> ...
    콘텐츠를 논리적 섹션으로 구성하고, 각 부분의 역할과 기능을 전달하는 데 도움
    태그에 의미를 부여함으로써 웹사이트의 구조를 파악하기 쉽도록 도와주기 위한 태그!

시맨틱 태그의 이점

  • 검색 엔진은 의미론적 마크업을 페이지의 검색 순위에 영향을 줄 수 있는 중요한 키워드로 간주함.
    SEO(검색엔진 최적화) 향상
  • 시각 장애가 있는 사용자가 화면 판독기로 페이지를 탐색할 때 의미론적 마크업을 안내판으로 사용 가능
  • 의미없고 / 클래스 이름 붙여져 있거나 / 그렇지 않은 끊임없는 div를 탐색하는 것보다 의미있는 코드 블록을 찾는 것이 훨씬 쉬움!
  • 개발자에게 태그 안에 채워질 데이터 유형을 제안함
  • 의미있는 이름짓기(Semantic naming)는 적절한 사용자 정의 요소 / 구성 요소의 이름짓기를 반영함

사용하기 위한 기본적인 규칙

  • 콘텐츠의 의미와 기능에 따라 콘텐츠의 각 부분에 적합한 요소를 선택해야 함
    로고나 제목이 포함된 페이지 상단 : <header> / 저작권이나 연락처, 소셜 미디어 계정 링크가 포함된 하단 : <footer>
  • 요소가 명확한 계층 구조와 구조를 형성하도록 요소들을 올바르게 중첩해야 함
    페이지의 주요 콘텐츠를 통틀어 둘러싸려면 : <main> / 여러 주제나 하위 제목 등 목록을 형성하려면 : <section>
  • 스타일 지정이나 스크립팅 목적으로 필요한 경우를 제외하고는 <div>처럼 의미 없는 요소나 속성을 사용하지 않아야 함

2. 시맨틱 태그의 종류

<article>

  • 독립적인 글을 다루는 데 사용 / 독립적으로 구분해 배포, 재사용할 수 있는 구획
    블로그 게시물, 매거진, 뉴스 기사, 제품 리뷰 등 독립적으로 배포하거나 재사용할 수 있는 독립형 콘텐츠 정의
  • 하나의 문서가 여러 개의 <article>을 가질 수 있음.

<aside>

  • 옆에 위치하는 콘텐츠를 담는 태그 / 페이지 콘텐츠를 제외한 콘텐츠를 정의함
    문서의 주요 내용과 간접적으로만 연관된 부분 (주로 사이드바 / 콜아웃 박스)

<details>

  • 사용자가 보거나 숨길 수 있는 추가 세부 정보를 정의함
    사용자와 상호작용이 가능! / 사용자는 버튼을 통해 열고 닫을 수 있음
    기본적으로 닫은 상태 (클릭 시 확장되는 성질)
    <summary> 태그는 <details>에서 보이는 부분 담당! : <details> 태그의 첫 번째 하위 항목이어야 함
<details>
  <summary>보이는 부분 (확장되기 전)</summary>
  세부 내용 (상호작용을 통해서 볼 수 있는 내용)
</details>

<figure>

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

<figcaption>

  • 부모 <figure> 요소가 포함하는 다른 콘텐츠에 대한 설명 혹은 범례
  • <figure>에 대한 간략한 설명
  • 가장 가까운 구획 콘텐츠나 구획 루트의 푸터를 나타냄
    일반적으로 구획의 작성자, 저작권 정보, 관련 문서 등의 내용을 담음
    연락처 정보, 사이트 맵, 웹사이트를 하나로 묶고 SEO를 강화하는 데 도움이 되는 소셜 미디어 사이트에 대한 링크 포함

<form>

  • 정보를 제출하기 위한 대화형 컨트롤을 포함하는 문서 구획
    <form> 요소를 꾸밀 때, 모든 elements의 유효성을 나타내는 CSS :valid:invalid 의사 클래스 사용 가능
  • :valid
    성공적으로 검증된 요소를 나타냄. 이를 통해 사용자가 데이터를 올바르게 입력했는지 시각적으로 보여줄 수 있음
  • :invalid
    실패한 모든 요소를 나타냄 / 필드 오류를 강조할 때 유용
  • 소개 및 탐색에 도움을 주는 콘텐츠를 나타냄
    제목, 로고, 검색 폼, 작성자 이름 등의 요소도 포함할 수 있음
    메타 태그 정보, 키워드, 가져온 CSS 파일이나 스타일 시트가 포함되는 경우 많음

<main>

  • 문서 <body>의 주요 콘텐츠를 나타냄
    주요 콘텐츠 영역은 문서의 핵심 주제나 앱의 핵심 기능에 직접적으로 연결됐거나 확장하는 콘텐츠로 이루어짐
    hidden 속성 없이는 문서에 하나보다 많은 <main> 요소가 존재해선 안 됨

<mark>

  • 현재 맥락에 관련이 깊거나 중요해 표시 또는 하이라이트한 부분을 나타냄
  • 문서의 부분 중 현재 페이지 내, 또는 다른 페이지로의 링크를 보여주는 구획
    메뉴, 목차, 색인 ...

<section>

  • 일반 구획 요소
  • HTML 문서의 독립적인 구획을 나타냄 / 더 적합한 의미를 가진 요소가 없을 때 사용
    보통 제목을 포함하지만, 항상 그런 것은 아님
  • 요소의 콘텐츠를 외부와 구분하여 단독으로 묶는 것이 나아보인다면 <article>요소가 더 좋은 선택일 수 있다.

<time>

  • 시간의 특정 지점 또는 구간을 나타냄
    datetime 특성의 값을 지정해 보다 적절한 검색 결과나, 알림 같은 특정 기능을 구현할 때 사용할 수 있음
<p>
  The Cure will be celebrating their 40th anniversary on <time datetime="2018-07-07">July 7</time> in London's Hyde
  Park.
</p>

<p>
  The concert starts at <time datetime="20:00">20:00</time> and you'll be able to enjoy the band for at least
  <time datetime="PT2H30M">2h 30m</time>.
</p>

3. <article><section>

이렇게 학습했는데, 현재 프로젝트에 어떻게 적용시키면 좋을지 감이 잡히지 않는다. 특히 <article><section> 태그의 차이가 무엇인지 명확히 이해를 못했다.
참고한 내용 : https://coding-factory.tistory.com/883

  • 태그를 적용한 부분을 떼어내 독립적으로 배포하거나 재사용하더라도 완전히 하나의 콘텐츠가 된다면 <article> 태그를 사용하면 된다.
  • <section> 태그는 <article> 태그와 달리 재배포할 수 없는 콘텐츠로 인식한다.
  • 이 내용을 바탕으로, chatGPT에게 예시를 부탁했다.
  • <article>
<article>
  <h1>블로그 포스트 제목</h1>
  <p>이것은 블로그 포스트의 내용입니다. 이 콘텐츠는 독립적으로 배포되거나 다른 곳에서 재사용할 수 있습니다.</p>
</article>

<article> 태그로 감싸져 있는 이 내용은, 떼어내서 다른 곳에 재사용하거나 배포할 수 있다.

  • <section>
<section>
  <h1>오늘의 주요 뉴스</h1>
  <article>
    <h2>뉴스 기사 제목 1</h2>
    <p>이것은 첫 번째 뉴스 기사의 내용입니다.</p>
  </article>
  <article>
    <h2>뉴스 기사 제목 2</h2>
    <p>이것은 두 번째 뉴스 기사의 내용입니다.</p>
  </article>
</section>

여기에서 <section>은, 여러 기사(<article>)을 그룹으로 묶는 역할을 하고 있다. 자체적으로 독립된 콘텐츠로 재배포되지 않으나, 각 <article> 태그로 감싼 개별 뉴스 기사는 독립적 배포가 가능하다.

이렇게 예시를 보니 이해가 된다...!!!


4. 프로젝트 적용

이제 실제로 프로젝트 화면에 시맨틱 태그를 적용 시켜보려 한다.


적용 시킬 화면은 home 화면이고, 위와 같이 구성되어 있다.
내가 시맨틱 태그를 적용시키지 않는다면... 이렇게 작성했을 것이다.

기존 코드라면...

const HomePage = () => {
  return (
    <>
      <div>
        <img src={이미지} />
        <p>상단 텍스트</p>
        <p>설명 텍스트</p>
      </div>
      <div>
        <p>카테고리 제목</p>
        <div>
          <div>카테고리1</div>
          <div>카테고리2</div>
          <div>카테고리3</div>
          <div>카테고리4</div>
        </div>
      </div>

      {/* 공통 컴포넌트 분리 */}
      <div>
        <p>카테고리 제목</p>
        <div>
          <div>카테고리1</div>
          <div>카테고리2</div>
          <div>카테고리3</div>
          <div>카테고리4</div>
        </div>
      </div>
      <div>
        <p>카테고리 제목</p>
        <div>
          <div>카테고리1</div>
          <div>카테고리2</div>
          <div>카테고리3</div>
          <div>카테고리4</div>
        </div>
      </div>
    </>
  );
};

export default HomePage;
  • 여기에서 네비 부분은 App.jsx 파일에 들어간다고 생각하고 이 페이지에 넣지 않았다. (공통으로 쓰이는 페이지가 더 많기 때문)

아마 기존 내 방식대로 한다면... <p> 태그도 안 썼을지도 (ㅠㅠ)
진짜 그냥 딱 보기만 해도 너무너무너무 별로인 코드다...😢😢😢 의미없이 쓴 <div> 태그가 도대체 몇 개인지...

고려하며 개선해본 코드!

const HomePage = () => {
  return (
    <>
      {/* 홈페이지의 상단 이미지 + 소개 내용 */}
      <header>
        <img src={이미지} />
        <p>상단 텍스트</p>
        <p>설명 텍스트</p>
      </header>

      {/* 카테고리별 라우팅 (다른 페이지로 이동) */}
      <section>
        <h2>카테고리 제목</h2>
        <nav>
          <ul>
            <li>카테고리1</li>
            <li>카테고리2</li>
            <li>카테고리3</li>
            <li>카테고리4</li>
          </ul>
        </nav>
      </section>

      {/* 공통 컴포넌트 분리 */}
      {/* 카테고리별 라우팅2 (다른 페이지로 이동) */}
      <section>
        <h2>카테고리 제목</h2>
        <nav>
          <ul>
            <li>카테고리1</li>
            <li>카테고리2</li>
            <li>카테고리3</li>
            <li>카테고리4</li>
          </ul>
        </nav>
      </section>
      {/* 위와 같은 카테고리별 라우팅2 */}
      <section>
        <h2>카테고리 제목</h2>
        <nav>
          <ul>
            <li>카테고리1</li>
            <li>카테고리2</li>
            <li>카테고리3</li>
            <li>카테고리4</li>
          </ul>
        </nav>
      </section>
    </>
  );
};

export default HomePage;

<nav> 태그를 활용하여 링크임을 명시해줬다.
또한, 목록을 <ul><li> 태그를 활용해 나타냈다.

  • 여기에서 <header><p>태그에 <h1> 태그를 쓰지 않은 이유는...
    크게 저 텍스트가 의미를 가지지 않았다고 생각했기 때문이다. 그저 소개나 설명하는 텍스트였기 때문에 따로 h태그를 사용해 표시하지 않았다.

5. 추가 학습

이전에 관심있게 읽었던 Article이 있다. 뉴스레터로 받아본 Article인데,
링크는 여기! : 웹 접근성 준수를 통한 모두에게 배달되는 일상의 행복

올바른 태그의 중요성

<div>home</div>
<button>home</button>
  • 동일한 스타일을 제공해 같은 버튼으로 보여도, 스크린 리더기에서는 div 태그가 버튼임을 알 수 없어 클릭할 수 있는 요소임을 알려주지 않는다.
    시각 장애를 가진 사용자는 홈 화면으로 이동할 수 없음
  • 그리고 button 태그에는 키보드 접근성이 내장되어 있지만, div 태그는 그렇지 않다.

이미지 대체 텍스트

이 부분이 정말 처음으로 알았던 부분이다...! 나는 alt 속성에 대체 텍스트를 무조건 제공해 줘야 되는 것이라고 생각했다. 그런데 단순 꾸밈 요소에 대한 대체 텍스트 제공은 오히려 정보 전달을 방해한다고...!!!

여기에서 대체 텍스트를 넣지 않는다는 것은!

<!-- 꾸밈요소 이미지 -->
<img src="꾸밈요소 이미지" />
  • 이렇게 아예 대체 텍스트를 넣지 않는다는 것이 아니다!!!
    정보 전달에 영향을 주지 않는 꾸밈 요소는 반드시 빈 alt 값을 제공해야 한다.
    그 이유는 : 스크린 리더기가 이미지의 alt 속성이 없는 경우 이미지명을 읽어주기 때문!!!

  • 그래서 내 코드를 추가적으로 수정하자면,

<header>
  <img src={이미지} alt="" />
  <p>상단 텍스트</p>
  <p>설명 텍스트</p>
</header>

프로젝트에서 사용된 이미지의 경우, 정보 전달에 영향을 주지 않는 단순 꾸밈 요소이기 때문에 저렇게 대체 텍스트를 비워줬다.



참고 사이트

0개의 댓글