CSS3 والتصميم المتجاوب

التجاوز والقص والرؤية

40 دقيقة الدرس 17 من 60

فهم التجاوز في CSS

عندما يتجاوز المحتوى داخل عنصر ما الأبعاد المحددة لذلك العنصر، يجب على المتصفح أن يقرر ما يفعله بالمحتوى الزائد. خاصية overflow تتحكم في هذا السلوك وهي واحدة من أهم خصائص التخطيط في CSS. بدون إدارة مناسبة للتجاوز، يمكن أن تنكسر تخطيطاتك، ويمكن أن يتداخل المحتوى مع عناصر أخرى، ويمكن أن تظهر أشرطة التمرير في أماكن غير متوقعة.

كل عنصر في CSS ينشئ صندوقاً مستطيلاً. عندما تحدد قيم width و height صريحة لهذا الصندوق، فأنت تخبر المتصفح بالمساحة القصوى المتاحة للمحتوى. إذا احتاج المحتوى -- سواء كان نصاً أو صوراً أو عناصر متداخلة -- إلى مساحة أكبر مما يوفره الصندوق، يحدث التجاوز. فهم كيفية التعامل مع هذا التجاوز أمر بالغ الأهمية لبناء تخطيطات متينة وقابلة للتنبؤ.

قيم خاصية overflow

تقبل خاصية overflow عدة قيم، كل منها ينتج سلوكاً مختلفاً عندما يتجاوز المحتوى حاويته:

  • visible -- القيمة الافتراضية. المحتوى الذي يتجاوز صندوق العنصر يُعرض خارج الصندوق ويبقى مرئياً. لا يحدث قص ولا تظهر أشرطة تمرير.
  • hidden -- المحتوى الذي يتجاوز صندوق العنصر يُقص. المحتوى المتجاوز يكون غير مرئي ولا يُوفر شريط تمرير للوصول إليه.
  • scroll -- المحتوى المتجاوز يُقص، لكن المتصفح يعرض دائماً أشرطة التمرير -- حتى لو كان المحتوى يتسع داخل العنصر. هذا يضمن مظهراً بصرياً متسقاً.
  • auto -- المتصفح يقرر. إذا تجاوز المحتوى، تظهر أشرطة التمرير. إذا اتسع المحتوى، لا تظهر أشرطة تمرير. هذه هي القيمة الأكثر استخداماً للحاويات القابلة للتمرير.
  • clip -- مشابهة لـ hidden، لكنها تمنع أيضاً التمرير البرمجي عبر JavaScript. لا يمكن تمرير العنصر على الإطلاق، على عكس hidden حيث يعمل scrollTo().

مثال: مقارنة قيم overflow

/* المحتوى ينسكب خارج الصندوق (افتراضي) */
.overflow-visible {
    width: 200px;
    height: 100px;
    overflow: visible;
    border: 2px solid #333;
}

/* المحتوى يُقطع عند حدود الصندوق */
.overflow-hidden {
    width: 200px;
    height: 100px;
    overflow: hidden;
    border: 2px solid #333;
}

/* أشرطة التمرير تظهر دائماً حتى لو لم تكن مطلوبة */
.overflow-scroll {
    width: 200px;
    height: 100px;
    overflow: scroll;
    border: 2px solid #333;
}

/* أشرطة التمرير تظهر فقط عند تجاوز المحتوى */
.overflow-auto {
    width: 200px;
    height: 100px;
    overflow: auto;
    border: 2px solid #333;
}

/* المحتوى مقصوص بدون تمرير نهائياً */
.overflow-clip {
    width: 200px;
    height: 100px;
    overflow: clip;
    border: 2px solid #333;
}
ملاحظة: قيمة overflow: clip هي إضافة حديثة لـ CSS. على عكس hidden، فهي لا تنشئ حاوية تمرير جديدة، مما يعني أن element.scrollTo() أو element.scrollTop في JavaScript لن يكون لهما أي تأثير. استخدم clip عندما تريد عدم وجود سلوك تمرير على الإطلاق.

