토스트는 모바일 및 데스크톱 운영 체제에서 보급된 푸시 알림을 모방하여 설계된 가벼운 알림창 입니다. Flexbox로 만들어져 있어 위치 조정 및 배치가 간단합니다.
개요
토스트 플러그인을 사용할 때 알아두어야 할 사항:
- 토스트는 퍼포먼스상의 이유로 opt-in 방식으로 되어 있기 때문에 스스로 초기화해야 합니다.
- 토스트는
autohide: false
를 지정하지 않으면 자동으로 숨겨집니다.
prefers-reduced-motion
미디어 쿼리에 따라 다릅니다. 접근성 문서의 모션 감소 문단을 참고하세요.
예시
기본
토스트의 확장성과 예측 가능성을 높이기 위해 header와 body 사용을 권장합니다. 토스트의 header는 display: flex
를 사용하고 있으며, margin 과 flexbox 유틸리티를 통해 콘텐츠를 쉽게 정렬시킬 수 있습니다.
토스트는 필요에 따라 유연하게 대응할 수 있으며 필요한 마크업은 거의 없습니다. 토스트 콘텐츠를 포함하는 요소가 최소 하나는 있어야 하고 닫기 버튼은 강력히 권장합니다.
<div class="toast" role="alert" aria-live="assertive" aria-atomic="true">
<div class="toast-header">
<img src="..." class="rounded me-2" alt="...">
<strong class="me-auto">Bootstrap</strong>
<small>11 mins ago</small>
<button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
</div>
<div class="toast-body">
Hello, world! This is a toast message.
</div>
</div>
opacity:0
이 아닌 display:none
으로) .hide
클래스를 동적으로 추가했습니다. 이것은 이제 더 이상 필요하지 않습니다. 그러나 이전 버전과의 호환성을 위해 스크립트는 다음 메이저 버전 전까지 클래스를 계속 토글합니다 (실제로 필요하지는 않음).
실시간
아래 버튼을 클릭하면 기본적으로 숨겨져 있는 알림 (오른쪽 하단 모서리에 있는 유틸리티와 함께 위치함)을 표시합니다.
<button type="button" class="btn btn-primary" id="liveToastBtn">Show live toast</button>
<div class="toast-container position-fixed bottom-0 end-0 p-3">
<div id="liveToast" class="toast" role="alert" aria-live="assertive" aria-atomic="true">
<div class="toast-header">
<img src="..." class="rounded me-2" alt="...">
<strong class="me-auto">Bootstrap</strong>
<small>11 mins ago</small>
<button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
</div>
<div class="toast-body">
Hello, world! This is a toast message.
</div>
</div>
</div>
다음 JavaScript를 사용하여 라이브 토스트 데모를 트리거할 수 있습니다:
const toastTrigger = document.getElementById('liveToastBtn')
const toastLiveExample = document.getElementById('liveToast')
if (toastTrigger) {
const toastBootstrap = bootstrap.Toast.getOrCreateInstance(toastLiveExample)
toastTrigger.addEventListener('click', () => {
toastBootstrap.show()
})
}
반투명
토스트는 아래의 콘텐츠와 어울려져 보이도록 약간 비치게 보여집니다.
<div class="toast" role="alert" aria-live="assertive" aria-atomic="true">
<div class="toast-header">
<img src="..." class="rounded me-2" alt="...">
<strong class="me-auto">Bootstrap</strong>
<small class="text-body-secondary">11 mins ago</small>
<button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
</div>
<div class="toast-body">
Hello, world! This is a toast message.
</div>
</div>
중첩
토스트를 toast container
로 감싸면 여러 개 사용할 수 있습니다.
<div class="toast-container position-static">
<div class="toast" role="alert" aria-live="assertive" aria-atomic="true">
<div class="toast-header">
<img src="..." class="rounded me-2" alt="...">
<strong class="me-auto">Bootstrap</strong>
<small class="text-body-secondary">just now</small>
<button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
</div>
<div class="toast-body">
See? Just like this.
</div>
</div>
<div class="toast" role="alert" aria-live="assertive" aria-atomic="true">
<div class="toast-header">
<img src="..." class="rounded me-2" alt="...">
<strong class="me-auto">Bootstrap</strong>
<small class="text-body-secondary">2 seconds ago</small>
<button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
</div>
<div class="toast-body">
Heads up, toasts will stack automatically
</div>
</div>
</div>
사용자 지정 콘텐츠
서브 컴포넌트를 삭제하거나, utilities로 조정하거나, 독자적인 마크업을 추가하여 토스트를 재정의할 수 있습니다. 아래 예시에서는, 기본 제공하는 .toast-header
를 삭제하고 Bootstrap Icons을 사용하여 사용자 정의 숨김 아이콘을 추가하고 flexbox utilities로 레이아웃을 조정해 보다 간단한 토스트를 만들고 있습니다.
<div class="toast align-items-center" role="alert" aria-live="assertive" aria-atomic="true">
<div class="d-flex">
<div class="toast-body">
Hello, world! This is a toast message.
</div>
<button type="button" class="btn-close me-2 m-auto" data-bs-dismiss="toast" aria-label="Close"></button>
</div>
</div>
또는 토스트에 추가적인 컨트롤이나 컴포넌트를 추가할 수도 있습니다.
<div class="toast" role="alert" aria-live="assertive" aria-atomic="true">
<div class="toast-body">
Hello, world! This is a toast message.
<div class="mt-2 pt-2 border-top">
<button type="button" class="btn btn-primary btn-sm">Take action</button>
<button type="button" class="btn btn-secondary btn-sm" data-bs-dismiss="toast">Close</button>
</div>
</div>
</div>
색상 스키마
위의 예시를 바탕으로 color와 background 유틸리티를 사용해 다른 토스트의 색상 배합을 만들 수 있습니다. 여기에서는 .toast
에 .bg-primary
를 추가하고, 닫기 버튼에는 .btn-close-white
를 추가하고 있습니다. 선명한 모서리를 보여주기 위해 .border-0
을 추가해 기본으로 제공한 모서리를 삭제하고 있습니다.
<div class="toast align-items-center text-bg-primary border-0" role="alert" aria-live="assertive" aria-atomic="true">
<div class="d-flex">
<div class="toast-body">
Hello, world! This is a toast message.
</div>
<button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast" aria-label="Close"></button>
</div>
</div>
배치
필요에 따라 사용자 지정 CSS로 토스트를 배치시킵니다. 우측 상단은 알림용으로 사용되는 경우가 많으며, 상단 중앙도 마찬가지입니다. 한번에 하나의 토스트 밖에 표시하지 않는다면, 배치 스타일을 .toast
의 오른쪽에 넣어주세요.
<form>
<div class="mb-3">
<label for="selectToastPlacement">Toast placement</label>
<select class="form-select mt-2" id="selectToastPlacement">
<option value="" selected>Select a position...</option>
<option value="top-0 start-0">Top left</option>
<option value="top-0 start-50 translate-middle-x">Top center</option>
<option value="top-0 end-0">Top right</option>
<option value="top-50 start-0 translate-middle-y">Middle left</option>
<option value="top-50 start-50 translate-middle">Middle center</option>
<option value="top-50 end-0 translate-middle-y">Middle right</option>
<option value="bottom-0 start-0">Bottom left</option>
<option value="bottom-0 start-50 translate-middle-x">Bottom center</option>
<option value="bottom-0 end-0">Bottom right</option>
</select>
</div>
</form>
<div aria-live="polite" aria-atomic="true" class="bg-body-secondary position-relative bd-example-toasts rounded-3">
<div class="toast-container p-3" id="toastPlacement">
<div class="toast">
<div class="toast-header">
<img src="..." class="rounded me-2" alt="...">
<strong class="me-auto">Bootstrap</strong>
<small>11 mins ago</small>
</div>
<div class="toast-body">
Hello, world! This is a toast message.
</div>
</div>
</div>
</div>
더 많은 알림을 만드는 시스템에서는 쉽게 쌓이게 하도록 wrapping 요소의 사용을 검토해 주세요.
<div aria-live="polite" aria-atomic="true" class="position-relative">
<!-- Position it: -->
<!-- - `.toast-container` for spacing between toasts -->
<!-- - `top-0` & `end-0` to position the toasts in the upper right corner -->
<!-- - `.p-3` to prevent the toasts from sticking to the edge of the container -->
<div class="toast-container top-0 end-0 p-3">
<!-- Then put toasts within -->
<div class="toast" role="alert" aria-live="assertive" aria-atomic="true">
<div class="toast-header">
<img src="..." class="rounded me-2" alt="...">
<strong class="me-auto">Bootstrap</strong>
<small class="text-body-secondary">just now</small>
<button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
</div>
<div class="toast-body">
See? Just like this.
</div>
</div>
<div class="toast" role="alert" aria-live="assertive" aria-atomic="true">
<div class="toast-header">
<img src="..." class="rounded me-2" alt="...">
<strong class="me-auto">Bootstrap</strong>
<small class="text-body-secondary">2 seconds ago</small>
<button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
</div>
<div class="toast-body">
Heads up, toasts will stack automatically
</div>
</div>
</div>
</div>
또한 flexbox 유틸리티를 사용해서 토스트를 수평 방향이나 수직 방향으로 정렬시킬 수도 있습니다.
<!-- Flexbox container for aligning the toasts -->
<div aria-live="polite" aria-atomic="true" class="d-flex justify-content-center align-items-center w-100">
<!-- Then put toasts within -->
<div class="toast" role="alert" aria-live="assertive" aria-atomic="true">
<div class="toast-header">
<img src="..." class="rounded me-2" alt="...">
<strong class="me-auto">Bootstrap</strong>
<small>11 mins ago</small>
<button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
</div>
<div class="toast-body">
Hello, world! This is a toast message.
</div>
</div>
</div>
접근성
토스트는 방텍스트가 사용자에게 방해가 되지 않도록 하기 위해 스크린 리더나 동일한 지원 기술을 사용하는 사람을 돕기 위해 토스트를 aria-live
region로 감싸줘야 합니다. 라이브 리젼으로의 변경(토스트 컴포넌트 주입/갱신 등)은 사용자의 포커스를 이동시키거나 사용자를 중단시키지 않고 스크린 리더에 의해 자동으로 안내됩니다. 게다가 aria-atomic="true"
를 포함함으로써 변경된 내용만 안내되는것이 아니라 토스트 전체가 항상 하나의(atomic) 유닛으로서 안내되게 됩니다.(토스트의 콘텐츠 일부만을 갱신한 경우나 같은 토스트의 콘텐츠를 나중의 시점에서 표시한 경우 등 문제가 생길수 있습니다) 필요한 정보가 프로세스에 중요한 경우, 예를 들어 폼 오류 목록 등의 경우는 토스트 대신 alert component를 사용해 주세요.
토스트가 생성되거나 업데이트 되기 전에 라이브리전이 마크업에 존재해야 한다는 점에 주의하십시오. 두 가지를 동시에 동적으로 생성하여 페이지에 주입하면 일반적으로 지원기술을 통해 공지되지 않습니다.
그리고, 내용에 따라 role
과 aria-live
의 레벨을 조정할 필요가 있습니다. 만약 오류와 같은 중요한 메세지라면 role="alert" aria-live="assertive"
속성을 사용하고, 그렇지 않으면 role="status" aria-live="polite"
속성을 사용합니다.
보여지는 콘텐츠가 바뀌면 사용자가 토스트를 읽기에 충분한 시간이 필요하므로 delay
타임아웃을 반드시 업데이트 해주세요.
<div class="toast" role="alert" aria-live="polite" aria-atomic="true" data-bs-delay="10000">
<div role="alert" aria-live="assertive" aria-atomic="true">...</div>
</div>
autohide: false
를 사용할 때에는, 사용자가 토스트를 해제할 수 있도록 닫기 버튼을 추가해야 합니다.
<div role="alert" aria-live="assertive" aria-atomic="true" class="toast" data-bs-autohide="false">
<div class="toast-header">
<img src="..." class="rounded me-2" alt="...">
<strong class="me-auto">Bootstrap</strong>
<small>11 mins ago</small>
<button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
</div>
<div class="toast-body">
Hello, world! This is a toast message.
</div>
</div>
기술적으로 토스트 안에 포커스나 액션이 가능한 컨트롤(추가 버튼이나 링크 등)을 추가할 수는 있지만, 자동 숨김 토스트에서는 이 사용을 피해 주세요. 토스트에 긴 delay
타임아웃를 주었다고 하더라도 키보드나 지원 기술 사용자가 알 수 있게 토스트까지(토스트는 표시된 시점에는 포커스를 받지 않기 때문에) 가기는 어려울 수 있습니다. 컨트롤이 필요한 경우에는 토스트에 반드시 autohide: false
를 사용하는 것을 권장합니다.
CSS
변수
v5.2.0에서 추가됨Bootstrap의 진화하는 CSS 변수 접근 방식의 일환으로, 이제 토스트에서 .toast
의 로컬 CSS 변수를 사용하여 실시간 사용자 정의 기능을 강화합니다. CSS 변수의 값은 Sass를 통해 설정되므로 Sass 사용자 정의도 계속 지원됩니다.
--#{$prefix}toast-zindex: #{$zindex-toast};
--#{$prefix}toast-padding-x: #{$toast-padding-x};
--#{$prefix}toast-padding-y: #{$toast-padding-y};
--#{$prefix}toast-spacing: #{$toast-spacing};
--#{$prefix}toast-max-width: #{$toast-max-width};
@include rfs($toast-font-size, --#{$prefix}toast-font-size);
--#{$prefix}toast-color: #{$toast-color};
--#{$prefix}toast-bg: #{$toast-background-color};
--#{$prefix}toast-border-width: #{$toast-border-width};
--#{$prefix}toast-border-color: #{$toast-border-color};
--#{$prefix}toast-border-radius: #{$toast-border-radius};
--#{$prefix}toast-box-shadow: #{$toast-box-shadow};
--#{$prefix}toast-header-color: #{$toast-header-color};
--#{$prefix}toast-header-bg: #{$toast-header-background-color};
--#{$prefix}toast-header-border-color: #{$toast-header-border-color};
Sass 변수
$toast-max-width: 350px;
$toast-padding-x: .75rem;
$toast-padding-y: .5rem;
$toast-font-size: .875rem;
$toast-color: null;
$toast-background-color: rgba(var(--#{$prefix}body-bg-rgb), .85);
$toast-border-width: var(--#{$prefix}border-width);
$toast-border-color: var(--#{$prefix}border-color-translucent);
$toast-border-radius: var(--#{$prefix}border-radius);
$toast-box-shadow: var(--#{$prefix}box-shadow);
$toast-spacing: $container-padding-x;
$toast-header-color: var(--#{$prefix}secondary-color);
$toast-header-background-color: rgba(var(--#{$prefix}body-bg-rgb), .85);
$toast-header-border-color: $toast-border-color;
사용 방법
JavaScript를 통해 초기화:
const toastElList = document.querySelectorAll('.toast')
const toastList = [...toastElList].map(toastEl => new bootstrap.Toast(toastEl, option))
트리거
해제는 아래와 같이 toast 내에서 버튼의 data-bs-dismiss
속성을 사용하여 수행할 수 있습니다.
<button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
또는 아래와 같이 data-bs-target
을 사용하여 toast 외부의 버튼에서도 수행할 수 있습니다:
<button type="button" class="btn-close" data-bs-dismiss="toast" data-bs-target="#my-toast" aria-label="Close"></button>
옵션
옵션은 데이터 속성이나 JavaScript를 통해 전달할 수 있으므로 data-bs-
에 옵션 이름을 추가할 수 있습니다(예: data-bs-animation="{value}"
). 데이터 속성을 통해 옵션을 전달할 때 옵션 이름의 대/소문자 유형을 ‘camelCase‘에서 ‘kebab-case‘로 변경해야 합니다. 예를 들어 data-bs-custom-class="beautifier"
대신 data-bs-customClass="beautifier"
를 사용합니다.
Bootstrap 5.2.0부터 모든 컴포넌트는 간단한 컴포넌트 구성을 JSON 문자열로 저장할 수 있는 experimental 예약 데이터 속성 data-bs-config
를 지원합니다. 요소에 data-bs-config='{"delay":0,"title":123}'
및 data-bs-title="456"
속성이 있는 경우 최종 title
값은 456
이 되며 별도의 데이터 속성이 data-bs-config
에 지정된 값을 재정의합니다. 또한 기존 데이터 속성에는 data-bs-delay='{"show":0,"hide":150}'
와 같은 JSON 값을 저장할 수 있습니다.
최종 구성 개체는 data-bs-config
, data-bs-
, js object
의 병합된 결과로, 주어진 최신 key-value가 다른 key-value를 재정의합니다.
이름 | 유형 | 기본값 | 설명 |
---|---|---|---|
animation |
boolean | true |
토스트에 CSS 페이드 전환을 적용합니다. |
autohide |
boolean | true |
지연 후 자동으로 토스트를 숨깁니다. |
delay |
number | 5000 |
토스트를 숨기기 전 지연 시간(밀리초)을 설정합니다. |
메소드
방법 | 설명 |
---|---|
dispose |
요소의 토스트를 숨깁니다. 토스트는 DOM에 남아 있지만 더 이상 표시되지 않습니다. |
getInstance |
정적 메서드를 사용하여 DOM 엘리먼트와 연관된 토스트 인스턴스를 가져올 수 있습니다. 예: const myToastEl = document.getElementById('myToastEl') const myToast = bootstrap.Toast.getInstance(myToastEl) 는 Bootstrap 토스트 인스턴스를 반환합니다. |
getOrCreateInstance |
정적 메서드를 사용하여 DOM 요소와 연결된 토스트 인스턴스를 가져오거나 초기화되지 않은 경우 새 인스턴스를 생성할 수 있습니다. const myToastEl = document.getElementById('myToastEl') const myToast = bootstrap.Toast.getOrCreateInstance(myToastEl) 는 Bootstrap 토스트 인스턴스를 반환합니다. |
hide |
요소의 토스트를 숨깁니다. 토스트가 실제로 숨겨지기 전(즉, hidden.bs.toast 이벤트가 발생하기 전) 호출자에게 반환합니다. autohide 를 false 로 설정한 경우 이 메서드를 수동으로 호출해야 합니다. |
isShown |
토스트의 가시성 상태에 따라 boolean을 반환합니다. |
show |
요소의 토스트를 표시합니다. 토스트가 실제로 표시되기 전(즉, shown.bs.toast 이벤트가 발생하기 전) 호출자에게 반환합니다. 이 메서드는 수동으로 호출해야 하며, 그렇지 않으면 토스트가 표시되지 않습니다. |
이벤트
이벤트 | 설명 |
---|---|
hide.bs.toast |
이 이벤트는 hide 인스턴스 메서드가 호출될 때 즉시 발생합니다. |
hidden.bs.toast |
이 이벤트는 토스트가 사용자에게 숨겨지는 것이 완료되면 발생합니다. |
show.bs.toast |
이 이벤트는 show 인스턴스 메서드가 호출될 때 즉시 발생합니다. |
shown.bs.toast |
이 이벤트는 토스트가 사용자에게 표시되었을 때 발생합니다. |
const myToastEl = document.getElementById('myToast')
myToastEl.addEventListener('hidden.bs.toast', () => {
// do something...
})