UIDex

البطاقة

Card

<article>

اسمه كمانكارد، كرت، بطاقة محتوى، بطاقة منتج، صندوق المحتوى، بطاقة معاينة، content card، product card، media card، tile، teaser، preview box

البطاقة حاوية تجمع محتوى كيان واحد، مقال أو منتج، في وحدة مستقلّة تُقرأ وحدها وتتكرّر عشرات المرّات داخل شبكة واحدة. وتضمّ عادةً صورة وعنواناً ونصّاً قصيراً وسطر بيانات وصفية وصفّ إجراءات، ولا يلزم حضور هذه الأجزاء كلّها. وهي ليست قسماً من الصفحة (section): القسم جزء من بنية الصفحة يظهر مرّة واحدة، وإذا حمل اسماً دخل قائمة المعالم عند قارئ الشاشة، أمّا البطاقة فوحدة متكرّرة لا محلّ لها في تلك القائمة. وليست صفّاً في جدول، لأن صفّ الجدول لا يُفهم إلا بترويسة عموده، بينما تحمل البطاقة تسمياتها بداخلها فتبقى مفهومة لو اقتُطعت ولُصقت في مكان آخر. واللوحة (panel) شيء ثالث: تعرض جزءاً من محتوى الصفحة الحالية وتبقى في موضعها، بينما تنوب البطاقة عن كيان مستقلّ له غالباً صفحته الخاصّة. والاختبار العملي عند المراجعة: إذا لم يكن للصندوق عنوان خاصّ به ولا كيان مستقلّ خلفه، فهو صندوق بحدود لا أكثر.

لو قلت عليه…

«المربّع اللي فيه صورة وعنوان وبيودّيك على صفحة تانية»«الصندوق اللي بيتكرّر في الشبكة»«الكارت بتاع المنتج في صفحة المتجر»«المستطيل اللي بيتضغط من أي مكان فيه»«صورة وتحتها سطرين وزرار حفظ»

العيّنة الحيّة

تفاعل مع الديمو. كل الأجزاء حقيقية ومرقّمة.

  • جديد

    مقارنة عملية بين خطوط الواجهات العربية، وأثر كلّ خطّ على أطوال السطور وعلى زمن التحميل في الصفحات الطويلة.

    ٧ دقائق قراءة

اضغط أي مكان فارغ في البطاقة ليفتح العنوان

RTLالصورة والنصّ يتبادلان بترتيب DOM وحده، بلا row-reverse

تشريح العنصر: كل جزء واسمه

مرّر على أي سطر ليتحدّد مكانه في الديمو فوق.

برومبت البناء

ابنِ بطاقة محتوى قابلة للتكرار في شبكة. اجعل جذرها <article> يحمل aria-labelledby يشير إلى معرّف العنوان، ولا تجعله <section> حتى لا تزحم قائمة المعالم. رتّب الأجزاء بهذا الترتيب: صورة بسمتَي width و height مع aspect-ratio و alt فارغ إذا كرّرت العنوان، ثم عنوان بمستوى يناسب مخطّط الصفحة، ثم متن مقطوع بـ ‎-webkit-line-clamp‎ مع overflow: hidden لا بارتفاع ثابت، ثم سطر بيانات وصفية فيه <time datetime> بصيغة ISO، ثم صفّ إجراءات. اجعل البطاقة كلّها قابلة للضغط برابط واحد حقيقي على العنوان يحمل ‎::after { content: ""; position: absolute; inset: 0; z-index: 1 }‎ مع position: relative على <article>، ولا تلفّ البطاقة كلّها داخل <a>: أي <a> ثانٍ بداخله يغلقه محلّل HTML ويخرجه ليصير شقيقاً له فيختلف الـ DOM عمّا كتبته، أمّا الزرّ فيبقى في مكانه لكنّه تعشيش تفاعلي غير صالح والضغط عليه يفعّل الرابط معه. ارفع كل عنصر تفاعلي آخر فوق تلك الطبقة بـ position: relative و z-index أكبر، وأعطِ كل زرّ اسماً يذكر بطاقته. ضع البطاقات داخل <ul> مع <li> لكل بطاقة، وأضف role="list" لأن list-style: none يُسقط دلالة القائمة في Safari مع VoiceOver. أظهر حالة التركيز بـ :focus-within على الحاوية لا بـ :hover وحده. واكتب المسافات والمواضع بالخصائص المنطقية وحدها: padding-inline و margin-inline-start و inset-inline-end و border-inline-start و border-start-start-radius، ولا تكتب left ولا right، ولا تضف row-reverse داخل [dir="rtl"].

سلوكه في الاتجاه من اليمين لليسار

الجزء ده حصري عندنا.

البطاقة الأفقية

ينعكس