التحكم في التجاوز لكل محور: overflow-x و overflow-y

يوفر CSS أيضاً overflow-x و overflow-y للتحكم في التجاوز على كل محور بشكل مستقل. هذا مفيد للغاية عندما تريد، على سبيل المثال، التمرير الأفقي بدون التمرير العمودي، أو تريد قص المحتوى عمودياً مع السماح بالتجاوز الأفقي.

مثال: التحكم المستقل في التجاوز لكل محور

/* التمرير الأفقي فقط */
.horizontal-scroll {
    width: 300px;
    overflow-x: auto;
    overflow-y: hidden;
    white-space: nowrap;
}

/* التمرير العمودي فقط */
.vertical-scroll {
    height: 200px;
    overflow-x: hidden;
    overflow-y: auto;
}

/* حاوية كود تتمرر أفقياً فقط */
.code-container {
    max-width: 100%;
    overflow-x: auto;
    overflow-y: visible;
    padding: 16px;
    background: #f4f4f4;
    border-radius: 8px;
}
تحذير: إذا عيّنت أحد المحاور إلى visible والآخر إلى hidden أو scroll أو auto، فإن المتصفح سيعامل داخلياً محور visible على أنه auto. هذا لأن العنصر القابل للتمرير يجب أن يقص المحتوى على كلا المحورين ليعمل بشكل صحيح. هذا مصدر شائع للارتباك عند خلط قيم overflow.

تجاوز النص وعلامة الحذف

خاصية text-overflow تتحكم في كيفية الإشارة للمستخدم بأن النص المضمّن قد تجاوز حاويته. أكثر حالة استخدام شيوعاً هي اقتطاع النص الطويل بعلامة حذف (...). ومع ذلك، text-overflow لا تعمل بمفردها -- فهي تتطلب مجموعة محددة من الخصائص لتعمل بشكل صحيح.

لكي يعمل اقتطاع النص، تحتاج إلى هذه الخصائص الثلاث معاً:

  1. overflow: hidden -- لقص النص المتجاوز.
  2. white-space: nowrap -- لمنع النص من الالتفاف إلى سطر جديد.
  3. text-overflow: ellipsis -- لاستبدال النص المقصوص بعلامة حذف.

مثال: اقتطاع النص في سطر واحد

