إطار Bootstrap 5

الرؤية والتفاعلات

13 دقيقة الدرس 38 من 40

الرؤية والتفاعلات

يوفر Bootstrap فئات أدوات للتحكم في رؤية العناصر وتفاعلات المستخدم والتضمينات المتجاوبة. تساعدك هذه الأدوات على إنشاء واجهات مستخدم سهلة الوصول وتفاعلية.

أدوات الرؤية

تحكم في رؤية العناصر دون التأثير على التخطيط:

<!-- مرئي وغير مرئي --> <div class="visible"> هذا العنصر مرئي (افتراضي) </div> <div class="invisible"> هذا العنصر غير مرئي ولكنه لا يزال يشغل مساحة في التخطيط </div> <!-- المقارنة مع d-none --> <div class="d-none"> هذا العنصر مخفي ولا يشغل مساحة (display: none) </div> <div class="invisible"> هذا العنصر مخفي ولكنه يشغل مساحة (visibility: hidden) </div> <!-- مثال عملي: تبديل الرؤية --> <button class="btn btn-primary" onclick="toggleVisibility()"> تبديل العنصر </button> <div id="toggleElement" class="mt-3 p-3 bg-light"> يمكن تبديل هذا العنصر </div> <script> function toggleVisibility() { const element = document.getElementById('toggleElement'); element.classList.toggle('invisible'); } </script>
ملاحظة: استخدم invisible عندما تريد إخفاء عنصر ولكن الحفاظ على مساحته في التخطيط. استخدم d-none عندما تريد إزالته تماماً من التخطيط.

أدوات قارئ الشاشة

أنشئ واجهات سهلة الوصول عن طريق إخفاء المحتوى بصرياً مع الحفاظ على توفره لقارئات الشاشة:

<!-- مخفي بصرياً (ولكن قابل للوصول لقارئات الشاشة) --> <span class="visually-hidden"> هذا النص مخفي بصرياً ولكن يقرأ بواسطة قارئات الشاشة </span> <button class="btn btn-primary"> <i class="bi bi-search"></i> <span class="visually-hidden">بحث</span> </button> <!-- مخفي بصرياً قابل للتركيز --> <a href="#main-content" class="visually-hidden-focusable"> الانتقال إلى المحتوى الرئيسي </a> <!-- زر بأيقونة فقط مع نص قارئ الشاشة --> <button class="btn btn-danger"> <i class="bi bi-trash"></i> <span class="visually-hidden">حذف العنصر</span> </button> <!-- دوار التحميل مع نص قارئ الشاشة --> <div class="spinner-border" role="status"> <span class="visually-hidden">جاري التحميل...</span> </div> <!-- تسمية النموذج (مخفية بصرياً) --> <label for="search" class="visually-hidden">بحث</label> <input type="text" class="form-control" id="search" placeholder="بحث..."> <!-- رابط تخطي التنقل --> <header> <a href="#main" class="visually-hidden-focusable"> الانتقال إلى المحتوى الرئيسي </a> <nav>...</nav> </header> <main id="main">...</main>
نصيحة: استخدم دائماً visually-hidden للأزرار بأيقونات فقط لضمان فهم مستخدمي قارئات الشاشة لغرض الزر.

الروابط الممتدة

اجعل بطاقات أو حاويات كاملة قابلة للنقر باستخدام الروابط الممتدة:

<!-- رابط ممتد أساسي --> <div class="card" style="width: 18rem;"> <img src="image.jpg" class="card-img-top" alt="المنتج"> <div class="card-body"> <h5 class="card-title">عنوان البطاقة</h5> <p class="card-text">نص وصف البطاقة.</p> <a href="#" class="stretched-link">اذهب إلى مكان ما</a> </div> </div> <!-- بطاقات متعددة مع روابط ممتدة --> <div class="row g-3"> <div class="col-md-4"> <div class="card h-100"> <div class="card-body"> <h5 class="card-title">المنتج 1</h5> <p class="card-text">الوصف</p> <a href="#" class="stretched-link">عرض التفاصيل</a> </div> </div> </div> <div class="col-md-4"> <div class="card h-100"> <div class="card-body"> <h5 class="card-title">المنتج 2</h5> <p class="card-text">الوصف</p> <a href="#" class="stretched-link">عرض التفاصيل</a> </div> </div> </div> </div> <!-- رابط ممتد مع موضع نسبي --> <div class="position-relative p-3 bg-light"> <h4>حاوية قابلة للنقر</h4> <p>هذه الحاوية بأكملها قابلة للنقر.</p> <a href="#" class="stretched-link">انقر هنا</a> </div> <!-- تحديد الحاوية بالموضع --> <div class="card position-relative"> <div class="card-body"> <h5 class="card-title">العنوان</h5> <p class="card-text">المحتوى</p> <a href="#" class="stretched-link">الرابط</a> </div> </div>
تحذير: الروابط الممتدة تعمل فقط مع أقرب سلف موضعه. إذا لم يكن للبطاقة position-relative، فقد يمتد الرابط خارج الحدود المقصودة.

