frontend

بدائل CSS Anchor Positioning: دليل الـ Auto-Flip لعام (2026)

١٨ يونيو ٢٠٢٦

CSS Anchor Positioning Fallbacks: Auto-Flip Guide (2026)

لجعل عنصر CSS مثبت (anchored) يتقلب تلقائيًا عندما يتجاوز حدود نافذة العرض (viewport)، أضف position-try-fallbacks إلى العنصر المحدد مع قيمة واحدة أو أكثر من قيم <try-tactic> مثل flip-block، أو flip-inline، أو flip-block flip-inline. يحافظ المتصفح على موضعه الافتراضي طالما كان مناسبًا للمساحة، ولا ينتقل إلى الوضع الاحتياطي إلا عندما يوشك العنصر على الخروج عن الحدود.

ملخص

يتيح لك تحديد موضع الإرساء (CSS anchor positioning) ربط القوائم المنسدلة، أو تلميحات الأدوات (tooltips)، أو النوافذ المنبثقة (popovers) بنقطة إرساء باستخدام CSS فقط. الجزء الصعب — وهو إبقاء العنصر داخل الشاشة — يتم حله بواسطة position-try-fallbacks وقاعدة @position-try، اللذان يجربان مواضع بديلة فقط عندما يتجاوز الموضع الافتراضي الحدود. اعتبارًا من عام 2026، أصبحت هذه الميزة مدعومة في Chrome/Edge 125+، و Firefox 147+، و Safari 26+ (حوالي 83% من المستخدمين)، لذا يمكنك استخدامها مع وضع أساسي معقول لبقية المستخدمين. يشرح هذا الدليل كيفية بناء قائمة منسدلة تتقلب تلقائيًا، ويوضح سبب عدم تفعيل البدائل أحيانًا، ويضيف إخفاءً مشروطًا باستخدام position-visibility.

ما ستتعلمه

  • كيف يقوم position-try-fallbacks بقلب العنصر المثبت بعيدًا عن حافة نافذة العرض
  • لماذا لا تعمل البدائل (fallbacks) الخاصة بك (والحل الوحيد الذي يعالج معظم الحالات)
  • كتابة بديل @position-try مخصص للتحكم الدقيق
  • الفرق بين position-area ودالة anchor()
  • إخفاء العنصر المثبت باستخدام position-visibility عندما يختفي مرساه (anchor) أثناء التمرير
  • صورة دعم المتصفحات المؤكدة لعام 2026، بما في ذلك Safari و @position-try

كيف أجعل عنصر CSS مثبتًا يتقلب عندما يتجاوز الحدود؟

أضف position-try-fallbacks إلى العنصر المحدد وادرج المواضع التي يمكن للمتصفح تجربتها عندما يتجاوز الموضع الافتراضي الحدود. يستخدم المتصفح موضعك الأساسي أولاً، ولا يطبق البديل إلا عند التجاوز — لا تُستخدم البدائل أبدًا طالما كان العنصر مناسبًا للمساحة.

ابدأ بمرسى (anchor) بسيط وقائمة منسدلة محددة الموضع. يحصل المرسى على anchor-name؛ وتشير القائمة المنسدلة إليه باستخدام position-anchor وتضع نفسها باستخدام position-area:

.menu-button {
  anchor-name: --menu-btn;
}

.menu {
  position: absolute;
  position-anchor: --menu-btn;
  /* الموضع الأساسي: مباشرة أسفل الزر، مع محاذاة الحواف اليسرى. */
  position-area: bottom span-right;
  margin-top: 6px;

  /* إذا تجاوز الموضع "بالأسفل" الحدود، جرب هذه الخيارات بالترتيب حتى يناسب أحدها المساحة. */
  position-try-fallbacks: flip-block, flip-inline, flip-block flip-inline;
}

