퍼블리싱 가이드
웹 서비스 퍼블리싱 시 일관된 품질을 유지하기 위한 기본 가이드입니다.
목표는 아래 4가지입니다.
- 웹접근성, 웹표준을 지키는 마크업 작성
- 과한 연출보다 통일된 UI 효과 유지
- CSS/SCSS 재사용 구조로 구현 시간 단축
- 렌더링 성능과 사용자 체감 성능까지 함께 점검
1. 기본 원칙
1-1. 마크업은 의미 중심으로 작성
- 화면 모양보다 콘텐츠 의미를 먼저 표현합니다.
- 레이아웃을 위해 의미 없는 태그를 남발하지 않습니다.
- 가능한 경우 시맨틱 태그를 우선 사용합니다.
headernavmainsectionarticleasidefooter
- 제목 구조는 순서대로 사용합니다.
h1→h2→h3- 디자인 크기 때문에 제목 단계를 건너뛰지 않습니다.
1-2. 접근 가능한 UI를 기본값으로 생각
- 클릭 가능한 요소는 가능하면
button,a를 사용합니다. div,span에 클릭 이벤트만 넣는 방식은 지양합니다.- 폼 요소는 반드시
label과 연결합니다. - 이미지에는 목적에 맞는
alt를 작성합니다.- 정보 전달 이미지: 의미 있는
alt - 장식용 이미지:
alt=""
- 정보 전달 이미지: 의미 있는
- 키보드만으로도 주요 기능을 사용할 수 있어야 합니다.
- 포커스가 보이도록 처리합니다. 포커스 제거만 하고 대체 스타일을 주지 않는 방식은 금지합니다.
- 색상만으로 상태를 구분하지 않습니다.
1-3. 웹표준 준수
- HTML은 표준 속성과 구조를 우선합니다.
- 태그는 소문자 사용을 기본으로 합니다.
- 속성 의미에 맞는 요소를 씁니다.
- 인라인 스타일 남용을 피합니다.
- JS가 없어도 핵심 콘텐츠 확인이 가능하도록 구성합니다.
2. 접근성 체크 포인트
2-1. 텍스트와 정보 구조
- 페이지마다 핵심
h1은 명확하게 1개 사용 권장 - 본문은 제목/문단/목록 구조가 드러나야 함
- 링크 텍스트는 목적이 분명해야 함
- 나쁨:
자세히 보기 - 좋음:
병원 안내 자세히 보기
- 나쁨:
2-2. 버튼/링크
- 페이지 이동은
a - 동작 실행은
button - 아이콘 버튼은
aria-label또는 시각적으로 숨긴 텍스트 제공 - 비활성 상태는 시각 표현과 속성을 함께 반영
disabled,aria-disabled
2-3. 폼
placeholder만으로 라벨을 대체하지 않습니다.- 오류 메시지는 입력 요소와 연관되도록 구성합니다.
- 필수값은 시각적 표시와 함께 전달합니다.
- 도움말 문구, 에러 문구는 스크린리더 흐름도 고려합니다.
<label for="user-email">이메일</label>
<input id="user-email" type="email" aria-describedby="email-help email-error" />
<p id="email-help">로그인에 사용할 이메일을 입력해 주세요.</p>
<p id="email-error" class="form-error">올바른 이메일 형식이 아닙니다.</p>
2-4. 이미지/미디어
- 의미 있는 이미지는 대체 텍스트 제공
- 장식용 이미지는 빈 alt 사용
- 자동 재생은 최소화
- 영상은 가능하면 자막 제공
2-5. 모션/애니메이션
- 과한 이동, 튕김, 반복 애니메이션은 지양합니다.
- 사용성에 꼭 필요한 경우에만 짧고 단순하게 사용합니다.
prefers-reduced-motion환경을 고려합니다.
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}
3. UI 효과 가이드
3-1. 효과는 단순하고 통일되게
효과는 보여주기보다 상태 전달에 목적을 둡니다.
권장 원칙:
- duration은 짧게 유지
- easing은 공통값 사용
- hover, focus, active 반응은 동일한 규칙 사용
- 페이지마다 다른 애니메이션 스타일을 남발하지 않기
권장 기준:
- 기본 transition:
150ms ~ 250ms - easing:
ease,ease-out중심 - transform/opacity 중심 사용
- width, height, top, left 변경 애니메이션은 최소화
3-2. 추천 인터랙션 범위
- 버튼: 배경색, border-color, opacity 정도
- 카드: 미세한 shadow 변화, 살짝 위로 이동
- 모달/레이어: opacity + translateY 정도
- 아코디언: 높이 애니메이션 남용보다 자연스러운 열림/닫힘 우선
$motion-duration-fast: 150ms;
$motion-duration-base: 200ms;
$motion-ease: ease-out;
.button,
.card,
.input,
.modal {
transition:
color $motion-duration-base $motion-ease,
background-color $motion-duration-base $motion-ease,
border-color $motion-duration-base $motion-ease,
opacity $motion-duration-fast $motion-ease,
transform $motion-duration-fast $motion-ease,
box-shadow $motion-duration-base $motion-ease;
}
4. CSS / SCSS 작성 규칙
4-1. 토큰 먼저 정의
색상, 간격, radius, z-index, shadow, duration은 반복 입력하지 말고 토큰화합니다.
$color-primary: #2563eb;
$color-text: #111827;
$color-muted: #6b7280;
$color-border: #d1d5db;
$color-danger: #dc2626;
$space-4: 4px;
$space-8: 8px;
$space-12: 12px;
$space-16: 16px;
$space-24: 24px;
$radius-sm: 6px;
$radius-md: 10px;
$radius-lg: 16px;
4-2. CSS Custom Properties와 병행 권장
테마 변경 가능성이 있으면 CSS 변수 기반으로 설계합니다.
:root {
--color-primary: #2563eb;
--color-text: #111827;
--color-bg: #ffffff;
--radius-md: 10px;
--motion-duration: 200ms;
}
4-3. mixin / function 적극 활용
반복되는 패턴은 함수화해서 퍼블리싱 시간을 줄입니다.
@function rem($px, $base: 16) {
@return calc($px / $base) * 1rem;
}
@mixin flex-center($inline: false) {
display: if($inline, inline-flex, flex);
align-items: center;
justify-content: center;
}
@mixin ellipsis($line: 1) {
overflow: hidden;
@if $line == 1 {
white-space: nowrap;
text-overflow: ellipsis;
} @else {
display: -webkit-box;
-webkit-line-clamp: $line;
-webkit-box-orient: vertical;
}
}
4-4. nesting은 3단계 이내 권장
- SCSS nesting이 깊어질수록 유지보수가 어려워집니다.
- 구조보다 컴포넌트 기준으로 클래스를 설계합니다.
4-5. 선택자 우선순위는 낮게 유지
- 태그 + 클래스 + 자손 선택자 과도한 중첩 지양
!important는 예외 상황에서만 사용- 상태는 modifier 클래스로 관리
- 예:
.button.is-disabled,.input.has-error
- 예:
5. 반응형 가이드
- 모바일 우선 작성
- 브레이크포인트는 최소한으로 운영
- 고정 높이/고정 폭 최소화
- 텍스트 증가와 운영 데이터 길이 증가를 고려
6. 성능 가이드
6-1. 렌더링 비용이 큰 스타일 주의
가급적 아래 속성 애니메이션은 최소화합니다.
widthheighttopleftmargin
권장:
transformopacity
6-2. 이미지 최적화
- 필요한 크기로 리사이즈
- 가능하면 WebP/AVIF 사용 검토
- lazy loading 적용 검토
width,height명시로 레이아웃 점프 방지
<img
src="/images/banner.webp"
alt="봄 프로모션 배너"
loading="lazy"
width="1200"
height="400"
/>
6-3. Core Web Vitals 기준 참고
- LCP: 2.5초 이하 권장
- INP: 200ms 이하 권장
- CLS: 0.1 이하 권장
퍼블리싱 단계에서 아래 항목을 같이 점검합니다.
- 첫 화면 큰 이미지/배너 과도하지 않은지
- 레이아웃 점프가 발생하지 않는지
- 버튼/입력 인터랙션이 무겁지 않은지
- 폰트/스크립트 로딩 때문에 첫 렌더가 지연되지 않는지
7. 팀 공통 운영 규칙 제안
- 클릭 동작은
button, 이동은a - 모든 폼 요소는
label연결 필수 - 모든 컴포넌트는
focus-visible상태 제공 - transition duration/easing 공통 토큰 사용
- spacing/color/radius/shadow는 하드코딩 최소화
- 공통 mixin/function 먼저 찾고 없으면 추가
- 새 UI는 접근성/반응형/성능까지 같이 리뷰
- 장식용 애니메이션은 최소화
- 이미지 width/height 명시 기본화
- 퍼블리싱 완료 전 Lighthouse/접근성 기본 점검 수행
함께 보면 좋은 문서
참고 기준
- W3C WCAG 2.2 Quick Reference
- MDN HTML 기본 문법 및 시맨틱 마크업 가이드
- MDN CSS Custom Properties 가이드
- web.dev Web Vitals / Core Web Vitals 가이드