أدوات تحديد النص

تحكم في سلوك تحديد نص المستخدم:

<!-- تحديد المستخدم للكل --> <p class="user-select-all"> انقر لتحديد كل هذا النص دفعة واحدة (مفيد لمقاطع الكود أو المعرفات) </p> <!-- عدم تحديد المستخدم --> <p class="user-select-none"> لا يمكن للمستخدم تحديد هذا النص </p> <!-- تحديد المستخدم التلقائي (افتراضي) --> <p class="user-select-auto"> يمكن تحديد هذا النص بشكل طبيعي (السلوك الافتراضي) </p> <!-- أمثلة عملية --> <!-- عرض مفتاح API --> <div class="p-3 bg-light"> <label>مفتاح API:</label> <code class="user-select-all d-block"> sk_test_4eC39HqLyjWDarjtT1zdp7dc </code> </div> <!-- نص الزر (منع التحديد) --> <button class="btn btn-primary user-select-none"> انقر علي </button> <!-- روابط التنقل (منع التحديد) --> <nav class="user-select-none"> <a href="#">الرئيسية</a> <a href="#">من نحن</a> <a href="#">اتصل بنا</a> </nav> <!-- مقطع كود (سهل النسخ) --> <pre class="user-select-all bg-dark text-white p-3"> npm install bootstrap </pre>
نصيحة: استخدم user-select-all لمفاتيح API أو الرموز أو مقاطع الكود لتسهيل النسخ للمستخدمين.

أحداث المؤشر

تحكم في ما إذا كانت العناصر تستجيب لأحداث المؤشر:

<!-- أحداث المؤشر لا شيء --> <div class="pe-none"> <a href="#">هذا الرابط غير قابل للنقر</a> <button class="btn btn-primary">هذا الزر غير قابل للنقر</button> </div> <!-- أحداث المؤشر تلقائي (افتراضي) --> <div class="pe-auto"> <a href="#">هذا الرابط قابل للنقر</a> </div> <!-- تراكب معطل --> <div class="position-relative"> <div class="content"> <button class="btn btn-primary">إجراء</button> </div> <div class="position-absolute top-0 start-0 w-100 h-100 pe-none"> <!-- تراكب شفاف لا يمنع النقرات --> </div> </div> <!-- حالة التحميل مع التفاعلات المعطلة --> <div class="card" id="loadingCard"> <div class="card-body pe-none opacity-50"> <h5 class="card-title">جاري التحميل...</h5> <p class="card-text">المحتوى</p> <button class="btn btn-primary">إرسال</button> </div> </div> <!-- تمكين التفاعلات بشكل انتقائي --> <div class="pe-none"> <p>هذا النص غير قابل للتحديد</p> <button class="btn btn-primary pe-auto"> ولكن هذا الزر قابل للنقر </button> </div>
ملاحظة: pe-none يجعل عنصراً يتجاهل جميع أحداث المؤشر، ولكن يمكن للأحفاد تجاوز ذلك باستخدام pe-auto.

مساعدات النسبة للتضمينات المتجاوبة

حافظ على نسب عرض إلى ارتفاع متسقة للمحتوى المضمن:

