내용으로 건너뛰기 문서 내비게이션으로 건너뛰기
// Toasts

가볍고 쉽게 재정의할 수 있는 알림메시로 푸시 알림을 보냅니다.

토스트는 모바일 및 데스크톱 운영 체제에서 보급된 푸시 알림을 모방하여 설계된 가벼운 알림창 입니다. Flexbox로 만들어져 있어 위치 조정 및 배치가 간단합니다.

개요

토스트 플러그인을 사용할 때 알아두어야 할 사항:

  • 토스트는 퍼포먼스상의 이유로 opt-in 방식으로 되어 있기 때문에 스스로 초기화해야 합니다.
  • 토스트는 autohide: false를 지정하지 않으면 자동으로 숨겨집니다.
이 컴포넌트의 애니메이션 효과는 prefers-reduced-motion 미디어 쿼리에 따라 다릅니다. 접근성 문서의 모션 감소 문단을 참고하세요.

예시

기본

토스트의 확장성과 예측 가능성을 높이기 위해 header와 body 사용을 권장합니다. 토스트의 header는 display: flex를 사용하고 있으며, margin 과 flexbox 유틸리티를 통해 콘텐츠를 쉽게 정렬시킬 수 있습니다.

토스트는 필요에 따라 유연하게 대응할 수 있으며 필요한 마크업은 거의 없습니다. 토스트 콘텐츠를 포함하는 요소가 최소 하나는 있어야 하고 닫기 버튼은 강력히 권장합니다.

html
<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()
  })
}

반투명

토스트는 아래의 콘텐츠와 어울려져 보이도록 약간 비치게 보여집니다.

html
<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로 감싸면 여러 개 사용할 수 있습니다.

html
<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로 레이아웃을 조정해 보다 간단한 토스트를 만들고 있습니다.

html
<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>

또는 토스트에 추가적인 컨트롤이나 컴포넌트를 추가할 수도 있습니다.

html
<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>

색상 스키마

위의 예시를 바탕으로 colorbackground 유틸리티를 사용해 다른 토스트의 색상 배합을 만들 수 있습니다. 여기에서는 .toast.bg-primary를 추가하고, 닫기 버튼에는 .btn-close-white를 추가하고 있습니다. 선명한 모서리를 보여주기 위해 .border-0을 추가해 기본으로 제공한 모서리를 삭제하고 있습니다.

html
<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의 오른쪽에 넣어주세요.

Bootstrap 11 mins ago
Hello, world! This is a toast message.
html
<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 요소의 사용을 검토해 주세요.

html
<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 유틸리티를 사용해서 토스트를 수평 방향이나 수직 방향으로 정렬시킬 수도 있습니다.

html
<!-- 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를 사용해 주세요.

토스트가 생성되거나 업데이트 되기 에 라이브리전이 마크업에 존재해야 한다는 점에 주의하십시오. 두 가지를 동시에 동적으로 생성하여 페이지에 주입하면 일반적으로 지원기술을 통해 공지되지 않습니다.

그리고, 내용에 따라 rolearia-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를 사용할 때에는, 사용자가 토스트를 해제할 수 있도록 닫기 버튼을 추가해야 합니다.

html
<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 토스트를 숨기기 전 지연 시간(밀리초)을 설정합니다.

메소드

모든 API 메서드는 비동기식이며 전환을 시작합니다. 전환이 시작되는 즉시 호출자에게 반환되지만 전환이 끝나기 전에 호출자에게 반환됩니다. 또한 전환 중인 컴포넌트에 대한 메서드 호출은 무시됩니다. JavaScript 문서에서 자세히 알아보세요.
방법 설명
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 이벤트가 발생하기 전) 호출자에게 반환합니다. autohidefalse로 설정한 경우 이 메서드를 수동으로 호출해야 합니다.
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...
})