في البطاقة الأفقية تجلس الصورة عند البداية المنطقية والنصّ بعدها، والتبادل يحدث بترتيب DOM وحده لأن المحور المضمّن في flex و grid يتبع direction: أوّل عنصر في الترتيب يظهر إلى اليمين في العربية بلا سطر CSS واحد، و grid-template-columns: 96px 1fr يضع عمود الصورة في اليمين تلقائياً. ولا تضف flex-direction: row-reverse داخل [dir="rtl"]، فهو انعكاس ثانٍ يعيد الصورة إلى الجهة الخطأ ويفصل الترتيب البصري عن ترتيب التنقّل بـ Tab.

الحشو وتدوير الزوايا

ينعكس

كلّ مسافة غير متماثلة داخل البطاقة تُكتب بالخصائص المنطقية: padding-inline للحشو الجانبي، و margin-inline-end على الصورة للفراغ الذي يفصلها عن النصّ. والصورة الملاصقة لحافّة البطاقة الأفقية تُدوَّر بزاويتَي الحافّة المضمّنة الأولى، أي border-start-start-radius و border-end-start-radius، فتنتقلان مع الاتجاه، بينما يبقى border-top-left-radius على اليسار ويقطع الصورة من الجهة الخطأ بعد الانعكاس. والشريط الملوّن الذي يميّز نوع البطاقة يُرسم بـ border-inline-start: 3px solid لا بـ border-left.

صفّ الإجراءات

ينعكس

الإجراء الأساسي يقف عند النهاية المنطقية للصفّ، أي عند يسار البطاقة في العربية. ضعه أخيراً في DOM واستعمل justify-content: flex-end على الصفّ أو margin-inline-start: auto على أوّل زرّ في المجموعة، لأن flex-end يقيس من نهاية المحور المضمّن الذي انعكس أصلاً مع الصفحة. ولا تستعمل margin-left: auto لأنها فيزيائية، ولا تعِد الترتيب بخاصّية order لأنها تحرّك ما تراه العين ولا تحرّك ما يتبعه التنقّل بـ Tab.

الشارة في الزاوية

ينعكس

الشارة المثبّتة في زاوية البطاقة («جديد»، «خصم ٢٠٪») تنتقل مع الاتجاه، فثبّتها بـ inset-inline-end: 8px بدل right: 8px. ولا تعكسها بـ transform: scaleX(-1)، فالقلب يقلب نصّها ورقمها معها ويجعلهما مقروءين بالمرآة. أمّا الشريط المائل فيحتاج خطوة زائدة، لأن rotate خاصّية فيزيائية لا تعرف الاتجاه: اكتب rotate(calc(45deg * var(--dir))) واضبط ‎--dir: -1‎ داخل [dir="rtl"]، وإلا مال الشريط في الاتجاه المعاكس وخرج عن زاوية البطاقة.

الصورة نفسها

لا ينعكس

محتوى الصورة لا ينعكس أبداً. القاعدة الشاملة [dir="rtl"] img { transform: scaleX(-1) } تقلب لقطات الشاشة والشعارات والوجوه، فتصير الكلمات داخل الصورة مقروءة بالمرآة. وانتبه إلى القصّ كذلك: قيمة object-position من نوع position ولا كلمة منطقية فيها، فكلماتها center و left و right و top و bottom إلى جانب الأطوال والنِّسَب، والمصغّرة المقصوصة بـ object-position: left center تبقى مقصوصة من اليسار الفيزيائي بعد الانعكاس، فبدّلها بنفسك داخل [dir="rtl"] إن كان موضوع الصورة يقتضي ذلك.

أسماؤه في الكود

كل سطر هو كلمة مكتبة واحدة عن نفس الشيء. خد السطر اللي بيكلّم مشروعك.

HTML<article>الجذر الطبيعي للبطاقة، ودوره الضمني article لا معلم، فلا يزحم قائمة المعالم.
CSS::after { position: absolute; inset: 0 }طبقة الضغط الممتدّة التي تحوّل البطاقة كلّها إلى هدف واحد برابط واحد.
ARIAaria-labelledby="card-title"يسمّي <article> بعنوانه، فيُعلَن باسم البطاقة عند القفز بين المقالات.
shadcn/ui<Card><CardHeader><CardTitle>Card و CardTitle كلاهما <div> منسّق، فالعنصر الدلالي ومستوى العنوان والرابط الممتدّ من عندك.
Material UI<CardActionArea>يُصيَّر زرّاً يغلّف محتوى البطاقة، فأي رابط أو زرّ بداخله تعشيش تفاعلي غير صالح.
Ant Design<Card cover={…} actions={[…]}>actions تُصيَّر <ul> في التذييل، وكلّ إجراء يظلّ محتاجاً اسماً يميّز بطاقته.
CSSborder-start-start-radiusالزاوية المنطقية للصورة الملاصقة لحافّة البطاقة الأفقية، تنتقل مع الاتجاه وحدها.

شوف كمان

آخر تحديث · 2026-08-19