<!-- نسبة عرض إلى ارتفاع 16:9 (افتراضية للفيديوهات) --> <div class="ratio ratio-16x9"> <iframe src="https://www.youtube.com/embed/..." allowfullscreen></iframe> </div> <!-- نسبة عرض إلى ارتفاع 4:3 --> <div class="ratio ratio-4x3"> <iframe src="https://www.youtube.com/embed/..." allowfullscreen></iframe> </div> <!-- نسبة عرض إلى ارتفاع 21:9 (عريض للغاية) --> <div class="ratio ratio-21x9"> <iframe src="https://www.youtube.com/embed/..." allowfullscreen></iframe> </div> <!-- نسبة عرض إلى ارتفاع 1:1 (مربع) --> <div class="ratio ratio-1x1"> <div class="d-flex align-items-center justify-content-center bg-light"> محتوى مربع </div> </div> <!-- نسبة عرض إلى ارتفاع مخصصة --> <div class="ratio" style="--bs-aspect-ratio: 50%;"> <div>نسبة عرض إلى ارتفاع 2:1</div> </div> <!-- أمثلة عملية --> <!-- تضمين فيديو متجاوب --> <div class="container"> <div class="ratio ratio-16x9"> <iframe src="https://www.youtube.com/embed/dQw4w9WgXcQ" title="فيديو YouTube" allowfullscreen ></iframe> </div> </div> <!-- تضمين خرائط Google --> <div class="ratio ratio-4x3"> <iframe src="https://www.google.com/maps/embed?..." style="border:0;" allowfullscreen="" loading="lazy" ></iframe> </div> <!-- معرض صور بنسب متسقة --> <div class="row g-3"> <div class="col-md-4"> <div class="ratio ratio-1x1"> <img src="image1.jpg" class="object-fit-cover" alt="صورة 1"> </div> </div> <div class="col-md-4"> <div class="ratio ratio-1x1"> <img src="image2.jpg" class="object-fit-cover" alt="صورة 2"> </div> </div> <div class="col-md-4"> <div class="ratio ratio-1x1"> <img src="image3.jpg" class="object-fit-cover" alt="صورة 3"> </div> </div> </div>
نصيحة: مساعدات النسبة تمنع المحتوى من القفز أو إعادة التدفق عند تحميل الوسائط المضمنة، مما يحسن تجربة المستخدم.

أدوات ملاءمة الكائن

تحكم في كيفية ملاءمة الصور ومقاطع الفيديو داخل حاوياتها:

<!-- ملاءمة الكائن للاحتواء --> <img src="image.jpg" class="object-fit-contain" style="width: 300px; height: 200px;" alt="محتوى"> <!-- ملاءمة الكائن للتغطية --> <img src="image.jpg" class="object-fit-cover" style="width: 300px; height: 200px;" alt="مغطى"> <!-- ملاءمة الكائن للملء --> <img src="image.jpg" class="object-fit-fill" style="width: 300px; height: 200px;" alt="ممتلئ"> <!-- ملاءمة الكائن للتصغير --> <img src="image.jpg" class="object-fit-scale" style="width: 300px; height: 200px;" alt="مصغر"> <!-- ملاءمة الكائن لا شيء --> <img src="image.jpg" class="object-fit-none" style="width: 300px; height: 200px;" alt="لا شيء"> <!-- ملاءمة الكائن المتجاوبة --> <img src="image.jpg" class="object-fit-contain object-fit-md-cover" alt="متجاوب"> <!-- أمثلة عملية --> <!-- صور مصغرة للمنتج (حجم متسق) --> <div class="row g-3"> <div class="col-4"> <img src="product1.jpg" class="object-fit-cover w-100" style="height: 200px;" alt="منتج 1"> </div> <div class="col-4"> <img src="product2.jpg" class="object-fit-cover w-100" style="height: 200px;" alt="منتج 2"> </div> <div class="col-4"> <img src="product3.jpg" class="object-fit-cover w-100" style="height: 200px;" alt="منتج 3"> </div> </div> <!-- صورة رمزية مع قص دائري --> <img src="avatar.jpg" class="rounded-circle object-fit-cover" style="width: 100px; height: 100px;" alt="الصورة الرمزية"> <!-- صورة لافتة --> <div style="height: 400px; overflow: hidden;"> <img src="banner.jpg" class="w-100 h-100 object-fit-cover" alt="اللافتة"> </div> <!-- خلفية فيديو --> <div class="position-relative" style="height: 500px;"> <video class="position-absolute top-0 start-0 w-100 h-100 object-fit-cover" autoplay muted loop> <source src="background.mp4" type="video/mp4"> </video> <div class="position-relative z-1 text-white text-center"> <h1>محتوى فوق الفيديو</h1> </div> </div>
ملاحظة: أدوات ملاءمة الكائن تتطلب أن يكون للعنصر أبعاد محددة (عرض وارتفاع) لكي تعمل بشكل صحيح.

