Skip to main content Skip to docs navigation

الإشعارات (Toasts)

أرسل إشعارات فورية إلى زوارك باستخدام الـ toast، وهي رسالة تنبيه خفيفة الوزن وسهلة التخصيص.

الـ Toasts هي إشعارات خفيفة الوزن مصممة لمحاكاة إشعارات الدفع (push notifications) التي شاعت في أنظمة تشغيل الهواتف المحمولة وأجهزة الكمبيوتر. لقد تم بناؤها باستخدام flexbox، لذا من السهل محاذاتها وتحديد موضعها.

نظرة عامة

أشياء يجب معرفتها عند استخدام إضافة الـ toast:

  • الـ Toasts اختيارية لأسباب تتعلق بالأداء، لذا يجب عليك تهيئتها بنفسك.
  • ستختفي الـ Toasts تلقائياً إذا لم تحدد autohide: false.

تعتمد تأثيرات الرسوم المتحركة لهذا المكوّن على استعلام الوسائط (media query) الخاص بـ prefers-reduced-motion. راجع قسم تقليل الحركة في مستندات إمكانية الوصول لدينا.

أمثلة

أساسي (Basic)

لتشجيع إنشاء إشعارات (toasts) قابلة للتوسيع ويمكن التنبؤ بها، نوصي باستخدام رأس (header) وجسم (body). تستخدم رؤوس الـ Toasts الخاصية display: flex ، مما يسمح بمحاذاة المحتوى بسهولة بفضل أدوات الهوامش والـ flexbox الخاصة بنا.

الـ Toasts مرنة بقدر ما تحتاج وتتطلب القليل جداً من علامات التكوين (markup). كحد أدنى، نحتاج إلى عنصر واحد يحتوي على محتواك (toasted) ونوصي بشدة بإضافة زر إغلاق.

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>

سابقاً، كانت السكربتات الخاصة بنا تضيف الفئة .hide ديناميكياً لإخفاء الإشعار (toast) تماماً (باستخدام display:none، بدلاً من مجرد opacity:0). هذا الأمر لم يعد ضرورياً الآن. ومع ذلك، ومن أجل التوافق مع الإصدارات السابقة، سيستمر السكربت الخاص بنا في تبديل الفئة (على الرغم من عدم وجود حاجة عملية لذلك) حتى الإصدار الرئيسي القادم.

مثال مباشر

انقر على الزر أدناه لإظهار إشعار (toast) (محدد الموضع باستخدام أدوات المساعدة الخاصة بنا في الزاوية اليمنى السفلية) والذي تم إخفاؤه افتراضياً.

<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 التالي لتشغيل العرض المباشر للإشعار (toast):

const toastTrigger = document.getElementById('liveToastBtn')
const toastLiveExample = document.getElementById('liveToast')

if (toastTrigger) {
  const toastBootstrap = bootstrap.Toast.getOrCreateInstance(toastLiveExample)
  toastTrigger.addEventListener('click', () => {
    toastBootstrap.show()
  })
}

شفاف (Translucent)

الـ Toasts شفافة قليلاً لتندمج مع ما يوجد خلفها.

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>

التكديس (Stacking)

