알림 · 토스트 · 인라인 오류

매뉴얼 · docs/alert.md

페이지 배너 (.alert)

일반 안내는 role="status" · 오류·긴급은 role="alert"

안내

시스템 점검이 7월 26일 00:00~04:00에 예정되어 있습니다.

완료

신청이 정상적으로 접수되었습니다.

주의

첨부파일은 5MB 이하만 업로드할 수 있습니다.

토스트 (.toast)

우측 하단 · toastShow() 또는 data-toast · 포커스/호버 시 자동 닫기 일시 정지

링크(a)에도 data-toast를 그대로 쓸 수 있습니다. javascript:toastShow(…) 는 쓰지 마세요.

준비 중 메뉴 (링크 예시) 오픈 예정 (링크 예시)

* JS: toastShow('메시지', { type: 'success', duration: 4000 })

* 중요한 확인(삭제 등)은 토스트 대신 모달 alertdialog을 사용하세요.

* 실제 다른 페이지로 이동하는 링크에는 data-toast를 붙이지 마세요. (클릭과 동시에 페이지가 바뀝니다)

실서비스에 토스트 적용하기 (초보용 · 순서대로)

토스트 = 화면 우측 하단에 잠깐 나타났다가 사라지는 알림입니다. “저장되었습니다”처럼 확인 버튼이 필요 없는 짧은 안내에 씁니다. 아래만 따라 하면 됩니다.

0. 준비 — 이 킷에서 뭘 가져가나

