3P by GN⁺ 11일전 | ★ favorite | 댓글 1개
  • HTML에서는 인식되지 않는 태그 이름을 사용해도 브라우저가 이를 일반 요소로 처리함
  • CSS에서 해당 태그 이름을 선택자로 지정하면 스타일 지정과 표시 제어가 가능함
  • 하이픈(-)이 포함된 이름을 쓰면 미래 HTML 표준과의 충돌을 방지할 수 있음
  • <div><span> 대신 의미 있는 사용자 정의 태그를 쓰면 코드 가독성이 높아짐
  • 복잡한 중첩 구조에서도 태그 이름만으로 구조를 파악하기 쉬워, 유지보수가 용이함

사용자 정의 HTML 태그의 활용

  • 브라우저는 알 수 없는 태그를 일반 블록 요소처럼 렌더링함

    • 이는 HTML 표준에 명시된 정상 동작으로, CSS에서 스타일을 지정하면 시각적으로 제어 가능
    • 예시로 <cool-thing> 같은 태그를 정의하고 CSS에서 cool-thing { ... } 형태로 꾸밀 수 있음
  • 태그 이름에 하이픈(-) 을 포함하면 향후 HTML 표준에 추가될 가능성이 없어 충돌 위험이 없음

    • 예: <main-article>, <quote-body>

가독성과 구조 개선

  • <div><span> 대신 의미 있는 이름의 태그를 사용하면 코드 이해가 쉬워짐
    • 예를 들어 <div class="article-header"> 대신 <article-header>를 사용 가능
  • 중첩된 <div> 구조에서는 닫는 태그 위치를 파악하기 어렵지만, 명시적 태그 이름을 쓰면 구조가 명확해짐
    • <main-article> 내부에 <article-header>, <article-quote> 등으로 구성하면 DOM 구조 파악이 직관적

예시 코드

  • 기존 방식
    <div class="cool-thing">
      Hello, World!
    </div>
    
  • 사용자 정의 태그 방식
    <cool-thing>
      Hello, World!
    </cool-thing>
    
    • CSS에서 cool-thing { display: block; font-weight: bold; text-align: center; ... } 형태로 스타일 지정 가능

결론

  • HTML 표준이 허용하는 유연한 태그 정의 기능을 활용하면,
    가독성 높은 구조적 마크업을 작성할 수 있음
  • 단, 기존에 정의된 의미 있는 태그가 있을 경우에는 기존 태그 사용이 우선