يمكنك تكديس الـ toasts عن طريق تغليفها في حاوية إشعارات (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>

محتوى مخصص

قم بتخصيص الـ toasts الخاصة بك عن طريق إزالة المكونات الفرعية، أو تعديلها باستخدام أدوات المساعدة, أو عن طريق إضافة علامات التكوين (markup) الخاصة بك. هنا قمنا بإنشاء toast أبسط عن طريق إزالة الـ .toast-header الافتراضية، وإضافة أيقونة إخفاء مخصصة من أيقونات الـ (Bootstrap), واستخدام بعض أدوات flexbox المساعدة لضبط التخطيط.

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>

بدلاً من ذلك، يمكنك أيضاً إضافة عناصر تحكم ومكونات إضافية إلى الـ toasts.

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>

مخططات الألوان

بناءً على المثال السابق، يمكنك إنشاء مخططات ألوان مختلفة للـ toasts باستخدام أدوات المساعدة الخاصة بـ الألوان و الخلفيات. هنا قمنا بإضافة .text-bg-primary إلى .toast، ثم أضفنا .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>

الموضع (Placement)

ضع الـ toasts باستخدام 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>

بالنسبة للأنظمة التي تولد المزيد من الإشعارات، فكر في استخدام عنصر تغليف بحيث يمكن تكديسها بسهولة.

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 المساعدة لمحاذاة الـ toasts أفقياً و/أو رأسياً.

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>

إمكانية الوصول

الـ Toasts مصممة لتكون مقاطعات صغيرة لزوارك أو مستخدميك، لذا لمساعدة أولئك الذين يستخدمون قارئات الشاشة والتقنيات المساعدة المماثلة، يجب عليك تغليف الـ toasts الخاصة بك في منطقة aria-live (aria-live region). يتم الإعلان عن التغييرات في المناطق الحية (مثل حقن/تحديث مكون toast) تلقائياً بواسطة قارئات الشاشة دون الحاجة إلى نقل تركيز المستخدم أو مقاطعته. بالإضافة إلى ذلك، قم بتضمين aria-atomic="true" لضمان الإعلان عن الـ toast بالكامل دائماً كوحدة واحدة (ذرية)، بدلاً من الإعلان فقط عما تم تغييره (والذي قد يؤدي إلى مشاكل إذا قمت بتحديث جزء فقط من محتوى الـ toast، أو عند عرض نفس محتوى الـ toast في وقت لاحق). إذا كانت المعلومات المطلوبة مهمة للعملية، على سبيل المثال لقائمة من الأخطاء في نموذج، فاستخدم مكون التنبيه (alert component) بدلاً من الـ toast.

لاحظ أن المنطقة الحية يجب أن تكون موجودة في علامات التكوين (markup) قبل إنشاء الـ toast أو تحديثه. إذا قمت بإنشاء كليهما ديناميكياً في نفس الوقت وحقنتهما في الصفحة، فبشكل عام لن يتم الإعلان عنهما بواسطة التقنيات المساعدة.

تحتاج أيضاً إلى تكييف مستوى الـ role والـ aria-live اعتماداً على المحتوى. إذا كانت رسالة مهمة مثل خطأ، استخدم سمات role="alert" aria-live="assertive"، وإلا استخدم سمات role="status" aria-live="polite".

بينما يتغير المحتوى الذي تعرضه، تأكد من تحديث مهلة delay (#الخيارات) بحيث يكون لدى المستخدمين وقت كافٍ لقراءة الـ toast.

<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 ، يجب عليك إضافة زر إغلاق للسماح للمستخدمين بإغلاق الـ toast.

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>

من الناحية التقنية، من الممكن إضافة عناصر تحكم قابلة للتركيز/للتفاعل (مثل أزرار أو روابط إضافية) في الـ toast الخاص بك، ولكن يجب تجنب القيام بذلك في الـ toasts التي تختفي تلقائياً. حتى لو أعطيت الـ toast مهلة delay timeout طويلة، فقد يجد مستخدمو لوحة المفاتيح والتقنيات المساعدة صعوبة في الوصول إلى الـ toast في الوقت المناسب لاتخاذ إجراء (بما أن الـ toasts لا تستقبل التركيز عند عرضها). إذا كنت مضطراً تماماً لوضع عناصر تحكم إضافية، فنحن نوصي باستخدام toast مع autohide: false.

الـ (CSS)

المتغيرات (Variables)

تمت الإضافة في الإصدار v5.2.0

كجزء من نهج الـ CSS variables المتطور في Bootstrap، تستخدم الـ toasts الآن متغيرات CSS محلية على toast. لتعزيز التخصيص في الوقت الفعلي. يتم تعيين قيم متغيرات 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;

الإستخدام

قم بتهيئة الـ toasts عبر الـ JavaScript:

const toastElList = document.querySelectorAll('.toast')
const toastList = [...toastElList].map(toastEl => new bootstrap.Toast(toastEl, option))

القداحات/المشغلات (Triggers)

يمكن تحقيق الإغلاق باستخدام سمة data-bs-dismiss على زر داخل الـ toast كما هو موضح أدناه:

<button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>

أو على زر خارج الـ toast باستخدام data-bs-target الإضافية كما هو موضح أدناه:

<button type="button" class="btn-close" data-bs-dismiss="toast" data-bs-target="#my-toast" aria-label="Close"></button>

خيارات

بما أنه يمكن تمرير الخيارات عبر سمات البيانات (data attributes) أو الـ JavaScript، يمكنك إضافة اسم الخيار إلى -data-bs ، كما في "data-bs-animation="{value}. تأكد من تغيير نوع حالة اسم الخيار من “camelCase” إلى “kebab-case” عند تمرير الخيارات عبر سمات البيانات. على سبيل المثال، استخدم "data-bs-custom-class="beautifier بدلاً من "data-bs-customClass="beautifier.

بدءاً من Bootstrap 5.2.0، تدعم جميع المكونات سمة بيانات محجوزة تجريبية وهي data-bs-config والتي يمكن أن تحتوي على تكوين بسيط للمكون كسلسلة JSON. عندما يحتوي العنصر على سمات 'data-bs-config='{"delay":0, "title":123} و "data-bs-title="456، ستكون قيمة title النهائية هي 456 وستقوم سمات البيانات المنفصلة بتجاوز القيم المعطاة في data-bs-config. بالإضافة إلى ذلك، يمكن لسمات البيانات الموجودة أن تحتوي على قيم JSON مثل 'data-bs-delay='{"show":0,"hide":150}.

كائن التكوين النهائي هو النتيجة المدمجة لـ data-bs-config و -data-bs و js object حيث يقوم آخر مفتاح-قيمة مُعطى بتجاوز القيم الأخرى.

الاسمالنوعالإفتراضيالوصف
animationbooleantrueتطبيق انتقال تلاشي CSS على الـ toast.
autohidebooleantrueإخفاء الـ toast تلقائياً بعد انتهاء المهلة.
delaynumber5000المهلة بالملي ثانية قبل إخفاء الـ toast.

الطرق، الأساليب (Methods)

جميع دوال الـ API هي دوال غير متزامنة (asynchronous) وتبدأ عملية انتقال (transition). وهي تعود إلى المستدعي بمجرد بدء عملية الانتقال، ولكن قبل انتهائها. بالإضافة إلى ذلك، سيتم تجاهل أي استدعاء للدالة على مكوّن يمر حالياً بعملية انتقال. تعرف على المزيد في مستندات JavaScript الخاصة بنا.

الأسلوبالوصف
disposeيخفي الـ toast الخاص بالعنصر. سيبقى الـ toast الخاص بك في الـ DOM ولكنه لن يظهر بعد الآن.
getInstanceأسلوب Static يسمح لك بالحصول على نسخة الـ toast المرتبطة بعنصر DOM.
على سبيل المثال: const myToastEl = document.getElementById('myToastEl') const myToast = bootstrap.Toast.getInstance(myToastEl) يعيد نسخة من الـ Bootstrap toast.
getOrCreateInstanceأسلوب Static يسمح لك بالحصول على نسخة الـ toast المرتبطة بعنصر DOM، أو إنشاء نسخة جديدة في حال لم يتم تهيئتها.
const myToastEl = document.getElementById('myToastEl') const myToast = bootstrap.Toast.getOrCreateInstance(myToastEl) يعيد نسخة من الـ Bootstrap toast.
hideيخفي الـ toast الخاص بالعنصر. يعود إلى المستدعي قبل أن يتم إخفاء الـ toast فعلياً (أي قبل وقوع حدث hidden.bs.toast). يجب عليك استدعاء هذا الأسلوب يدوياً إذا قمت بتعيين autohide إلى false.
isShownيعيد قيمة منطقية (boolean) وفقاً لحالة ظهور الـ toast.
showيظهر الـ toast الخاص بالعنصر. يعود إلى المستدعي قبل أن يتم إظهار الـ toast فعلياً (أي قبل وقوع حدث shown.bs.toast). يجب عليك استدعاء هذا الأسلوب يدوياً، وإلا فلن يظهر الـ toast الخاص بك.

الأحداث (Events)

الحدثالوصف
hide.bs.toastيتم إطلاق هذا الحدث فور استدعاء أسلوب الـ hide الخاص بالنسخة.
hidden.bs.toastيتم إطلاق هذا الحدث عندما ينتهي إخفاء الـ toast عن المستخدم.
show.bs.toastيتم إطلاق هذا الحدث فور استدعاء أسلوب الـ show الخاص بالنسخة.
shown.bs.toastيتم إطلاق هذا الحدث عندما يصبح الـ toast مرئياً للمستخدم.
const myToastEl = document.getElementById('myToast')
myToastEl.addEventListener('hidden.bs.toast', () => {
  // do something...
})