القيم الثلاث المحددة مسبقًا لـ <try-tactic> هي flip-block (يقلب الموضع على طول محور الكتلة — الأسفل يصبح أعلى)، و flip-inline (يقلب على طول المحور المضمن — اليمين يصبح يسارًا)، و flip-start (يعكس عبر محور قطري، مبدلاً اتجاهات الكتلة والمضمن).1 يمكنك الجمع بين اثنين في خيار واحد مفصول بمسافة، مثل flip-block flip-inline، للقلب قطريًا. تقوم المتصفحات بتقييم القائمة من اليسار إلى اليمين وتختار الخيار الأول الذي يبقي العنصر بالكامل داخل الشاشة.

الأخطاء الشائعة: لماذا لا يعمل position-try-fallbacks؟

السبب الأكثر شيوعًا هو أنك أعطيت المتصفح تقلبات في محور واحد فقط. إذا كان المرسى يقع بالقرب من زاوية، فقد يتجاوز العنصر الحدود في كلا الاتجاهين في وقت واحد، ولا يحل flip-block ولا flip-inline وحدهما هذه المشكلة — فأنت بحاجة أيضًا إلى خيار flip-block flip-inline المدمج.1 وهذا هو بالضبط سبب إدراج الخيارات الثلاثة في المثال أعلاه.

هناك أمران آخران قد يسببان ارتباكًا. أولاً، لا يتم تفعيل البدائل إلا عند تجاوز الحدود: إذا كان العنصر مناسبًا في مكانه الافتراضي، فسيتم تجاهل القائمة تمامًا، مما قد يبدو وكأن "لا شيء حدث". ثانيًا، قد يكون كود CSS الخاص بك قديمًا قبل إعادة التسمية في عام 2024. كانت الخاصية تسمى سابقًا position-try-options وكان position-area يسمى سابقًا inset-area؛ تم تغيير اسميهما، لذا فإن الأكواد القديمة لا تفعل شيئًا في المتصفحات الحالية.2 استخدم الأسماء الحالية: position-try-fallbacks و position-area.

كيف أكتب بديل @position-try مخصص؟

استخدم قاعدة @position-try لتعريف موضع مسمى، ثم أشر إلى هذا الاسم في position-try-fallbacks. يمنحك هذا تحكمًا لا توفره التكتيكات المحددة مسبقًا، مثل تعديل الهوامش (margins) أو تغيير أي حواف داخلية ترتبط بأي جانب:

@position-try --above {
  top: auto;
  bottom: anchor(top);
  margin-top: 0;
  margin-bottom: 6px;
}

@position-try --shift-left {
  position-area: bottom span-left;
}

.menu {
  position: absolute;
  position-anchor: --menu-btn;
  position-area: bottom span-right;
  margin-top: 6px;

  position-try-fallbacks: --above, --shift-left;
}

يبدأ كل اسم @position-try بشرطتين (وهو <dashed-ident>). يمكنك مزج الأسماء المخصصة والتكتيكات المحددة مسبقًا في خيار بديل واحد — عندما تفعل ذلك، يتم تطبيق الخيار المخصص أولاً ثم يتم تطبيق تحويل التكتيك فوقه.1 إذا كان الاسم في القائمة لا يطابق أي قاعدة @position-try، فسيتم تخطي هذا الإدخال ببساطة، وهو سبب صامت آخر لعدم "عمل" البديل.

ما الفرق بين position-area ودالة anchor()؟

position-area هي الطريقة السريعة القائمة على الشبكة لوضع عنصر؛ أما anchor() فهي الطريقة الدقيقة القائمة على الحواف. كلاهما يحل نفس المشكلة بمستويات مختلفة من التحكم.

تتعامل position-area مع المرسى كخلية مركزية في شبكة 3×3 ضمنية وتسمح لك بوضع العنصر في بلاطة واحدة أو أكثر باستخدام كلمات رئيسية مثل top، أو bottom span-right، أو bottom span-all. الصفوف هي top/center/bottom (منطقياً: block-start/center/block-end) والأعمدة هي left/center/right (منطقياً: start/center/end).3 وهي تغطي معظم حالات القوائم المنسدلة وتلميحات الأدوات في سطر واحد.