أدوات المؤشر

غير مظهر المؤشر عند التمرير (يتطلب CSS مخصص في Bootstrap 5):

<!-- أنماط المؤشر المخصصة --> <style> .cursor-pointer { cursor: pointer; } .cursor-grab { cursor: grab; } .cursor-grabbing { cursor: grabbing; } .cursor-not-allowed { cursor: not-allowed; } .cursor-wait { cursor: wait; } .cursor-help { cursor: help; } .cursor-crosshair { cursor: crosshair; } .cursor-move { cursor: move; } .cursor-text { cursor: text; } .cursor-zoom-in { cursor: zoom-in; } .cursor-zoom-out { cursor: zoom-out; } </style> <!-- أمثلة الاستخدام --> <div class="cursor-pointer p-3 bg-light"> مرر فوقي (مؤشر يد) </div> <div class="cursor-not-allowed p-3 bg-light"> هذا الإجراء معطل </div> <div class="cursor-help p-3 bg-light"> مرر للمساعدة </div> <div class="cursor-grab p-3 bg-light"> اسحبني </div> <!-- أمثلة تفاعلية --> <button class="btn btn-secondary cursor-not-allowed" disabled> زر معطل </button> <div class="card cursor-pointer"> <div class="card-body"> <h5 class="card-title">بطاقة قابلة للنقر</h5> <p class="card-text">البطاقة بأكملها قابلة للنقر</p> </div> </div>

أمثلة التفاعل العملية

ادمج أدوات متعددة للتفاعلات المعقدة:

<!-- معرض بطاقات تفاعلي --> <div class="row g-4"> <div class="col-md-4"> <div class="card position-relative overflow-hidden"> <div class="ratio ratio-4x3"> <img src="image1.jpg" class="object-fit-cover" alt="صورة 1"> </div> <div class="card-body"> <h5 class="card-title">العنوان</h5> <p class="card-text text-truncate">الوصف</p> <a href="#" class="stretched-link">عرض المزيد</a> </div> </div> </div> </div> <!-- حالة التحميل سهلة الوصول --> <div class="position-relative"> <button class="btn btn-primary" id="submitBtn"> إرسال </button> <div class="position-absolute top-0 start-0 w-100 h-100 d-none" id="loadingOverlay"> <div class="spinner-border" role="status"> <span class="visually-hidden">جاري التحميل...</span> </div> </div> </div> <!-- قسم معطل مع تلميح أداة --> <div class="position-relative pe-none opacity-50" data-bs-toggle="tooltip" title="الميزة قريباً"> <h4>ميزة مميزة</h4> <p>هذه الميزة غير متوفرة بعد.</p> <button class="btn btn-primary">الترقية الآن</button> </div> <!-- كتلة كود النسخ إلى الحافظة --> <div class="position-relative"> <pre class="user-select-all bg-dark text-white p-3">npm install bootstrap</pre> <button class="btn btn-sm btn-light position-absolute top-0 end-0 m-2" onclick="copyCode()"> <i class="bi bi-clipboard"></i> <span class="visually-hidden">نسخ الكود</span> </button> </div>

تمرين تطبيقي

أنشئ معرض وسائط تفاعلي بالميزات التالية:

  • شبكة من 6 صور بنسبة عرض إلى ارتفاع 1:1 باستخدام مساعدات النسبة
  • الصور تستخدم object-fit-cover لملء الحاويات
  • البطاقة بأكملها قابلة للنقر باستخدام الروابط الممتدة
  • تراكب التحميل مع دوار و pe-none أثناء التحميل
  • تأثيرات التمرير التي تظهر عنوان الصورة (مخفي بشكل افتراضي)
  • نص قارئ الشاشة لإمكانية الوصول
  • متجاوب: عمودان على الموبايل، 3 على التابلت، 6 على الديسكتوب
الأخطاء الشائعة:
  • استخدام invisible عندما تكون هناك حاجة إلى d-none (أو العكس)
  • نسيان visually-hidden على الأزرار بأيقونات فقط
  • عدم تعيين position-relative على حاويات الروابط الممتدة
  • استخدام مساعدات النسبة بدون هيكل حاوية مناسب
  • تطبيق object-fit بدون أبعاد محددة