/* نمط اقتطاع علامة الحذف الكلاسيكي */
.truncate {
    width: 250px;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

/* الاستخدام في HTML:
   <p class="truncate">
       هذه فقرة طويلة جداً سيتم اقتطاعها
       بعلامة حذف عندما تتجاوز الحاوية.
   </p>
*/

لاقتطاع النص متعدد الأسطر، يوفر CSS خاصية -webkit-line-clamp، التي تعمل بالاشتراك مع وضع عرض مبني على flex. هذا يسمح لك بعرض عدد محدد من الأسطر قبل الاقتطاع بعلامة حذف.

مثال: اقتطاع النص متعدد الأسطر

/* الاقتطاع بعد 3 أسطر بعلامة حذف */
.line-clamp-3 {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 3;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* الاقتطاع بعد سطرين */
.line-clamp-2 {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* الاستخدام في HTML:
   <div class="line-clamp-3">
       <p>هذا نص طويل يمتد عبر عدة أسطر.
       سيتم اقتطاعه بعد ثلاثة أسطر وستظهر علامة
       حذف في نهاية السطر الثالث للإشارة إلى
       وجود محتوى إضافي مخفي عن العرض.</p>
   </div>
*/
نصيحة: على الرغم من البادئة -webkit-، فإن -webkit-line-clamp مدعومة من جميع المتصفحات الحديثة بما في ذلك Firefox و Safari. وهي الطريقة الوحيدة الموثوقة لتحقيق اقتطاع النص متعدد الأسطر باستخدام CSS فقط.

إنشاء حاويات قابلة للتمرير

الحاويات القابلة للتمرير ضرورية لبناء واجهات الويب الحديثة -- نوافذ الدردشة والأشرطة الجانبية وجداول البيانات ومعارض الصور كلها تعتمد على مناطق قابلة للتمرير. المفتاح هو تحديد بُعد ثابت واستخدام overflow: auto بحيث تظهر أشرطة التمرير فقط عند الحاجة.

مثال: بناء حاويات قابلة للتمرير

/* شريط جانبي قابل للتمرير */
.sidebar {
    width: 280px;
    height: 100vh;
    overflow-y: auto;
    padding: 20px;
    background-color: #f8f9fa;
    position: sticky;
    top: 0;
}

/* نافذة دردشة قابلة للتمرير */
.chat-messages {
    height: 400px;
    overflow-y: auto;
    padding: 16px;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

/* معرض صور قابل للتمرير أفقياً */
.gallery {
    display: flex;
    gap: 16px;
    overflow-x: auto;
    padding: 16px 0;
    scroll-snap-type: x mandatory;
}

.gallery img {
    flex-shrink: 0;
    width: 300px;
    height: 200px;
    object-fit: cover;
    border-radius: 8px;
    scroll-snap-align: start;
}

/* غلاف جدول بيانات قابل للتمرير */
.table-wrapper {
    max-width: 100%;
    overflow-x: auto;
    border: 1px solid #dee2e6;
    border-radius: 8px;
}

.table-wrapper table {
    min-width: 800px;
    width: 100%;
    border-collapse: collapse;
}

تخصيص شريط التمرير

أشرطة التمرير الافتراضية في المتصفح قد تتعارض مع تصميمك. يوفر CSS نهجين لتخصيص أشرطة التمرير: العناصر الزائفة الخاصة بـ WebKit وخصائص scrollbar-width و scrollbar-color القياسية.

العناصر الزائفة لشريط تمرير WebKit

المتصفحات المبنية على WebKit (Chrome و Edge و Safari) تدعم عدة عناصر زائفة للتحكم الدقيق في شريط التمرير:

  • ::-webkit-scrollbar -- شريط التمرير بالكامل.
  • ::-webkit-scrollbar-track -- المسار الخلفي لشريط التمرير.
  • ::-webkit-scrollbar-thumb -- الجزء القابل للسحب من شريط التمرير.
  • ::-webkit-scrollbar-button -- أزرار الأسهم للأعلى/الأسفل أو اليسار/اليمين.
  • ::-webkit-scrollbar-corner -- الزاوية حيث يلتقي شريطا التمرير الأفقي والعمودي.

مثال: شريط تمرير مخصص باستخدام عناصر WebKit الزائفة

/* شريط تمرير مخصص لحاوية محددة */
.custom-scroll::-webkit-scrollbar {
    width: 8px;
    height: 8px;
}

.custom-scroll::-webkit-scrollbar-track {
    background: #f1f1f1;
    border-radius: 4px;
}

.custom-scroll::-webkit-scrollbar-thumb {
    background: #888;
    border-radius: 4px;
}

.custom-scroll::-webkit-scrollbar-thumb:hover {
    background: #555;
}

/* إخفاء شريط التمرير مع الحفاظ على وظيفة التمرير */
.hidden-scrollbar::-webkit-scrollbar {
    display: none;
}

.hidden-scrollbar {
    -ms-overflow-style: none;   /* IE و Edge */
    scrollbar-width: none;      /* Firefox */
}

تنسيق شريط التمرير القياسي

توفر مواصفات أشرطة تمرير CSS خاصيتين تعملان عبر Firefox والإصدارات الأحدث من Chrome:

مثال: تنسيق شريط التمرير القياسي

/* شريط تمرير رفيع بألوان مخصصة */
.styled-scrollbar {
    scrollbar-width: thin;           /* auto | thin | none */
    scrollbar-color: #888 #f1f1f1;  /* لون-الإبهام لون-المسار */
}

/* إخفاء شريط التمرير كلياً (Firefox) */
.no-scrollbar {
    scrollbar-width: none;
}

/* دمج كلا النهجين لدعم المتصفحات المتعددة */
.cross-browser-scrollbar {
    /* قياسي (Firefox) */
    scrollbar-width: thin;
    scrollbar-color: #6366f1 #e5e7eb;
}

.cross-browser-scrollbar::-webkit-scrollbar {
    width: 6px;
}

.cross-browser-scrollbar::-webkit-scrollbar-track {
    background: #e5e7eb;
}

.cross-browser-scrollbar::-webkit-scrollbar-thumb {
    background: #6366f1;
    border-radius: 3px;
}
نصيحة: قدّم دائماً كلاً من عناصر WebKit الزائفة والخصائص القياسية لأقصى توافق مع المتصفحات. اختبر أشرطة التمرير المخصصة في Firefox و Chrome لضمان التناسق.

الرؤية: visible و hidden و collapse

خاصية visibility تتحكم فيما إذا كان العنصر مرئياً على الصفحة. على عكس display: none، فإن العنصر المخفي لا يزال يشغل مساحة في التخطيط -- فهو ببساطة غير مرئي.

  • visibility: visible -- القيمة الافتراضية. العنصر مرئي.
  • visibility: hidden -- العنصر غير مرئي لكنه لا يزال يشغل مساحته الطبيعية في التخطيط. العناصر الأخرى لا تتغير مواضعها.
  • visibility: collapse -- لصفوف وأعمدة ومجموعات الجداول، يزيل الصف/العمود والمساحة التي يشغلها. على العناصر الأخرى، يتصرف مثل hidden.

visibility: hidden مقابل display: none

هذا أحد أهم الفروقات في CSS:

مثال: visibility: hidden مقابل display: none

<style>
    .container {
        display: flex;
        gap: 10px;
    }
    .box {
        width: 100px;
        height: 100px;
        background: #6366f1;
    }
    /* العنصر غير مرئي لكنه لا يزال يشغل مساحة 100x100 بكسل */
    .box-hidden {
        visibility: hidden;
    }
    /* العنصر يُزال تماماً من التخطيط */
    .box-none {
        display: none;
    }
</style>

<div class="container">
    <div class="box">1</div>
    <div class="box box-hidden">2 (مخفي)</div>
    <div class="box">3</div>
</div>
<!-- الصندوق 3 يبقى في مكانه لأن الصندوق 2 لا يزال يشغل مساحة -->

<div class="container">
    <div class="box">1</div>
    <div class="box box-none">2 (بدون عرض)</div>
    <div class="box">3</div>
</div>
<!-- الصندوق 3 ينتقل بجانب الصندوق 1 لأن الصندوق 2 أُزيل تماماً -->

الفروقات الرئيسية بين الاثنين:

  • تأثير التخطيط: visibility: hidden يحافظ على مساحة العنصر؛ display: none يزيله تماماً.
  • إمكانية الوصول: كلاهما مخفي عن قارئات الشاشة، لكن visibility: hidden مع aria-hidden="false" يمكن أن يكون معقداً.
  • الانتقالات: يمكنك عمل انتقال لـ visibility (ينتقل بين المرئي والمخفي عند نقطة المنتصف)، لكن لا يمكنك عمل انتقال لـ display.
  • الأحداث: عناصر visibility: hidden لا تستقبل أحداث النقر. عناصر display: none لا تتواجد في التخطيط أصلاً.
  • الأداء: display: none يُفعّل إعادة حساب كاملة للتخطيط عند التبديل. visibility: hidden يتطلب فقط إعادة رسم.

خاصية opacity

خاصية opacity تحدد مستوى شفافية العنصر. تتراوح من 0 (شفاف تماماً) إلى 1 (معتم بالكامل). على عكس visibility: hidden، فإن العنصر بقيمة opacity: 0 لا يزال يستقبل أحداث النقر ويشغل مساحة.

مثال: استخدام opacity لتأثيرات التلاشي

/* شفاف تماماً -- العنصر غير مرئي لكنه تفاعلي */
.transparent {
    opacity: 0;
}

/* شبه شفاف -- تأثير الشفافية */
.semi-transparent {
    opacity: 0.5;
}

/* تأثير الظهور التدريجي عند التمرير */
.fade-card {
    opacity: 0.7;
    transition: opacity 0.3s ease;
}

.fade-card:hover {
    opacity: 1;
}

/* حالة التعطيل مع تقليل الشفافية */
.button-disabled {
    opacity: 0.5;
    cursor: not-allowed;
    pointer-events: none;  /* يمنع النقر */
}

/* طبقة فوقية للصورة مع opacity */
.overlay {
    position: absolute;
    inset: 0;
    background-color: rgba(0, 0, 0, 0.6);
    opacity: 0;
    transition: opacity 0.3s ease;
}

.card:hover .overlay {
    opacity: 1;
}
تحذير: الشفافية تُطبق على العنصر بأكمله وجميع أبنائه. إذا عيّنت opacity: 0.5 على عنصر أب، فلا يمكن للأبناء أن يكونوا أكثر عتامة من 50%. إذا كنت تحتاج فقط خلفية شبه شفافة، استخدم rgba() أو hsla() لخاصية background-color بدلاً من ذلك.

clip-path: قص العناصر إلى أشكال

خاصية clip-path تسمح لك بتحديد منطقة مرئية لعنصر ما. أي شيء خارج الشكل المحدد يُقص ويصبح غير مرئي. هذه خاصية قوية لإنشاء تخطيطات غير مستطيلة وتأثيرات الصور والتصاميم الإبداعية بدون HTML إضافي أو صور.

الأشكال الأساسية

يوفر CSS أربع دوال أشكال مدمجة لـ clip-path:

  • circle() -- ينشئ منطقة قص دائرية. الصيغة: circle(نصف-القطر at مركز-x مركز-y).
  • ellipse() -- ينشئ منطقة قص بيضاوية. الصيغة: ellipse(rx ry at مركز-x مركز-y).
  • polygon() -- ينشئ منطقة قص من سلسلة من نقاط الإحداثيات. كل نقطة هي زوج x y.
  • inset() -- ينشئ منطقة قص مستطيلة مع زوايا مستديرة اختيارية. الصيغة: inset(أعلى يمين أسفل يسار round نصف-قطر-الحد).

مثال: أشكال clip-path الأساسية

/* دائرة -- نصف قطر 50% متمركزة افتراضياً */
.clip-circle {
    clip-path: circle(50%);
}

/* دائرة -- موضع مخصص */
.clip-circle-offset {
    clip-path: circle(40% at 30% 50%);
}

/* شكل بيضاوي */
.clip-ellipse {
    clip-path: ellipse(50% 35% at 50% 50%);
}

/* مثلث باستخدام polygon */
.clip-triangle {
    clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
}

/* شكل خماسي باستخدام polygon */
.clip-pentagon {
    clip-path: polygon(50% 0%, 100% 38%, 82% 100%, 18% 100%, 0% 38%);
}

/* قص قطري */
.clip-diagonal {
    clip-path: polygon(0 0, 100% 0, 100% 80%, 0 100%);
}

/* inset مع زوايا مستديرة */
.clip-inset {
    clip-path: inset(10px 20px 10px 20px round 15px);
}

/* clip-path متحرك عند التمرير */
.clip-animated {
    clip-path: circle(0% at 50% 50%);
    transition: clip-path 0.6s ease;
}

.clip-animated:hover {
    clip-path: circle(75% at 50% 50%);
}
نصيحة: يمكن تحريك خاصية clip-path باستخدام انتقالات CSS، مما يتيح تأثيرات كشف إبداعية. عند الانتقال بين الأشكال، تأكد من أن كلا الشكلين البدائي والنهائي يستخدمان نفس الدالة (كلاهما circle() أو كلاهما polygon() بنفس عدد النقاط).

mask و mask-image

خصائص mask و mask-image توفر طريقة أخرى لقص العناصر، لكن بمرونة أكبر من clip-path. تستخدم الأقنعة قناة ألفا (الشفافية) للصورة لتحديد أي أجزاء من العنصر مرئية. المناطق السوداء في القناع تخفي العنصر، والمناطق البيضاء تظهره، والمناطق الرمادية تنشئ تأثيرات شبه شفافة.

مثال: استخدام mask-image

/* قناع تدرجي -- يتلاشى في الأسفل */
.fade-bottom {
    -webkit-mask-image: linear-gradient(to bottom, black 60%, transparent 100%);
    mask-image: linear-gradient(to bottom, black 60%, transparent 100%);
}

/* قناع تدرج شعاعي -- تأثير الضوء الكشاف */
.spotlight {
    -webkit-mask-image: radial-gradient(circle at 50% 50%, black 30%, transparent 70%);
    mask-image: radial-gradient(circle at 50% 50%, black 30%, transparent 70%);
}

/* قناع SVG من رابط */
.svg-mask {
    -webkit-mask-image: url('mask-shape.svg');
    mask-image: url('mask-shape.svg');
    -webkit-mask-size: cover;
    mask-size: cover;
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
}

/* تلاشي النص للمحتوى الطويل */
.text-fade {
    max-height: 200px;
    overflow: hidden;
    -webkit-mask-image: linear-gradient(to bottom, black 70%, transparent 100%);
    mask-image: linear-gradient(to bottom, black 70%, transparent 100%);
}
ملاحظة: أضف دائماً البادئة -webkit- لخصائص mask-image. Safari لا يزال يتطلب النسخة ذات البادئة، و Chrome يدعم كلتيهما. Firefox يستخدم النسخة بدون بادئة.

content-visibility لأداء العرض

خاصية content-visibility هي ميزة CSS حديثة نسبياً مصممة لتحسين أداء العرض. تسمح للمتصفح بتخطي عرض العناصر التي خارج الشاشة حتى تكون مطلوبة. يمكن أن يسرّع هذا بشكل كبير أوقات تحميل الصفحة الأولية في الصفحات ذات المحتوى الكثير.

  • content-visibility: visible -- الافتراضي. المحتوى يُعرض بشكل طبيعي.
  • content-visibility: hidden -- المحتوى لا يُعرض ولا يمكن الوصول إليه. مشابه لـ display: none لكنه يحافظ على حالة العرض لإعادة عرض أسرع.
  • content-visibility: auto -- المتصفح يتخطى تلقائياً عرض العناصر خارج الشاشة ويعرضها عندما تظهر عند التمرير.

مثال: content-visibility للأداء

/* كل قسم في الصفحة يمكنه استخدام content-visibility: auto */
.page-section {
    content-visibility: auto;
    contain-intrinsic-size: 0 500px;  /* ارتفاع تقديري للتخطيط */
}

/* بطاقات مقالات المدونة في قائمة طويلة */
.blog-card {
    content-visibility: auto;
    contain-intrinsic-size: 0 350px;
}

/* لوحات التبويب غير المرئية */
.tab-panel[hidden] {
    content-visibility: hidden;
}

/* الدمج مع contain للأداء الأقصى */
.performance-optimized {
    content-visibility: auto;
    contain-intrinsic-size: auto 300px;
    contain: layout style paint;
}
تحذير: عند استخدام content-visibility: auto، وفّر دائماً قيمة contain-intrinsic-size. بدونها، قد يعامل المتصفح العنصر على أنه بارتفاع صفر عندما يكون خارج الشاشة، مما يتسبب في قفز شريط التمرير بشكل متقطع مع تمرير المستخدم وعرض العناصر.

مقارنة عملية: إخفاء العناصر

يوفر CSS طرقاً عديدة لإخفاء العناصر، كل منها له تأثيرات مختلفة على التخطيط وإمكانية الوصول والأداء والتفاعلية. إليك ملخص لجميع الطرق:

  • display: none -- يزيل العنصر تماماً من التخطيط. غير متاح لقارئات الشاشة. لا يمكن عمل انتقال له.
  • visibility: hidden -- يخفي العنصر لكن يحافظ على مساحته. غير متاح. يمكن عمل انتقال له (ينتقل عند نقطة المنتصف).
  • opacity: 0 -- يجعل العنصر شفافاً تماماً. لا يزال يشغل مساحة ولا يزال يستقبل أحداث المؤشر. يمكن عمل انتقال سلس له.
  • clip-path: circle(0) -- يقص العنصر إلى لا شيء. لا يزال يشغل مساحة. يمكن عمل انتقال سلس له.
  • transform: scale(0) -- يقلص العنصر إلى نقطة. لا يزال يشغل المساحة الأصلية. يمكن عمل انتقال سلس له.
  • content-visibility: hidden -- يخفي المحتوى ويحافظ على حالة العرض. غير متاح.
  • position: absolute; left: -9999px -- ينقل العنصر خارج الشاشة. لا يزال متاحاً لقارئات الشاشة. يُستخدم لأصناف المخفي بصرياً.

تمرين 1: بطاقة قابلة للتمرير مع شريط تمرير مخصص

أنشئ مكون بطاقة بارتفاع ثابت 300 بكسل وعرض 400 بكسل. داخل البطاقة، أضف محتوى نصي كافٍ لإحداث تجاوز. طبّق overflow-y: auto لجعلها قابلة للتمرير. ثم نسّق شريط التمرير باستخدام كل من عناصر WebKit الزائفة وخصائص scrollbar-width و scrollbar-color القياسية. يجب أن يكون إبهام شريط التمرير شريطاً أزرق مستديراً (#3b82f6) على مسار رمادي فاتح (#f3f4f6). يجب أن يكون عرض شريط التمرير 6 بكسل. اختبر في كل من Chrome و Firefox للتحقق من التوافق بين المتصفحات.

تمرين 2: كشف الصورة باستخدام clip-path

أنشئ بطاقة صورة تستخدم clip-path لكشف نفسها عند التمرير. ابدأ بـ clip-path: circle(0% at 50% 50%) بحيث تكون الصورة مخفية تماماً. عند التمرير، انتقل إلى clip-path: circle(75% at 50% 50%) مع انتقال سلس مدته 0.5 ثانية. أضف طبقة نصية فوق الصورة تستخدم opacity للظهور التدريجي عند التمرير. يجب أن يكون للطبقة خلفية سوداء شبه شفافة باستخدام rgba(0, 0, 0, 0.5) ونص أبيض. أضف أيضاً تأثير تلاشي تدريجي mask-image على فقرة منفصلة أسفل البطاقة بحيث يتلاشى النص في الأسفل.

تمرين 3: معاينة مقال مدونة مقتطعة

ابنِ بطاقة معاينة مقال مدونة تعرض عنواناً وتاريخ نشر ومقتطف محتوى. يجب اقتطاع العنوان إلى سطر واحد بعلامة حذف باستخدام overflow: hidden و white-space: nowrap و text-overflow: ellipsis. يجب تقييد مقتطف المحتوى إلى 3 أسطر بالضبط باستخدام -webkit-line-clamp. أسفل المقتطف، أضف رابط "اقرأ المزيد". نسّق البطاقة بأكملها بحد خفيف وحشوة، وتأكد من أن البطاقة تستخدم content-visibility: auto مع contain-intrinsic-size مناسب لتحسين الأداء.