توضع دالة anchor() داخل خصائص الإزاحة (top، left، inset-block-start، وما إلى ذلك) وتعيد طولاً عند حافة محددة للمرسى، مثل bottom: anchor(top) أو left: anchor(right). وهي تقبل الجوانب الفيزيائية، والجوانب المنطقية (start، end، self-start، self-end)، و center.4 استخدم anchor() عندما تحتاج إلى التثبيت بحافة دقيقة أو الموضع بالنسبة لأكثر من مرسى واحد؛ واستخدم position-area عندما تكون خلية الشبكة كافية.

كيف أخفي عنصرًا مثبتًا عندما يختفي مرساه عن الشاشة أثناء التمرير؟

استخدم خاصية position-visibility. فهي تخفي العنصر المحدد الموضع بشكل مشروط بناءً على التجاوز أو رؤية المرسى، وهو أمر مفيد عندما يطفو تلميح الأداة في مساحة فارغة بعد خروج مرساه من الحاوية أثناء التمرير:

.menu {
  position: absolute;
  position-anchor: --menu-btn;
  position-area: bottom span-right;

  /* إخفاء القائمة تمامًا بمجرد قص الزر بالكامل. */
  position-visibility: anchors-visible;
}

تحتوي position-visibility على ثلاث قيم: always (الافتراضي — يظهر دائمًا)، و no-overflow (يخفي العنصر تمامًا عندما يبدأ في تجاوز حاويته أو نافذة العرض)، و anchors-visible (يخفيه تمامًا عندما يتم إخفاء المرسى تمامًا بسبب التجاوز أو التغطية).5 هذه الخاصية أحدث من خصائص الإرساء الأساسية ولا تزال قيد الاستقرار عبر المحركات، لذا تعامل معها كتحسين تدريجي (progressive enhancement) وتحقق من الدعم قبل الاعتماد عليها في الإنتاج.

هل يدعم Safari خاصية CSS anchor positioning و @position-try؟

نعم. أطلق Safari خاصية CSS anchor positioning — بما في ذلك قاعدة @position-try و position-try-fallbacks — في إصدار Safari 26.0 (الصادر في سبتمبر 2025)، لكل من macOS و iOS.67 الإرشادات القديمة التي تقول "Safari يدعم anchor() ولكن ليس @position-try" تصف حقبة معاينة Safari 18.x التجريبية وأصبحت الآن قديمة؛ النسخة المستقرة تدعم آلية البدائل (fallback).

ومع ذلك، فإن أي شخص يستخدم Safari 18.7 أو أقدم لا يملك خاصية anchor positioning على الإطلاق، لذا لا يزال وضع موضع أساسي احتياطي أمراً مهماً (انظر قسم المتصفحات أدناه).

هل CSS anchor positioning جاهزة للاستخدام الفعلي في 2026؟

بالنسبة لمعظم الجمهور، نعم — مع وجود خطة احتياطية للمتصفحات القديمة. وفقاً لموقع caniuse، الميزة مدعومة افتراضياً في Chrome و Edge 125+، و Safari 26.0+، و Firefox 147+، و Opera 111+، و Samsung Internet 27+، لتصل إلى حوالي 83% من المستخدمين العالميين اعتباراً من أبريل 2026.6

المتصفحأول إصدار بدعم افتراضي
Chrome125
Edge125
Firefox147 (مستقر 2026-01-13)
Safari (macOS + iOS)26.0
Opera111
Samsung Internet27

كان Firefox هو آخر المحركات الرئيسية التي اعتمدتها: الإصدارات 145–146 كانت تحتوي عليها خلف تفضيل layout.css.anchor-positioning.enabled، وقام الإصدار 147 بتفعيلها افتراضياً.68 الخلاصة العملية هي أن anchor positioning خيار ممتاز للعمل الجديد اليوم، طالما أن مستخدمي Firefox قبل 147 أو Safari قبل 26 لا يزالون يرون تخطيطاً قابلاً للاستخدام.

كيف أحافظ على قابليتها للاستخدام في المتصفحات التي لا تدعم anchor positioning؟

اجعل موضعك الأساسي خارج أي كتلة @position-try، واترك البدائل تضيف فقط تحسين الانعكاس (flip). المتصفحات التي لا تفهم anchor positioning ستتجاهل الخصائص غير المعروفة وتعود إلى تحديد الموضع العادي، لذا سيظل العنصر يظهر في مكان منطقي:

