بدائل CSS Anchor Positioning: دليل الـ Auto-Flip لعام (٢٠٢٦)
إزاي تخلي الـ dropdowns والـ tooltips المثبتة بـ CSS تتقلب وتختفي لما تخرج بره المساحة المتاحة باستخدام position-try-fallbacks و @position-try. دليل ٢٠٢٦ شغال cross-browser.
جدول المحتويات
لجعل عنصر 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، اللذان يجربان مواضع بديلة فقط عندما يتجاوز الموضع الافتراضي الحدود. اعتبارًا من عام ٢٠٢٦، أصبحت هذه الميزة مدعومة في Chrome/Edge 125+، و Firefox 147+، و Safari 26+ (حوالي ٨٣٪ من المستخدمين)، لذا يمكنك استخدامها مع وضع أساسي معقول لبقية المستخدمين. يشرح هذا الدليل كيفية بناء قائمة منسدلة تتقلب تلقائيًا، ويوضح سبب عدم تفعيل البدائل أحيانًا، ويضيف إخفاءً مشروطًا باستخدام position-visibility.
ما ستتعلمه
- كيف يقوم
position-try-fallbacksبقلب العنصر المثبت بعيدًا عن حافة نافذة العرض - لماذا لا تعمل البدائل (fallbacks) الخاصة بك (والحل الوحيد الذي يعالج معظم الحالات)
- كتابة بديل
@position-tryمخصص للتحكم الدقيق - الفرق بين
position-areaودالةanchor() - إخفاء العنصر المثبت باستخدام
position-visibilityعندما يختفي مرساه (anchor) أثناء التمرير - صورة دعم المتصفحات المؤكدة لعام ٢٠٢٦، بما في ذلك 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 (يعكس عبر محور قطري، مبدلاً اتجاهات الكتلة والمضمن).١ يمكنك الجمع بين اثنين في خيار واحد مفصول بمسافة، مثل flip-block flip-inline، للقلب قطريًا. تقوم المتصفحات بتقييم القائمة من اليسار إلى اليمين وتختار الخيار الأول الذي يبقي العنصر بالكامل داخل الشاشة.
الأخطاء الشائعة: لماذا لا يعمل position-try-fallbacks؟
السبب الأكثر شيوعًا هو أنك أعطيت المتصفح تقلبات في محور واحد فقط. إذا كان المرسى يقع بالقرب من زاوية، فقد يتجاوز العنصر الحدود في كلا الاتجاهين في وقت واحد، ولا يحل flip-block ولا flip-inline وحدهما هذه المشكلة — فأنت بحاجة أيضًا إلى خيار flip-block flip-inline المدمج.١ وهذا هو بالضبط سبب إدراج الخيارات الثلاثة في المثال أعلاه.
هناك أمران آخران قد يسببان ارتباكًا. أولاً، لا يتم تفعيل البدائل إلا عند تجاوز الحدود: إذا كان العنصر مناسبًا في مكانه الافتراضي، فسيتم تجاهل القائمة تمامًا، مما قد يبدو وكأن "لا شيء حدث". ثانيًا، قد يكون كود CSS الخاص بك قديمًا قبل إعادة التسمية في عام ٢٠٢٤. كانت الخاصية تسمى سابقًا position-try-options وكان position-area يسمى سابقًا inset-area؛ تم تغيير اسميهما، لذا فإن الأكواد القديمة لا تفعل شيئًا في المتصفحات الحالية.٢ استخدم الأسماء الحالية: 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>). يمكنك مزج الأسماء المخصصة والتكتيكات المحددة مسبقًا في خيار بديل واحد — عندما تفعل ذلك، يتم تطبيق الخيار المخصص أولاً ثم يتم تطبيق تحويل التكتيك فوقه.١ إذا كان الاسم في القائمة لا يطابق أي قاعدة @position-try، فسيتم تخطي هذا الإدخال ببساطة، وهو سبب صامت آخر لعدم "عمل" البديل.
ما الفرق بين position-area ودالة anchor()؟
position-area هي الطريقة السريعة القائمة على الشبكة لوضع عنصر؛ أما anchor() فهي الطريقة الدقيقة القائمة على الحواف. كلاهما يحل نفس المشكلة بمستويات مختلفة من التحكم.
تتعامل position-area مع المرسى كخلية مركزية في شبكة ٣×٣ ضمنية وتسمح لك بوضع العنصر في بلاطة واحدة أو أكثر باستخدام كلمات رئيسية مثل top، أو bottom span-right، أو bottom span-all. الصفوف هي top/center/bottom (منطقياً: block-start/center/block-end) والأعمدة هي left/center/right (منطقياً: start/center/end).٣ وهي تغطي معظم حالات القوائم المنسدلة وتلميحات الأدوات في سطر واحد.
توضع دالة anchor() داخل خصائص الإزاحة (top، left، inset-block-start، وما إلى ذلك) وتعيد طولاً عند حافة محددة للمرسى، مثل bottom: anchor(top) أو left: anchor(right). وهي تقبل الجوانب الفيزيائية، والجوانب المنطقية (start، end، self-start، self-end)، و center.٤ استخدم 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 (يخفيه تمامًا عندما يتم إخفاء المرسى تمامًا بسبب التجاوز أو التغطية).٥ هذه الخاصية أحدث من خصائص الإرساء الأساسية ولا تزال قيد الاستقرار عبر المحركات، لذا تعامل معها كتحسين تدريجي (progressive enhancement) وتحقق من الدعم قبل الاعتماد عليها في الإنتاج.
هل يدعم Safari خاصية CSS anchor positioning و @position-try؟
نعم. أطلق Safari خاصية CSS anchor positioning — بما في ذلك قاعدة @position-try و position-try-fallbacks — في إصدار Safari 26.0 (الصادر في سبتمبر ٢٠٢٥)، لكل من macOS و iOS.٦٧ الإرشادات القديمة التي تقول "Safari يدعم anchor() ولكن ليس @position-try" تصف حقبة معاينة Safari 18.x التجريبية وأصبحت الآن قديمة؛ النسخة المستقرة تدعم آلية البدائل (fallback).
ومع ذلك، فإن أي شخص يستخدم Safari 18.7 أو أقدم لا يملك خاصية anchor positioning على الإطلاق، لذا لا يزال وضع موضع أساسي احتياطي أمراً مهماً (انظر قسم المتصفحات أدناه).
هل CSS anchor positioning جاهزة للاستخدام الفعلي في ٢٠٢٦؟
بالنسبة لمعظم الجمهور، نعم — مع وجود خطة احتياطية للمتصفحات القديمة. وفقاً لموقع caniuse، الميزة مدعومة افتراضياً في Chrome و Edge 125+، و Safari 26.0+، و Firefox 147+، و Opera 111+، و Samsung Internet 27+، لتصل إلى حوالي ٨٣٪ من المستخدمين العالميين اعتباراً من أبريل ٢٠٢٦.٦
| المتصفح | أول إصدار بدعم افتراضي |
|---|---|
| Chrome | ١٢٥ |
| Edge | ١٢٥ |
| Firefox | ١٤٧ (مستقر 2026-01-13) |
| Safari (macOS + iOS) | 26.0 |
| Opera | ١١١ |
| Samsung Internet | ٢٧ |
كان Firefox هو آخر المحركات الرئيسية التي اعتمدتها: الإصدارات ١٤٥–١٤٦ كانت تحتوي عليها خلف تفضيل layout.css.anchor-positioning.enabled، وقام الإصدار ١٤٧ بتفعيلها افتراضياً.٦٨ الخلاصة العملية هي أن anchor positioning خيار ممتاز للعمل الجديد اليوم، طالما أن مستخدمي Firefox قبل ١٤٧ أو Safari قبل ٢٦ لا يزالون يرون تخطيطاً قابلاً للاستخدام.
كيف أحافظ على قابليتها للاستخدام في المتصفحات التي لا تدعم 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 تعوض هذا السلوك؛ استخدمها مع التحسين التدريجي بدلاً من إرسالها لكل زائر.٩ تجربة الانعكاس عبر @position-try تتكامل أيضاً بشكل طبيعي مع Popover API (سمة popover بالإضافة إلى popovertarget)، والتي أصبحت Baseline منذ يناير ٢٠٢٥ وتتولى العرض في الطبقة العليا (top-layer)، ومفتاح Escape، والإغلاق عند النقر في الخارج (light-dismiss) نيابة عنك.١٠
الخلاصة
تجعل خاصية CSS anchor positioning أخيراً مهمة "إبقاء هذه القائمة المنسدلة على الشاشة" مشكلة تنسيق بدلاً من كونها مشكلة JavaScript. ادرج بضعة position-try-fallbacks، وتضمن خيار القطر flip-block flip-inline، وحدد @position-try مخصصاً عندما تحتاج إلى تحكم دقيق، وأضف position-visibility لإخفاء العناصر التي تبتعد مراسيها عند التمرير. ثبت موضعاً أساسياً بسيطاً بحيث يظل Firefox قبل ١٤٧ و Safari قبل ٢٦ يعرضان المحتوى بشكل نظيف، وبذلك ستحصل على حل قوي يعتمد بشكل أساسي على CSS.
إذا كنت تبني واجهة مستخدم حديثة باستخدام CSS، فراجع أدلتنا المصاحبة حول بدء استخدام تخطيط وعرض CSS، وإطلاق الوضع الداكن في Tailwind v4 بدون وميض، وتصحيح أخطاء View Transitions API عندما لا تعمل.
الأسئلة الشائعة
كيف أجعل عنصر CSS مثبت ينعكس عندما يتجاوز الحدود؟
أضف position-try-fallbacks إلى العنصر المحدد الموضع وادرج المواضع مثل flip-block, flip-inline, flip-block flip-inline. يحافظ المتصفح على الموضع الافتراضي طالما أنه مناسب وينتقل إلى أول بديل يتجنب تجاوز الحدود.
لماذا لا تعمل position-try-fallbacks الخاصة بي؟
عادةً لأنك أدرجت انعكاسات أحادية المحور فقط، لذا فإن تجاوز الحدود عند الزوايا ليس له بديل صالح — أضف خيار flip-block flip-inline المشترك. تأكد أيضاً من أن العنصر يتجاوز الحدود بالفعل (البدائل لا تعمل أبداً بخلاف ذلك) وأنك تستخدم أسماء الخصائص الحالية، وليس الأسماء التي تم تغييرها مثل position-try-options أو inset-area.
ما الفرق بين position-area و anchor()؟
تضع position-area العنصر على شبكة ٣×٣ حول المرساة (anchor) باستخدام كلمات رئيسية مثل bottom span-right — وهي سريعة وتغطي معظم الحالات. بينما توضع anchor() داخل خصائص الإزاحة (inset) للتثبيت بحافة مرساة محددة، مثل bottom: anchor(top) — وهي أكثر دقة وتدعم مراسي متعددة.
هل يدعم Safari خاصية @position-try؟
نعم، منذ إصدار Safari 26.0 (سبتمبر ٢٠٢٥) على macOS و iOS. النصائح السابقة التي تقول "Safari يفتقر إلى @position-try" تشير إلى فترة المعاينة 18.x التجريبية وهي قديمة.
كيف أخفي عنصراً مثبتاً عندما تختفي مرساته عن الشاشة عند التمرير؟
استخدم position-visibility: anchors-visible لإخفاء العنصر بمجرد قص المرساة بالكامل، أو no-overflow لإخفائه عندما يتجاوز العنصر نفسه الحدود. هذه الخاصية أحدث من الخصائص الأساسية، لذا تحقق من الدعم قبل الاعتماد عليها.
هل CSS anchor positioning جاهزة للاستخدام الفعلي في ٢٠٢٦؟
لحوالي ٨٣٪ من المستخدمين نعم — Chrome/Edge 125+، و Firefox 147+، و Safari 26+ جميعها تدعمها افتراضياً. وفر موضعاً أساسياً بـ CSS عادي (أو polyfill من OddBird) لمتصفحات Firefox و Safari الأقدم.
المراجع
-
MDN Web Docs — "position-try-fallbacks". https://developer.mozilla.org/en-US/docs/Web/CSS/position-try-fallbacks ↩ ↩2 ↩3
-
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 ↩
-
MDN Web Docs — "position-area". https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/position-area ↩
-
MDN Web Docs — "دالة anchor() في CSS". https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Values/anchor ↩
-
MDN Web Docs — "خيارات التراجع والإخفاء الشرطي للتجاوز" (position-visibility). https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Anchor_positioning/Try_options_hiding ↩
-
Can I use — "CSS Anchor Positioning" (الاستخدام العالمي ~٨٢٫٨٣٪، StatCounter أبريل ٢٠٢٦). https://caniuse.com/css-anchor-positioning ↩ ↩٢ ↩٣
-
WebKit — "ميزات WebKit في Safari 26.0" (2025-09-15). https://webkit.org/blog/17333/webkit-features-in-safari-26-0/ ↩
-
Mozilla Bugzilla 1988225 — "تفعيل تفضيل تحديد المواقع بالإرساء (layout.css.anchor-positioning.enabled) افتراضياً على جميع القنوات". https://bugzilla.mozilla.org/show_bug.cgi?id=1988225 ↩
-
OddBird — CSS Anchor Positioning Polyfill. https://GitHub.com/oddbird/css-anchor-positioning ↩
-
web.dev — "واجهة Popover API أصبحت الآن متاحة حديثاً في Baseline". https://web.dev/blog/popover-baseline ↩
للوكلاء الآليين:get_post/posts/index.json/ar/css-anchor-positioning-fallbacks.md
نشرة مجانية
ابقَ على مسار النيرد
رسالتان كلّ أسبوع: شرح معمّق لموضوع واحد يوم الاثنين، وملخّص يوم الخميس للدورات والأدلّة والمقالات والبودكاست والوظائف.