- CLAUDE.md: 프로젝트 지침 파일 추가 (@import 방식으로 rules 참조) - docs/rules/html-structure.md: 시맨틱 HTML, 접근성, Vue 템플릿 구조 규칙 - docs/rules/tailwindcss-strategy.md: TailwindCSS v4 스타일링 전략 규칙 - docs/rules/nuxt-conventions.md: Nuxt 4 코딩 컨벤션 규칙 (라우팅/컴포저블/데이터패칭/Pinia 등) - docs/MARKUP_CONVENTION_GUIDE.md: 마크업 컨벤션 종합 가이드
21 KiB
이메일 발송용 HTML Table 코딩 Rules
Gmail, Naver Mail, Outlook 등 주요 이메일 클라이언트 호환 기준 최종 업데이트: 2026-04-07
왜 이메일 HTML은 특별한가?
이메일 클라이언트는 웹 브라우저와 다르게 동작한다.
| 클라이언트 | 렌더링 엔진 | 주요 제한 |
|---|---|---|
| Gmail (웹) | WebKit 기반 | <head> 스타일 일부 제거, <style> 지원 제한적 |
| Gmail (앱) | Gmail 자체 파서 | 외부 CSS 불가, 인라인 스타일 필수 |
| Outlook 2016~2021 | Microsoft Word (MSHTML) | Flexbox/Grid 미지원, CSS 한계 |
| Outlook 365 (웹) | WebKit | 비교적 현대적 |
| Naver Mail (웹) | WebKit 기반 | <style> 범위 제한 |
| Apple Mail | WebKit | 현대 CSS 대부분 지원 |
| Samsung Mail | WebKit 기반 | 대부분 지원 |
결론: 가장 제한적인 Outlook + Gmail 앱을 기준으로 코딩해야 한다.
빠른 참조 체크리스트
코드 작성 전/리뷰 시 아래 항목을 확인한다.
- 레이아웃에
<table>구조를 사용했는가? (Flexbox/Grid 금지) - 모든 스타일이 인라인(
style="")으로 작성되었는가? <table>에role="presentation"속성이 있는가?<table>에border="0" cellpadding="0" cellspacing="0"이 설정되어 있는가?- 너비를
width속성과style="width:"를 동시에 명시했는가? - 모든 색상이 6자리 HEX(
#ffffff)로 표기되어 있는가? (3자리,rgb(),rgba()금지) - 폰트에 웹 안전 폰트(fallback 포함)를 사용했는가?
- 이미지에
alt,width,height,border="0",display:block이 모두 있는가? - 전체 컨테이너 너비가 600px 이하인가?
<html>,<head>,<body>태그를 모두 포함했는가?<meta charset="UTF-8">과 viewport 메타 태그가 있는가?- MSO 조건부 주석(
<!--[if mso]>)으로 Outlook 버튼을 대응했는가? - 배경 이미지 대신 배경색(
bgcolor)을 주요 배경으로 사용했는가? <td>의line-height를 명시했는가? (Outlook 기본값 불일치)
규칙 상세
Rule 1: 기본 HTML 골격
모든 이메일 HTML은 아래 골격을 기반으로 시작한다.
DO: 표준 이메일 골격
<!DOCTYPE html>
<html lang="ko" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="x-apple-disable-message-reformatting" />
<title>이메일 제목</title>
<!--[if mso]>
<noscript>
<xml>
<o:OfficeDocumentSettings>
<o:PixelsPerInch>96</o:PixelsPerInch>
</o:OfficeDocumentSettings>
</xml>
</noscript>
<![endif]-->
<style>
/* 리셋 스타일: <head>에서만 전역 리셋 허용 */
* { box-sizing: border-box; }
body { margin: 0; padding: 0; width: 100% !important; }
img { -ms-interpolation-mode: bicubic; }
a { text-decoration: none; }
/* 모바일 반응형 */
@media only screen and (max-width: 600px) {
.email-container { width: 100% !important; }
.stack-on-mobile { display: block !important; width: 100% !important; }
.hide-on-mobile { display: none !important; }
.show-on-mobile { display: block !important; }
.full-width-image img { width: 100% !important; height: auto !important; }
}
</style>
</head>
<body style="margin: 0; padding: 0; background-color: #f4f4f4; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%;">
<!-- 이메일 미리보기 텍스트 (받은편지함 목록에서 표시) -->
<div style="display: none; max-height: 0; overflow: hidden; mso-hide: all;">
미리보기 텍스트가 여기에 표시됩니다. ‌ ‌ ‌ ‌ ‌
</div>
<!-- 이메일 전체 래퍼 테이블 -->
<table
role="presentation"
border="0"
cellpadding="0"
cellspacing="0"
width="100%"
style="background-color: #f4f4f4;"
>
<tr>
<td align="center" style="padding: 20px 10px;">
<!-- 이메일 본문 컨테이너 (최대 600px) -->
<table
class="email-container"
role="presentation"
border="0"
cellpadding="0"
cellspacing="0"
width="600"
style="max-width: 600px; width: 600px; background-color: #ffffff;"
>
<tr>
<td>
<!-- 섹션별 콘텐츠 삽입 -->
</td>
</tr>
</table>
</td>
</tr>
</table>
</body>
</html>
DON'T: 불완전한 골격
<!-- 금지: DOCTYPE, head 없이 body 내용만 작성 -->
<table>
<tr>
<td>내용</td>
</tr>
</table>
<!-- 금지: div로 레이아웃 구성 -->
<div style="max-width: 600px; margin: 0 auto;">
<div style="display: flex;">내용</div>
</div>
Rule 2: 레이아웃 - Table 구조 필수
이메일에서는 모든 레이아웃을 <table>로 구성한다. div, Flexbox, CSS Grid는 Outlook에서 동작하지 않는다.
열 분할 패턴
DO: 2열 레이아웃 (테이블 중첩)
<!-- 2열 레이아웃: 각 열을 <td>로 분리 -->
<table role="presentation" border="0" cellpadding="0" cellspacing="0" width="600">
<tr>
<!-- 왼쪽 열: 280px -->
<td
class="stack-on-mobile"
valign="top"
width="280"
style="width: 280px; padding: 16px;"
>
왼쪽 콘텐츠
</td>
<!-- 간격 열: 40px -->
<td width="40" style="width: 40px;"> </td>
<!-- 오른쪽 열: 280px -->
<td
class="stack-on-mobile"
valign="top"
width="280"
style="width: 280px; padding: 16px;"
>
오른쪽 콘텐츠
</td>
</tr>
</table>
DO: 헤더 / 본문 / 푸터 섹션 구조
<table role="presentation" border="0" cellpadding="0" cellspacing="0" width="600" style="width: 600px;">
<!-- 헤더 섹션 -->
<tr>
<td align="center" bgcolor="#1a56db" style="background-color: #1a56db; padding: 24px 32px;">
<img src="https://example.com/logo.png" alt="서비스명" width="120" height="40"
style="display: block; width: 120px; height: 40px; border: 0;" />
</td>
</tr>
<!-- 구분선 -->
<tr>
<td bgcolor="#e5e7eb" style="background-color: #e5e7eb; height: 1px; font-size: 0; line-height: 0;"> </td>
</tr>
<!-- 본문 섹션 -->
<tr>
<td style="padding: 40px 32px;">
<!-- 본문 콘텐츠 -->
</td>
</tr>
<!-- 구분선 -->
<tr>
<td bgcolor="#e5e7eb" style="background-color: #e5e7eb; height: 1px; font-size: 0; line-height: 0;"> </td>
</tr>
<!-- 푸터 섹션 -->
<tr>
<td align="center" bgcolor="#f9fafb" style="background-color: #f9fafb; padding: 24px 32px;">
<!-- 푸터 콘텐츠 -->
</td>
</tr>
</table>
DON'T: div 또는 Flexbox 사용
<!-- 금지: Outlook에서 깨짐 -->
<div style="display: flex; gap: 20px;">
<div style="flex: 1;">왼쪽</div>
<div style="flex: 1;">오른쪽</div>
</div>
<!-- 금지: CSS Grid 사용 -->
<div style="display: grid; grid-template-columns: 1fr 1fr;">
<div>왼쪽</div>
<div>오른쪽</div>
</div>
Rule 3: 인라인 스타일 필수 (CSS 클래스 금지)
Gmail 앱과 일부 이메일 클라이언트는 <head>의 <style> 블록을 제거한다. 모든 스타일은 인라인으로 작성한다.
<head>의 <style>은 모바일 반응형(@media)과 전역 리셋에만 허용한다.
DO: 인라인 스타일 사용
<td style="
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans KR', Arial, sans-serif;
font-size: 16px;
line-height: 1.6;
color: #111827;
padding: 24px 32px;
background-color: #ffffff;
">
안내 메시지가 여기에 들어갑니다.
</td>
DON'T: 클래스 기반 스타일
<!-- 금지: Gmail 앱에서 클래스 스타일이 제거됨 -->
<td class="content-cell">
안내 메시지
</td>
Rule 4: 색상 표기 규칙
이메일 클라이언트 간 색상 호환을 위해 표기 방식을 통일한다.
| 표기법 | 지원 여부 | 사용 여부 |
|---|---|---|
#ffffff (6자리 HEX) |
전체 클라이언트 | 사용 |
#fff (3자리 HEX) |
Outlook 일부 미지원 | 금지 |
rgb(255, 255, 255) |
Outlook 미지원 | 금지 |
rgba(255, 255, 255, 0.5) |
Outlook 미지원 | 금지 |
hsl(...) |
대부분 미지원 | 금지 |
색상명 (red, blue) |
일부만 지원 | 금지 |
DO: 6자리 HEX + bgcolor 이중 설정
<!-- bgcolor 속성(HTML 4)과 style 속성 동시 설정: 최대 호환성 -->
<td bgcolor="#1a56db" style="background-color: #1a56db;">
내용
</td>
<table bgcolor="#f9fafb" style="background-color: #f9fafb;">
...
</table>
DON'T: rgba 또는 3자리 HEX 사용
<!-- 금지: Outlook에서 렌더링 안 됨 -->
<td style="background-color: rgba(26, 86, 219, 0.9);">내용</td>
<td style="color: #fff;">내용</td>
Rule 5: 폰트 및 타이포그래피
웹 안전 폰트 스택 (한국어 지원)
<!-- 한국어 지원 폰트 스택 -->
<td style="
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans KR',
'Apple SD Gothic Neo', '맑은 고딕', Malgun Gothic, Arial, sans-serif;
font-size: 16px;
line-height: 1.6;
color: #111827;
">
한국어 텍스트
</td>
타이포그래피 규칙
| 속성 | 규칙 | 이유 |
|---|---|---|
font-size |
px 단위 사용 |
em/rem 클라이언트별 기준값 상이 |
line-height |
숫자 또는 px |
모든 <td>에 명시 (Outlook 기본값 문제) |
font-weight |
bold 또는 숫자 (700) |
둘 다 명시 권장 |
| 웹 폰트 | 사용 금지 | Gmail/Outlook 미지원, fallback만 렌더링됨 |
DO: 올바른 타이포그래피
<!-- 제목 -->
<h1 style="
margin: 0 0 16px 0;
font-family: -apple-system, 'Noto Sans KR', Arial, sans-serif;
font-size: 24px;
font-weight: bold;
line-height: 1.3;
color: #111827;
">
이메일 제목입니다
</h1>
<!-- 본문 단락 -->
<p style="
margin: 0 0 16px 0;
font-family: -apple-system, 'Noto Sans KR', Arial, sans-serif;
font-size: 15px;
line-height: 1.7;
color: #374151;
">
본문 텍스트 내용입니다.
</p>
<!-- 링크 -->
<a href="https://example.com" style="color: #1a56db; text-decoration: underline;">
링크 텍스트
</a>
DON'T: 웹 폰트, em 단위 사용
<!-- 금지: 웹 폰트 (대부분 이메일 클라이언트에서 fallback으로 치환됨) -->
<td style="font-family: 'Pretendard', sans-serif;">내용</td>
<!-- 금지: em 단위 (기준값이 클라이언트마다 다름) -->
<p style="font-size: 1em; line-height: 1.5em;">내용</p>
Rule 6: 이미지
DO: 올바른 이미지 태그
<!-- 모든 필수 속성 포함 -->
<img
src="https://example.com/images/banner.png"
alt="이벤트 배너: 7월 여름 세일 최대 50% 할인"
width="600"
height="200"
border="0"
style="
display: block;
width: 100%;
max-width: 600px;
height: auto;
border: 0;
outline: none;
text-decoration: none;
-ms-interpolation-mode: bicubic;
"
/>
이미지 필수 속성 체크리스트
| 속성 | 이유 |
|---|---|
src |
반드시 절대 경로(https://) 사용. 상대 경로 금지 |
alt |
이미지 차단 시 대체 텍스트 표시 |
width + height |
레이아웃 깨짐 방지 (HTML 속성 + style 이중 설정) |
border="0" |
IE/Outlook에서 이미지 링크 테두리 제거 |
display: block |
이미지 하단 여백(inline 기본값) 제거 |
-ms-interpolation-mode: bicubic |
IE/Outlook 이미지 보간 품질 향상 |
DON'T: 잘못된 이미지 사용
<!-- 금지: 상대 경로 사용 -->
<img src="/images/banner.png" alt="배너" />
<!-- 금지: width/height 누락 -->
<img src="https://example.com/banner.png" alt="배너" />
<!-- 금지: display:block 누락 (하단 여백 발생) -->
<img src="https://example.com/banner.png" alt="배너" width="600" height="200" />
<!-- 금지: alt 없음 (이미지 차단 시 빈 공간) -->
<img src="https://example.com/banner.png" width="600" height="200" style="display:block;" />
Rule 7: 버튼 (CTA)
Outlook은 CSS border-radius를 지원하지 않는다. 둥근 버튼은 VML(MSO 조건부 주석) 을 사용해야 한다.
DO: 크로스 클라이언트 버튼 (VML 포함)
<!-- 버튼 래퍼 td -->
<td align="center" style="padding: 24px 32px;">
<!--[if mso]>
<v:roundrect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word"
href="https://example.com/cta"
style="height:48px; v-text-anchor:middle; width:200px;"
arcsize="10%"
stroke="f"
fillcolor="#1a56db">
<w:anchorlock/>
<center style="color:#ffffff; font-family:Arial,sans-serif; font-size:15px; font-weight:bold;">
지금 시작하기
</center>
</v:roundrect>
<![endif]-->
<!--[if !mso]><!-->
<a
href="https://example.com/cta"
style="
display: inline-block;
padding: 14px 32px;
background-color: #1a56db;
color: #ffffff;
font-family: -apple-system, 'Noto Sans KR', Arial, sans-serif;
font-size: 15px;
font-weight: bold;
line-height: 1;
text-decoration: none;
border-radius: 6px;
mso-hide: all;
"
>
지금 시작하기
</a>
<!--<![endif]-->
</td>
DON'T: 버튼 이미지 사용, CSS만으로 구현
<!-- 금지: 이미지 버튼 (이미지 차단 시 CTA 소실) -->
<td>
<a href="https://example.com">
<img src="https://example.com/btn.png" alt="지금 시작하기" />
</a>
</td>
<!-- 금지: VML 없이 CSS border-radius만 사용 (Outlook에서 사각형으로 표시) -->
<a href="..." style="border-radius: 6px; background-color: #1a56db;">버튼</a>
Rule 8: 간격 조절
Outlook은 margin을 <td>, <table> 등에 신뢰할 수 없게 적용한다. 간격은 padding과 빈 <tr>을 활용한다.
DO: padding과 spacer tr로 간격 조절
<!-- padding으로 내부 여백 -->
<td style="padding: 24px 32px 0 32px;">
<h2 style="margin: 0 0 16px 0; ...">제목</h2>
<p style="margin: 0 0 16px 0; ...">본문</p>
</td>
<!-- spacer tr로 섹션 간 여백 -->
<tr>
<td style="height: 24px; font-size: 0; line-height: 0;"> </td>
</tr>
<!-- spacer td로 열 간격 -->
<td width="20" style="width: 20px; font-size: 0; line-height: 0;"> </td>
DON'T: margin에만 의존
<!-- 금지: table/td에 margin 사용 (Outlook에서 무시됨) -->
<table style="margin: 0 auto; margin-top: 24px;">
<tr>
<td style="margin-bottom: 16px;">내용</td>
</tr>
</table>
Rule 9: 모바일 반응형
이메일도 반응형이 필요하다. <head> <style>의 @media 쿼리를 활용한다.
DO: 모바일 반응형 패턴
<!-- head의 style 블록 -->
<style>
@media only screen and (max-width: 600px) {
/* 전체 너비로 확장 */
.email-container { width: 100% !important; }
/* 2열 -> 1열 스택 */
.stack-on-mobile {
display: block !important;
width: 100% !important;
}
/* 모바일에서 숨김 */
.hide-on-mobile { display: none !important; }
/* 모바일에서만 표시 */
.show-on-mobile {
display: block !important;
max-height: none !important;
}
/* 텍스트 크기 조정 */
.mobile-text-lg { font-size: 20px !important; line-height: 1.3 !important; }
.mobile-padding { padding: 16px !important; }
/* 이미지 전체 너비 */
.full-width-image img { width: 100% !important; height: auto !important; }
}
</style>
<!-- 2열 레이아웃 (모바일에서 스택으로) -->
<table role="presentation" border="0" cellpadding="0" cellspacing="0" width="600">
<tr>
<td class="stack-on-mobile" width="280" style="width: 280px; padding: 16px;">
왼쪽 콘텐츠
</td>
<td class="stack-on-mobile" width="280" style="width: 280px; padding: 16px;">
오른쪽 콘텐츠
</td>
</tr>
</table>
모바일/데스크탑 전용 콘텐츠
<!-- 데스크탑에서만 표시 -->
<tr class="hide-on-mobile">
<td>데스크탑 전용 콘텐츠</td>
</tr>
<!-- 모바일에서만 표시 (기본: max-height:0; overflow:hidden) -->
<tr class="show-on-mobile" style="display: none; max-height: 0; overflow: hidden; mso-hide: all;">
<td>모바일 전용 콘텐츠</td>
</tr>
Rule 10: 구분선 및 장식 요소
CSS border나 <hr>은 이메일 클라이언트마다 다르게 렌더링된다. 테이블 셀로 구분선을 만든다.
DO: 테이블 기반 구분선
<!-- 가로 구분선 -->
<tr>
<td
bgcolor="#e5e7eb"
style="background-color: #e5e7eb; height: 1px; font-size: 0; line-height: 0; mso-line-height-rule: exactly;"
>
</td>
</tr>
<!-- 여백 + 구분선 -->
<tr>
<td style="padding: 0 32px;">
<table role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
<td bgcolor="#e5e7eb" style="background-color: #e5e7eb; height: 1px; font-size: 0; line-height: 0;"> </td>
</tr>
</table>
</td>
</tr>
DON'T: hr 태그 또는 border 속성으로 구분선
<!-- 금지: hr은 클라이언트별 스타일 불일치 -->
<hr style="border: 1px solid #e5e7eb;" />
<!-- 금지: border-bottom으로 구분선 -->
<td style="border-bottom: 1px solid #e5e7eb;">내용</td>
Rule 11: 텍스트 이메일 대비 (접근성)
HTML 이메일은 반드시 텍스트 버전과 함께 발송한다(멀티파트 MIME). 이미지 차단 시에도 내용 전달이 가능해야 한다.
- 모든 이미지에 의미 있는
alt텍스트 작성 - 버튼/CTA는 텍스트 링크 형태로도 제공
- 중요 정보를 이미지에만 담지 않는다 (이미지 차단 시 소실)
Rule 12: Outlook 전용 조건부 주석 패턴
<!-- Outlook 전용 콘텐츠 -->
<!--[if mso]>
<table role="presentation" border="0" cellpadding="0" cellspacing="0">
<tr>
<td style="width: 600px;">
<![endif]-->
<!-- 비-Outlook 콘텐츠 -->
<!--[if !mso]><!-->
<div style="max-width: 600px;">
<!--<![endif]-->
<!-- ... 공통 콘텐츠 ... -->
<!--[if !mso]><!-->
</div>
<!--<![endif]-->
<!--[if mso]>
</td>
</tr>
</table>
<![endif]-->
금지사항 요약 (Anti-patterns)
| 금지 항목 | 대안 |
|---|---|
display: flex / display: grid |
<table> 레이아웃 |
position: absolute/fixed |
테이블 레이아웃으로 배치 |
background-image (배경) |
bgcolor + background-color |
border-radius (Outlook) |
VML <v:roundrect> |
3자리 HEX (#fff) |
6자리 HEX (#ffffff) |
rgb() / rgba() / hsl() |
6자리 HEX |
웹 폰트 (@font-face, Google Fonts) |
시스템 폰트 스택 |
em / rem 단위 |
px 단위 |
margin (table/td) |
padding + spacer td/tr |
<hr> 구분선 |
bgcolor td (height: 1px) |
| 이미지 상대 경로 | 절대 경로 (https://) |
<img> display 미설정 |
style="display: block;" |
| CSS 클래스만으로 스타일 | 인라인 스타일 + 클래스 병행 |
!important 남용 |
클라이언트별 조건부 주석 활용 |
자주 하는 실수 TOP 5
1. Outlook에서 버튼이 사각형으로 표시됨
border-radius는 Outlook Word 렌더러에서 무시된다. VML 조건부 주석으로 반드시 대응한다. (Rule 7 참조)
2. 이미지가 차단되었을 때 레이아웃 붕괴
이미지에 width, height, display: block을 모두 설정하지 않으면, 이미지 차단 시 레이아웃이 무너진다.
<!-- 반드시 width/height/display:block 명시 -->
<img src="..." alt="..." width="600" height="200"
style="display: block; width: 100%; max-width: 600px; height: auto; border: 0;" />
3. Outlook에서 줄 간격이 너무 좁거나 넓음
Outlook은 line-height 기본값이 다르다. 모든 <td> 에 line-height를 명시하고 mso-line-height-rule: exactly를 추가한다.
<td style="font-size: 15px; line-height: 24px; mso-line-height-rule: exactly;">
텍스트 내용
</td>
4. Gmail 앱에서 스타일이 전혀 적용되지 않음
Gmail 앱은 <head> <style> 블록을 완전히 제거한다. 레이아웃과 타이포그래피는 반드시 인라인 스타일로 작성한다.
5. 모바일에서 좁은 화면에 600px 고정 레이아웃
이메일 컨테이너에 width="600"과 함께 max-width: 600px을 설정하고, 모바일 반응형 클래스를 @media 쿼리로 관리한다.
<table class="email-container" width="600" style="width: 600px; max-width: 600px;">
@media only screen and (max-width: 600px) {
.email-container { width: 100% !important; }
}