.menu {
  /* Plain CSS fallback for engines with no anchor positioning. */
  position: absolute;
  top: 100%;
  left: 0;

  /* Progressive enhancement for engines that support it. */
  position-anchor: --menu-btn;
  position-area: bottom span-right;
  position-try-fallbacks: flip-block, flip-inline, flip-block flip-inline;
}

بالنسبة للفرق التي تحتاج إلى عمل التثبيت (anchoring) على المتصفحات القديمة، توفر OddBird مكتبة polyfill لـ CSS anchor positioning تعوض هذا السلوك؛ استخدمها مع التحسين التدريجي بدلاً من إرسالها لكل زائر.9 تجربة الانعكاس عبر @position-try تتكامل أيضاً بشكل طبيعي مع Popover API (سمة popover بالإضافة إلى popovertarget)، والتي أصبحت Baseline منذ يناير 2025 وتتولى العرض في الطبقة العليا (top-layer)، ومفتاح Escape، والإغلاق عند النقر في الخارج (light-dismiss) نيابة عنك.10

الخلاصة

تجعل خاصية CSS anchor positioning أخيراً مهمة "إبقاء هذه القائمة المنسدلة على الشاشة" مشكلة تنسيق بدلاً من كونها مشكلة JavaScript. ادرج بضعة position-try-fallbacks، وتضمن خيار القطر flip-block flip-inline، وحدد @position-try مخصصاً عندما تحتاج إلى تحكم دقيق، وأضف position-visibility لإخفاء العناصر التي تبتعد مراسيها عند التمرير. ثبت موضعاً أساسياً بسيطاً بحيث يظل Firefox قبل 147 و Safari قبل 26 يعرضان المحتوى بشكل نظيف، وبذلك ستحصل على حل قوي يعتمد بشكل أساسي على CSS.

إذا كنت تبني واجهة مستخدم حديثة باستخدام CSS، فراجع أدلتنا المصاحبة حول بدء استخدام تخطيط وعرض CSS، وإطلاق الوضع الداكن في Tailwind v4 بدون وميض، وتصحيح أخطاء View Transitions API عندما لا تعمل.

Footnotes

  1. MDN Web Docs — "position-try-fallbacks". https://developer.mozilla.org/en-US/docs/Web/CSS/position-try-fallbacks 2 3

  2. Chrome for Developers — "Anchor positioning syntax changes" (inset-area → position-area; position-try-options → position-try-fallbacks). https://developer.chrome.com/blog/anchor-syntax-changes

  3. MDN Web Docs — "position-area". https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/position-area

  4. MDN Web Docs — "دالة anchor() في CSS". https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Values/anchor

  5. MDN Web Docs — "خيارات التراجع والإخفاء الشرطي للتجاوز" (position-visibility). https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Anchor_positioning/Try_options_hiding

  6. Can I use — "CSS Anchor Positioning" (الاستخدام العالمي ~82.83%، StatCounter أبريل 2026). https://caniuse.com/css-anchor-positioning 2 3

  7. WebKit — "ميزات WebKit في Safari 26.0" (2025-09-15). https://webkit.org/blog/17333/webkit-features-in-safari-26-0/

  8. Mozilla Bugzilla 1988225 — "تفعيل تفضيل تحديد المواقع بالإرساء (layout.css.anchor-positioning.enabled) افتراضياً على جميع القنوات". https://bugzilla.mozilla.org/show_bug.cgi?id=1988225

  9. OddBird — CSS Anchor Positioning Polyfill. https://GitHub.com/oddbird/css-anchor-positioning

  10. web.dev — "واجهة Popover API أصبحت الآن متاحة حديثاً في Baseline". https://web.dev/blog/popover-baseline

الأسئلة الشائعة

أضف position-try-fallbacks إلى العنصر المحدد الموضع وادرج المواضع مثل flip-block, flip-inline, flip-block flip-inline . يحافظ المتصفح على الموضع الافتراضي طالما أنه مناسب وينتقل إلى أول بديل يتجنب تجاوز الحدود.