Hacker News 의견들
  • <tag-name>은 인식되지 않는 태그가 아님을 강조함
    자신의 블로그 글을 소개하며, <tagname>은 WHATWG가 새 요소로 추가하기 전까지 HTMLUnknownElement로 처리되지만, <tag-name>유효한 HTMLElement로서 레이아웃과 스타일링에 유용하다고 설명함
    JavaScript Custom Elements API로 업그레이드하면 정의된 커스텀 요소가 됨
    모든 브라우저에서 표준 동작이며, W3C HTML Validator도 대시가 포함된 커스텀 요소를 HTMLElement로 인정함
    다만 기본 UA 스타일시트의 [hidden]{display:none} 규칙은 상속되지 않으므로 직접 지정해야 함
    <DIV>가 기본적으로 display:block인 것도 UA 스타일시트 덕분이므로, 커스텀 요소에는 직접 display 속성을 설정해야 함
    CSS의 :defined:not(:defined) 선택자를 통해 정의된/정의되지 않은 요소를 구분할 수 있음
    Declarative Shadow DOM(<template shadowrootmode="open">)도 동일하게 정의되지 않은 커스텀 요소를 생성함

    • Chromium 기준으로는 UA 스타일시트의 문제가 아니라, hiddenHTML 표현 속성(presentation attribute) 이기 때문이라고 반박함
      UA 스타일시트는 커스텀 요소에도 동일하게 적용되며, [hidden] 규칙은 존재하지 않음
      hiddenalign="right"처럼 속성 자체가 스타일로 해석되는 예시임
    • 대시(-) 대신 콜론(:) 을 쓸 수 있었다면 XML 네임스페이스를 자연스럽게 통합할 수 있었을 것이라 아쉬움을 표현함
      nginx나 apache에서 콜론을 하이픈으로 변환하는 것도 가능했을 것이라 언급함
      “1999년으로 돌아갈 수는 없지만”이라며 회상적인 어조로 마무리함
    • 왜 이런 방식이 기본 관행이 아닌지 의문을 제기함
  • 예시 코드의 <div> 중첩 구조가 과도하다고 지적함
    <article>, <header>, <blockquote>의미론적 태그를 쓰는 것이 더 적절하다고 제안함

    • 커스텀 태그는 클래스 속성과 달리 하나의 이름만 가질 수 있음을 지적함
      클래스는 여러 개를 가질 수 있고 순서가 없지만, 중첩된 커스텀 요소는 순서를 강제하므로 동일한 표현을 하기 어려움
    • “div soup”이 나쁜 게 아니라, HTML이 구조와 스타일을 강하게 결합한 설계 결정의 결과라고 분석함
      1996년에는 타당했지만 지금은 그렇지 않다고 평가함
  • 3~4년간 커스텀 요소를 사용해온 경험을 공유함
    아이디어는 영리하지만 실무에서는 까다로움
    너무 많은 커스텀 태그를 쓰면 가독성이 떨어지고, 블록/인라인 구분이 어려워짐
    균형 잡힌 접근법으로, 기본 태그는 그대로 쓰고, <x-card><x-hero>처럼 컴포넌트형 요소에만 커스텀 태그를 사용함
    하위 구성요소는 <div slot="hero-blurb">처럼 slot 속성으로 구분함
    클래스는 수정·커스터마이징 용도로만 제한하고, 구조는 slot으로 표현하는 방식을 선호함

    • 균형 잡힌 웹 컴포넌트 접근법에 관심이 많다며, 예시나 툴셋을 요청함
      자신이 만든 Good.HTML을 소개하며, 자동 훅(autohook)템플릿 리터럴 기반 인터폴레이션, 정렬된 컴포넌트 구조를 지원한다고 설명함
      < !app-header /> 같은 셀프 클로징 커스텀 요소도 주석 노드 트릭으로 구현했다고 덧붙임
    • CSS에서 slot 속성을 기준으로 선택하려면 div[slot="hero-blurb"]처럼 쓰면 된다고 질문함
    • 이 패턴이 BEM의 block–element 구조를 떠올리게 한다고 언급함
  • 기본적으로 커스텀 태그는 <span>처럼 동작함
    필요하면 Custom Element API를 통해 동작을 정의할 수 있음

    • 2014년에 커스텀 요소를 광범위하게 사용했으며, React가 대세가 된 것에 아쉬움을 표현함
      대부분의 사용자에게는 SPA보다 HTML+커스텀 요소 조합이 더 나았을 것이라 생각함
    • 의미론적 요소를 우선 사용하고, 필요할 때만 커스텀 요소를 쓰는 것이 좋다고 함
      자신이 만든 Hypalink 예시를 공유하며, Web Components의 저평가를 지적함
  • <yes-script>라는 커스텀 태그를 만들어 <noscript>의 반대 역할을 구현했다고 소개함
    JS가 비활성화된 경우 특정 영역을 숨길 수 있음
    프로젝트 링크를 공유함

    • CSS의 @media (scripting) 기능을 이용하면 순수 CSS만으로도 동일한 효과를 낼 수 있다고 제안함
      MDN 문서 참고 링크를 첨부함
  • 과거 브라우저에서 제거된 <blink> 태그를 직접 재현한 경험을 공유함
    jQuery와 visibility 조작으로 구현했으며, 브라우저가 임의 태그를 허용한다는 사실에 놀랐다고 함
    코드가 10줄 남짓이라 공개하지는 않았지만, 비슷한 시도가 많을 것이라 추측함

    • 실제로 대부분의 브라우저는 <blink>를 구현한 적이 없으며, Firefox와 Opera만 2013년까지 지원했다고 설명함
    • Flash가 사라진 것에 여전히 아쉬움을 표함
    • CSS만으로도 <blink> 효과를 낼 수 있다며 예시 코드를 공유함
      .blink 대신 blink 선택자를 쓰면 태그에 직접 적용된다고 함
    • <blink> 같은 동작은 단순한 HTML 요소로 제공되기엔 너무 큰 의미를 가진 기능이라며, 사라진 것을 반긴다고 밝힘
  • <main-article>, <article-header> 등의 예시는 실제 HTML 태그로 대체할 수 있다고 지적함
    <article>, <header>, <blockquote>를 쓰는 것이 더 적절함

    • 미리 정의된 HTML 태그를 쓰면 브라우저의 기본 스타일링 혜택도 함께 얻을 수 있다고 덧붙임
  • 커스텀 태그는 기본적으로 <span>처럼 인라인으로 렌더링되지만, CSS로 기본 display 속성을 지정하면 됨
    과거에는 네임스페이스 문제로 피했지만, 표준에서 하이픈(-)을 허용하면서 충돌 위험이 사라짐
    CSS 선택자에서도 문제없이 작동하며, querySelector로도 접근 가능함
    Vue 같은 프레임워크 없이도 현대 HTML만으로 충분히 표현 가능하다고 느낌

    • 하이픈이 포함된 비표준 요소는 HTMLUnknownElement가 아닌 HTMLElement로 처리된다고 보충함
      이는 향후 업그레이드 시 프로토타입 체인이 자연스럽게 확장되도록 하기 위한 설계임
  • 모든 커스텀 요소에 기본 스타일을 지정하려면 다음처럼 하면 됨

    :where(:not(:defined)) {
      display: block;
    }
    
    • 이 방법을 찾고 있었다며, 감탄과 감사를 표현함
  • 예전 IE는 HTML5 태그를 인식하지 못했기 때문에, 2010년경 자신이 만든 스크립트로 해결했다고 회상함
    JS로 태그를 한 번 생성하면 IE가 인식하게 되었고, 이후 삭제해도 문제없었음
    이 방식으로 임의의 태그도 렌더링 가능하다는 걸 깨달았다고 함
    당시 블로그 글을 함께 공유함

    • 인기 있었던 html5shim도 같은 방식으로 동작했다고 덧붙임