عند وضع تلميح أداة أو قائمة منسدلة، غالبًا ما تريد تحديد موضعها بالنسبة إلى عنصر آخر على الصفحة. على الرغم من توفّر طرق تستخدم تحديد الموضع المطلق لتحقيق هذا التأثير، كانت المتطلبات الأكثر تعقيدًا تلجأ في السابق إلى تحديد موضع العناصر باستخدام JavaScript.
توفّر ميزة "تحديد موضع عنصر الارتساء في CSS" طريقة لتحديد موضع عنصر بشكل تصريحي بالنسبة إلى عنصر آخر.
عناصر الربط
لتحويل عنصر إلى رابط ثابت، عليك منحه قيمة anchor-name
لأي سلسلة تبدأ بشرطتين. هذا هو المعرّف الذي سيستخدمه العنصر الموضّع للعثور على عنصر الربط، ومن المفيد منحه اسمًا وصفيًا. يمكنك حتى منح عنصر أسماء مرجعية متعددة، إذا كان سيتم استخدامه كمرجع بطرق مختلفة.
عليك ضبط بعض السمات على العنصر الذي تم تحديد موضعه كي يمكن ربطه. أولاً، عليك إخراج العنصر من تدفّق المستند، ليصبح عائمًا، وذلك من خلال ضبط position: absolute
أو position: fixed
.
بعد ذلك، عليك تحديد نقطة الربط التي تريد ربط الجهاز بها من خلال ضبط position-anchor
على اسم نقطة الربط الذي ضبطته على نقطة الربط.
أخيرًا، عليك تحديد كيفية وضع نقطة الارتكاز. سنتعرّف على المزيد حول position-area
لاحقًا في هذه الوحدة.
#anchor {
anchor-name: --my-anchor;
}
#positionedElement {
position: absolute;
position-anchor: --my-anchor;
position-area: end;
}
الربط الضمني
أما النوافذ المنبثقة، فيمكن ربطها بسهولة أكبر. عند فتح نافذة منبثقة باستخدام زر يتضمّن popovertarget
أو من خلال ضبط source
باستخدام showPopover({source})
، يتمّ ضبط "عنصر ربط ضمني" للنافذة المنبثقة تلقائيًا. بما أنّ النافذة المنبثقة تظهر تلقائيًا مع position: fixed
، كل ما عليك فعله لتحديد موضعها هو ضبط الموضع.
#anchor{}
#positionedElement {
position-area: end;
margin: unset;
}
تحديد نطاق الإعلانات الثابتة المحتملة
يمكنك تنفيذ تحديد موضع العنصر الثابت كجزء من أحد المكوّنات، حتى تتمكّن من استخدام نمط مثل القائمة المنسدلة في مواضع متعددة. إذا كنت تستخدم anchor-name
نفسه عدة مرات، كيف تتأكّد من أنّ كل عنصر في الموضع يجد العنصر الثابت الصحيح؟
تتضمّن حلول JavaScript إضافة معرّفات فريدة إلى كل عنصر ربط، ثم الإشارة إلى هذا المعرّف من العنصر الذي تمّ تحديد موضعه. يصبح هذا الأمر مرهقًا، ولكن توفّر CSS حلاً أبسط باستخدام anchor-scope
.
تحدّد السمة anchor-scope
أسماء الروابط الثابتة التي ستتم مطابقتها فقط بين عنصر وجميع العناصر التابعة له. يقبل هذا الحقل قائمةً باسم واحد أو أكثر من أسماء الروابط الثابتة أو الكلمة الرئيسية all
للحدّ من نطاق جميع أسماء الروابط الثابتة المحدّدة.
يُفضّل إضافة anchor-scope
إلى عنصر رئيسي لكلّ من العنصر الموضّع وعنصر الربط الذي لا يحتوي على عناصر ربط أخرى بالاسم نفسه. في كثير من الأحيان، يكون هذا في جذر المكوّن القابل لإعادة الاستخدام.
يوضّح المثال التالي الفرق الذي تحدثه السمة anchor-scope
عند تطبيقها على عناصر متكرّرة لها القيمة نفسها anchor-name
. في المثال، تشير جميع عناصر <img>
وبانرات الصور إلى اسم الرابط --image
. عند تطبيق anchor-scope
على عناصر <li>
، لن يتطابق position-anchor: --image
إلا مع عنصر <img>
ضِمن عنصر <li>
نفسه كالبانر، وإلا سيتطابق مع آخر <img>
تم عرضه.
إقناع العملاء بالتبديل
بعد ربط العنصر بعنصر الارتساء، حان الوقت لتحديد موضعه. توفّر ميزة "تحديد موضع عنصر ثابت" طريقتَين لتحديد الموضع، وهما position-area
والدالة anchor()
.
position-area
تتيح لك السمة position-area
تحديد موضع عنصر حول نقطة الارتكاز من خلال تحديد كلمة رئيسية واحدة أو كلمتَين رئيسيتَين. ويشمل ذلك العديد من حالات الاستخدام الشائعة، وغالبًا ما يكون مكانًا جيدًا للبدء.
طريقة عمل position-area
تعمل position-area
من خلال إنشاء حاوية جديدة للعنصر الذي تم ضبط موضعه في منطقة تم إنشاؤها بواسطة حواف العنصر الثابت والحاوية الأصلية للعنصر الذي تم ضبط موضعه.
على الرغم من توفّر العديد من الكلمات الرئيسية لـ position-area
، يمكن تقسيمها إلى بضع فئات لتسهيل فهمها. Anchor-tool.com هي أداة رائعة لاستكشاف البنية.
الكلمات الرئيسية المادية
يمكنك استخدام الكلمات الرئيسية المادية top
وleft
وbottom
وright
وcenter
. على سبيل المثال، سيؤدي استخدام position-area: top right
إلى وضع العنصر الموضّع أعلى نقطة الربط وإلى يسارها. تحتوي هذه الكلمات الرئيسية أيضًا على مكافئات المحور الفعلي، وهي y-start
وx-start
وy-end
وx-end
.
الكلمات الرئيسية المنطقية
يمكنك أيضًا استخدام الكلمات الرئيسية المنطقية، block-start
وblock-end
وinline-start
وinline-end
. على سبيل المثال، سيؤدي استخدام position-area: block-end inline-start
إلى وضع العنصر الموضّع أسفل العنصر الثابت وإلى يساره في لغات مثل الإنجليزية، أو بعد العنصر الثابت على محور الكتلة وقبل العنصر الثابت على المحور المضمّن في وضع الكتابة الخاص بالمستند. يمكن أيضًا استخدام center
مع كلمة رئيسية منطقية.
يمكنك أيضًا حذف المحور إذا كنت تحدّد كلمات رئيسية منطقية، مع تحديد محور الكتلة أولاً ثم المحور المضمّن ثانيًا. position-area: start end
هو نفسه position-area: block-start inline-end
أو حتى position-area: inline-end block-start
.
الامتداد على مساحات شبكة متعددة
حتى الآن، ربما لاحظت أنّ هذه الخيارات تسمح لك فقط بوضع العنصر الموضّع ضمن مساحة شبكة واحدة. تؤدي إضافة البادئة span
إلى السمات الفعلية أو المنطقية إلى إضافة مساحة شبكة المركز المجاورة. سيتم وضع position-area: span-top right
على يمين العنصر الأساسي، ومن أسفل العنصر الأساسي إلى أعلى الحاوية الأصلية للعنصر الذي تم وضعه.
موضع منطقة شائع للقائمة المنسدلة هو position-area: block-end span-inline-end
.
تمتد الكلمة الرئيسية span-all
على 3 صفوف أو أعمدة.
كلمة رئيسية واحدة
إذا ضبطت كلمة رئيسية واحدة فقط، سيتم ضبط المحور الآخر تلقائيًا. تعمل هذه الميزة إلى حدّ كبير على النحو المتوقّع، ولكن قد يكون من المفيد فهم طريقة عملها.
إذا كانت الكلمة الرئيسية المقدَّمة واضحة بشأن محورها، يتم احتساب المحور الآخر على أنّه span-all
. هذا يعني أنّ position-area: bottom
يساوي position-area: bottom span-all
، وسيكون العنصر الذي تم تحديد موضعه أسفل العنصر الأساسي، وسيتوفّر له العرض الكامل للحاوية.
من ناحية أخرى، إذا لم تشِر الكلمة الرئيسية بوضوح إلى أحد المحاور، يتم تكرارها. position-area: start
تعادل start start
، ويتم وضعها في أعلى يمين العنصر الثابت في اللغات التي تُكتب من اليسار إلى اليمين.
الدالة anchor()
في حالات الاستخدام المتقدّم، قد لا تستوفي position-area
متطلباتك. تتيح لك الدالة anchor()
ضبط خصائص فردية للوحة المضمّنة استنادًا إلى موضع عنصر آخر. يؤدي ذلك إلى الحصول على طول CSS، ما يعني أنّه يمكنك استخدامه في العمليات الحسابية ومع دوال CSS الأخرى. بالإضافة إلى ذلك، يمكنك أيضًا ربط جوانب مختلفة بمثبتات مختلفة.
تأخذ الدالة anchor()
اسم رابط وموضع رابط. إذا كان العنصر يتضمّن عنصر ربط تلقائيًا، سواء تم ضبطه باستخدام position-anchor
أو بشكل ضمني، مثلاً باستخدام عنصر منبثق، يمكنك حذف اسم عنصر الربط.
.positionedElement {
block-start: anchor(--my-anchor start);
/* OR */
position-anchor: --my-anchor;
block-start: anchor(start);
}
القيم الاحتياطية
إذا لم يتم العثور على عنصر أساسي للدالة anchor()
، سيكون التعريف بأكمله غير صالح. قد يحدث ذلك إذا تم عرض عنصر الربط بعد العنصر الموضّع، أو إذا لم يكن هناك عنصر يحمل anchor-name
مطابقًا. للتعامل مع هذه الحالة، يمكنك ضبط مدة أو نسبة احتياطية.
.positionedElement {
block-start: anchor(--my-anchor, 100px)
}
في المثال السابق، يتم ربط القيمة اليسرى للعنصر الموضّع بالعنصر --focused-anchor
، ولكن لا يتوفّر العنصر anchor-name
إلا عند تمرير مؤشر الماوس فوق الزر الأول أو التركيز عليه. بما أنّ الدالة anchor()
تؤدي إلى تحديد طول، يمكنك استخدام مرجع آخر كبديل. إذا لم نقدّم عنصرًا احتياطيًا، لن يتم تحديد موضع العنصر المحدد.
الكلمات الرئيسية على الجانب
تحدّد قيمة جانب العنصر الثابت الحافة التي سيتم وضع العنصر الثابت مقابلها. على غرار position-area
، تتوافق قيمة جهة عنصر التثبيت مع عدة أنواع مختلفة من التركيبات.
النوع | القيم | الوصف |
---|---|---|
طبيعية | top ، وleft ، وbottom ، وright |
تتطابق الكلمات الرئيسية الفعلية مع جانب معيّن من العنصر الثابت، ولكن لا يمكن استخدامها إلا على المحور نفسه الذي يتم فيه ضبط موضع العنصر المحدّد. على سبيل المثال، يضع |
جانب الصفحة | inside ، outside |
تتوافق الكلمة الرئيسية على سبيل المثال، يشير |
منطقي | start ، وend ، وself-start ، وself-end |
تشير الكلمات الرئيسية المنطقية إلى جوانب عنصر الرابط استنادًا إلى وضع الكتابة للعنصر الذي تمّ تحديد موضعه باستخدام |
النسبة المئوية | 0% - 100% |
تضع قيمة النسبة المئوية العنصر الموضّع على طول المحور من بداية العنصر الأساسي إلى نهايته على المحور المحدّد. يقع |
يوضّح المثال التالي كيف تنتقل قيمة النسبة المئوية دائمًا من البداية إلى النهاية على المحور المحدّد:
جارٍ استخدام anchor()
بما أنّ anchor()
يمثّل طولاً، فهو مرن للغاية. يمكنك تعديل القيمة باستخدام دوال CSS، مثل max()
وcalc()
.
أحد القيود هو أنّه يمكنك استخدام وظائف anchor()
على خصائص الإضافات فقط.
يضيف المثال السابق خلفية إلى لوحة التفاصيل المفتوحة يتم تحريكها بسلاسة عند فتح لوحة مختلفة، ويتم توسيعها لتشمل لوحة تفاصيل تم التمرير فوقها. ولتحقيق ذلك، يتم استخدام min()
لاختيار الطول الأصغر بين نقطتَي ربط.
#indicator{
/* Use the smaller of the 2 values: */
inset-block-start: min(
/* 1. The start side of the default anchor, which is the open `<details>` element */
anchor(start),
/* 2. The start side of the hovered `<details>` element. */
anchor(--hovered start,
/* If no `<details>` element is hovered, this falls back to infinity px, so that the other value is smaller, and therefore used. */
var(calc(1px * infinity)))
);
}
يستخدم المثال أيضًا calc()
لإضافة مساحة مضمّنة حول اللوحة المفتوحة.
استخدام حجم عنصر الربط
يمكنك أيضًا استخدام الدالة anchor-size()
لاستخدام أبعاد العنصر الثابت لتحديد حجم العنصر الموضّع أو موضعه أو هامشه.
تأخذ anchor-size()
اسم رابط أو تستخدم الرابط التلقائي. بشكلٍ تلقائي، سيتم استخدام حجم العنصر الثابت على المحور الذي يتم استخدامه فيه، وبالتالي ستعرض الدالة width: anchor-size()
عرض العنصر الثابت. يمكنك أيضًا استخدام المحور الآخر من خلال تحديد الطول الذي تريده، وذلك باستخدام الكلمات الرئيسية المادية width
وheight
أو الكلمات الرئيسية المنطقية block
وinline
وself-block
وself-inline
.
التعامل مع تجاوز السعة
لقد أنشأت مكوّن قائمة منسدلة، واستخدمت تحديد موضع العنصر الثابت لوضع القائمة المنسدلة في المكان الذي تريده، ولكن بعد ذلك نقلت القائمة إلى الجانب الآخر من الشاشة، أو استخدمتها لقائمة مستخدم، وكان اسم المستخدم طويلاً جدًا. فجأةً، يختفي القائمة المنسدلة من الشاشة. فماذا أفعل الآن؟
يتضمّن تحديد موضع العناصر الثابتة في CSS نظامًا مدمجًا يتيح لك إنشاء مجموعة قوية من البدائل بسرعة عندما ينتهي موضع العنصر خارج الحاوية التي يتضمّنها.
خيارات بديلة
تأخذ قاعدة position-try-fallbacks
قائمة بخيارات احتياطية. عندما يفيض الموضع التلقائي، سيتم تجربة كل خيار بالترتيب إلى أن يتم العثور على موضع لا يفيض.
يمكنك استخدام أي قيمة position-area
كخيار احتياطي. في هذا المثال، في أوضاع الكتابة من اليمين إلى اليسار، مثل اللغة العربية، سيحاول العنصر الموضّع أن يكون في أسفل العنصر الثابت، ويمتد على العمودَين الأوسط والأيسر. إذا كان المحتوى يفيض، سيحاول الظهور في أسفل عنصر الربط، ويمتد على العمودَين الأيمن والأوسط. وإذا حدث تجاوز في هذا الموضع أيضًا، سيعود الموضع إلى الموضع التلقائي، حتى لو حدث تجاوز فيه.
.positioned-element {
position-area: block-end span-inline-end;
position-try-fallbacks: block-end span-inline-start;
}
هناك أيضًا العديد من الكلمات الرئيسية flip-
التي تعالج حالات الرجوع الشائعة. تجرب flip-block
وflip-inline
قلب العنصر على المحورين الأفقي والعمودي. يمكن أيضًا دمجها مع flip-block flip-inline
لقلب المحورَين. تعكس قيمة flip-start
العنصر الذي تم ضبط موضعه على خط قطري من زوايا بداية العنصر الأساسي إلى زوايا نهايته.
يمكنك أيضًا إنشاء خيار احتياطي مخصّص باستخدام @position-try
، ما يتيح لك ضبط الهوامش والمحاذاة وحتى تغيير نقطة الارتكاز.
@position-try --menu-below {
position-area: bottom span-right;
margin-top: 1em;
}
#positioned-element {
position-try: --menu-below;
}
يمكن إضافة flip-block
وflip-inline
إلى خيارات @position-try
الاحتياطية لإنشاء منتج مختلف.
#positioned-element {
position-try: --menu-below, flip-inline --menu-below;
}
في المثال السابق، يتّبع المتصفّح الخطوات التالية، ويتوقف بمجرد العثور على حلّ لا يؤدي إلى تجاوز السعة.
- يتم وضع العنصر مع
position-area: end
في أسفل يسار العنصر الثابت. - إذا حدث تجاوز، يتم وضع العنصر باستخدام خيار الاحتياط المخصّص المسمّى
--bottom-span-right
، والذي يضعه معposition-area: bottom span-right
، مع هامش إضافي أدناه. - إذا حدث تجاوز للسعة، يتم وضع العنصر باستخدام
flip-inline --bottom-span-right
، ما يجمع بين خيار العنصر الاحتياطي المخصّص وflip-inline
، وهو في الأساسposition-area: bottom span-left
. - إذا حدث تجاوز للسعة، يتم وضع العنصر باستخدام
--use-alternate
خيار الاحتياطي المخصّص، ما يؤدي إلى وضعه أسفل عنصر ربط مختلف تمامًا. - إذا حدث تجاوز للسعة، يعود العنصر إلى موضعه الأصلي مع
position-area: end
، على الرغم من أنّه من المعروف أنّ ذلك سيؤدي إلى تجاوز السعة.
الترتيب الاحتياطي
بشكلٍ تلقائي، عندما يفيض الموضع الأولي، سيحاول المتصفّح استخدام كل خيار في position-try-fallbacks
إلى أن يتم العثور على موضع لا يفيض. يمكنك إلغاء هذا السلوك باستخدام position-try-order
لاختبار كل خيار احتياطي، واستخدام الخيار الذي يتضمّن أكبر مساحة على محور محدّد.
يمكنك تحديد المحور باستخدام الكلمات الرئيسية المنطقية most-block-size
وmost-inline-size
أو باستخدام الكلمات الرئيسية الفعلية most-height
وmost-width
.
يمكن دمج position-try-order
وposition-try-fallbacks
مع الاختصار position-try
، مع وضع الترتيب أولاً.
الانتقال
عندما يتنقّل المستخدم في الصفحة، يتوقّع أن تتحرّك الصفحة بسلاسة. ولتحقيق ذلك، تفرض المتصفّحات قيودًا على كيفية استخدام ميزة "تحديد موضع العنصر الثابت" عند التمرير.
على الرغم من أنّه يمكنك ربط عنصر ثابت بمواضع في حاويات تمرير مختلفة، لن يتحرّك العنصر إلا استجابةً لتمرير أحد المواضع. سيكون هذا هو عنصر الربط التلقائي، وهو إما عنصر الربط الضمني من النافذة المنبثقة أو قيمة position-anchor
.
ستلاحظ أنّ العنصر الموضّع يظل مرئيًا حتى عندما يتم تمرير العنصر الأساسي بعيدًا عن منطقة العرض. لإخفاء العنصر الذي تم ضبط موضعه عندما يكون عنصر الربط مخفيًا، اضبط القيمة position-visibility: anchors-visible
. لا ينطبق ذلك فقط عندما يتم التمرير السريع فوق العنصر الثابت، ولكن أيضًا إذا كان مخفيًا بطرق أخرى، مثل visibility: hidden
.
التحقّق من فهمك
ما هي القيم الصالحة للجانب في anchor()
؟
inside
25%
25px
25px
كقيمة احتياطية، لا يمكن استخدام سوى النسب المئوية للجانب.block-start
start
ما هي القيم الصالحة لـ position-area
؟
top
block-end inline-end
block-start block-end
ما هي المواقع التي تتوافق مع الدالة anchor()
؟
top
margin-left
inset-block-start
transform
ماذا يحدث إذا كانت هناك روابط متعددة تتضمّن anchor-name
نفسه؟