실서비스 프로젝트 폴더로 다음을 복사합니다.

  • css/alert.css — 토스트 모양(위치·색)
  • js/common.js — 그중 /* ===== 12) 토스트 알림 구간
    (파일을 통째로 써도 되고, 토스트 관련 함수만 옮겨도 됩니다)
  • js/jquery-3.7.1.min.js (또는 프로젝트에 이미 있는 jQuery)
    → common.js의 토스트는 jQuery($)를 사용합니다

* 이 킷처럼 css/style.css에서 @import url(alert.css); 해도 되고, HTML에서 <link rel="stylesheet" href="/a11y/…/alert.css">로 직접 연결해도 됩니다.

1단계 — CSS · JS 연결

적용할 HTML 페이지의 <head>와 </body> 직전에 아래처럼 넣습니다. 순서가 중요합니다. jQuery → common.js.

<!-- head 안 -->
<link rel="stylesheet" href="/css/alert.css">
<!-- (이미 style.css에 alert를 import 중이면 link는 생략) -->

<!-- body 맨 아래, </body> 직전 -->
<script src="/js/jquery-3.7.1.min.js"></script>
<script src="/js/common.js"></script>

2단계 — 토스트가 붙을 자리 만들기 (필수에 가깝음)

토스트 메시지들은 #toastRegion 안에 쌓입니다. 사이트 공통 레이아웃(모든 페이지가 쓰는 footer 아래 등)에 딱 1번 넣으세요.

<!-- #wrap 밖, </body> 직전 · 스크립트보다 위 권장 -->
<div id="toastRegion"
     class="toast-region"
     aria-live="polite"
     aria-relevant="additions"
     aria-atomic="false"></div>

<script src="/js/jquery-3.7.1.min.js"></script>
<script src="/js/common.js"></script>

* aria-live="polite" 덕분에 스크린리더가 새 알림을 읽어 줍니다. 속성을 지우지 마세요.

* 이 마크업을 안 넣어도 toastShow가 자동으로 영역을 만들지만, 처음부터 HTML에 두는 것을 권장합니다.

3단계 — 알림을 띄우는 방법 (둘 중 하나)

방법 A — HTML만 (버튼 · 링크에 속성)

클릭하면 바로 토스트가 뜹니다. JS를 따로 안 짜도 됩니다. 버튼과 링크 모두 같은 속성을 씁니다.

<!-- 버튼 (저장·확인 등 “동작”) -->
<button type="button"
  data-toast="저장되었습니다."
  data-toast-type="success">
  저장
</button>

<!-- 링크: 준비 중·오픈 예정처럼 “아직 이동할 곳 없음” -->
<a href="#none"
  data-toast="준비 중입니다."
  data-toast-type="info">
  메뉴명
</a>

<!-- 표시 시간(ms)을 바꾸고 싶을 때 -->
<button type="button"
  data-toast="잠시 후 사라집니다."
  data-toast-type="info"
  data-toast-duration="6000">
  안내
</button>

* 이렇게 쓰지 마세요: href="/a11y/javascript:toastShow('준비중입니다.', { type: 'info' });"
→ 접근성·유지보수에 좋지 않은 방식입니다. 위처럼 data-toast를 쓰세요.

* 링크에 data-toast를 쓸 때 href는 #none 또는 #을 권장합니다. common.js가 클릭 시 페이지 이동을 막습니다.

* 진짜로 다른 URL로 가는 <a href="/board/…">에는 data-toast를 붙이지 마세요.

data-toast 속성
속성 필수 설명
data-toast 필수 화면에 보일 문구
data-toast-type 선택 info(기본) · success · warning · error
data-toast-duration 선택 자동으로 사라지기까지 시간(밀리초). 기본 4000(4초)

방법 B — JavaScript로 호출 (저장 성공·AJAX 후 등)

폼 제출·서버 응답 뒤에 “성공/실패”를 알려줄 때 씁니다. common.js가 로드된 뒤라면 어디서든 toastShow를 호출할 수 있습니다.

<script>
  // 가장 단순
  toastShow('저장되었습니다.', { type: 'success' });

  // 옵션 예시
  toastShow('처리 중 오류가 발생했습니다.', {
    type: 'error',     // info | success | warning | error
    duration: 6000,    // 6초 후 닫힘 · 0 이면 자동 닫기 없음
    closable: true     // 닫기 버튼 (기본 true)
  });

  // 예: 저장 버튼 클릭 후
  $('#saveBtn').on('click', function () {
    // …서버에 저장하는 코드…
    toastShow('저장되었습니다.', { type: 'success' });
  });
</script>
toastShow 옵션
옵션 기본값 설명
type 'info' 색·의미. error일 때는 스크린리더용 role="alert"
duration 4000 자동 닫힘(ms). 0이면 닫기 버튼으로만 닫음
closable true false면 닫기 버튼 없음

4단계 — 잘 됐는지 확인

  1. 브라우저로 페이지를 연다 (가능하면 로컬 서버 또는 HTTPS).
  2. 위의 데모처럼 data-toast 버튼을 클릭한다 → 우측 하단에 알림이 뜨는지 본다.
  3. 개발자 도구(F12) → Console에 toastShow('테스트', { type: 'success' });를 입력해 Enter → 동일하게 뜨면 JS 연결 성공.
  4. 알림에 마우스를 올리거나 Tab으로 닫기 버튼에 포커스하면 자동 닫힘이 잠시 멈춥니다.

자주 하는 실수

  • common.js를 jQuery보다 먼저 로드함 → $ is not defined 오류. jQuery 먼저.
  • alert.css를 안 넣음 → 토스트는 생기지만 위치가 깨지거나 스타일이 없음.
  • toastShow is not defined → common.js 경로가 틀렸거나 아직 로드 전에 호출함.
  • href="/a11y/javascript:toastShow(…)" 사용 → data-toast로 바꾸세요.
  • 삭제 확인·약관 동의처럼 사용자가 꼭 응답해야 하는 일에 토스트를 씀 → 모달(alertdialog)을 쓰세요.

최소 완성 예시 (한 페이지에 다 넣기)

<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <title>토스트 테스트</title>
  <link rel="stylesheet" href="/css/alert.css">
</head>
<body>
  <button type="button"
    data-toast="저장되었습니다."
    data-toast-type="success">저장</button>

  <div id="toastRegion" class="toast-region"
    aria-live="polite" aria-relevant="additions" aria-atomic="false"></div>

  <script src="/js/jquery-3.7.1.min.js"></script>
  <script src="/js/common.js"></script>
</body>
</html>

* 매뉴얼: docs/alert.md · 이 페이지 하단에도 실제 #toastRegion이 있습니다.

인라인 필드 오류 (.field-msg)

aria-invalid="true" + aria-describedby로 오류 문구 연결

예: name@example.com

이메일 형식이 올바르지 않습니다.

본인 이름을 입력하세요.

* 오류를 없앨 때 aria-invalid를 제거하고 오류 문구를 숨기거나 삭제합니다.