تلميحات تستند إلى الموضع

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

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

المشكلة

لنفترض أنّ هناك تلميحًا يظهر فوق علامة الارتساء تلقائيًا. ويحتوي على سهم "لأسفل" في الجزء السفلي. إذا انتقل المستخدم إلى الأسفل وانقلب تلميح الشاشة ليظهر أسفل نقطة الارتكاز، سيشير السهم الآن إلى الاتجاه الخاطئ وسيكون على الجانب الخطأ من تلميح الشاشة.

الحلّ: طلبات البحث عن الحاويات الثابتة

من خلال ضبط container-type: anchored على العنصر الذي تم تحديد موضعه، يمكنك تحويله إلى حاوية طلب بحث تعرف حالتها المحدّدة من خلال الارتساء. يمكنك بعد ذلك استخدام طلب البحث @container anchored() لتعديل العناصر التابعة أو العناصر الزائفة.

1. إنشاء تلميح ومشغّل

استخدِم Popover API لإنشاء تلميح. يؤدي استدعاء النافذة المنبثقة عبر popovertarget إلى إنشاء اتصال إرساء ضمني تلقائيًا مع زر التشغيل، لذلك لا يلزم استخدام anchor-name أو position-anchor بشكل صريح.

<button popovertarget="tooltip" id="anchor" aria-describedby="tooltip">anchor</button>
<div id="tooltip" popover role="tooltip"></div>

إعادة ضبط أنماط الهوامش والمسافات البادئة في النوافذ المنبثقة لاستخدامها مع ميزة "تحديد موضع الارتساء"، ولكن فقط إذا كانت هذه الميزة متاحة

@supports (anchor-name: --my-anchor) {
  [popover] {
    inset: auto;
    margin: unset;
  }
}

2. إعداد الحاوية

طبِّق السمة container-type: anchored على العنصر الذي يتم تحديد موضعه. يجب أيضًا تحديد السمة position-try-fallbacks لهذا العنصر لتفعيل سلوك التقليب.

#tooltip {
  position: fixed;
  position-area: block-start;
  position-try-fallbacks: flip-block;

  /* Enable anchored container queries */
  container-type: anchored;
}

3- التصميم استنادًا إلى الشكل الاحتياطي

استخدِم @container anchored(fallback: <value>) لتطبيق الأنماط عندما يكون عنصر احتياطي معيّن نشطًا.

Like all container queries, @container can only style descendants of the container. من الاستراتيجيات الشائعة لإنشاء الأسهم استخدام العنصرَين الزائفَين ::before و::after، اللذين يتم التعامل معهما كعناصر فرعية ويمكن تنسيقهما مباشرةً. ومع ذلك، لتصميم تلميح الأدوات نفسه (كما هو موضّح في الخطوة 4)، سنضيف عنصرًا فرعيًا إلى تلميح الأدوات، وننشئ السهم في العنصر الزائف ::before.

<div id="tooltip" popover role="tooltip">
  <div class="tooltip-content">Tooltip</div>
</div>
.tooltip-content::before {
  /* Default "down" arrow for the 'top' position */
  content: "▼";
  position: absolute;
  inset-block-end: 0;
  inset-inline-start: 1rem;
}

/* Update to an "up" arrow when the 'flip-block' fallback (bottom) is active */
@container anchored(fallback: flip-block) {
  .tooltip-content::before {
    content: "▲";
    inset-block-start: 0;
    inset-block-end: auto;
  }
}

4. تصميم الحاوية نفسها

إذا كنت بحاجة إلى تغيير السمات في الحاوية نفسها (مثل margin أو background-color) عند قلبها، عليك استخدام عنصر تضمين داخلي.

  1. طبِّق السمة container-type: anchored على العنصر الخارجي الذي تم تحديد موضعه.
  2. استهدِف العنصر الداخلي ضمن مجموعة @container.
@container anchored(fallback: flip-block) {
  .tooltip-content {
    border-radius: 0 0 .5rem .5rem;
    margin-block-start: 0.25rem;
  }
}

أفضل الممارسات

  • تفضيل البدائل المنطقية: استخدِم كلمات رئيسية مثل flip-block وflip-inline في position-try-fallbacks لطلبات البحث الأبسط التي تتعامل مع الكتابة من اليمين إلى اليسار وأوضاع الكتابة المختلفة تلقائيًا.
  • استخدام العناصر الزائفة للأسهم: أسهم تلميحات الشاشة هي عناصر تزيينية بحتة، وهي مثالية لاستخدام ::before أو ::after، والتي يمكن تصميمها من خلال طلبات البحث عن الحاويات الثابتة بدون نموذج DOM إضافي.

استراتيجيات احتياطية

يُعدّ تحديد موضع السهم استنادًا إلى الموضع الاحتياطي المطبَّق تحسينًا تدريجيًا، ولا توجد طريقة أخرى للتفاعل مع الموضع الاحتياطي. لإخفاء السهم في المتصفّحات التي لا تتيح استخدام طلبات البحث عن حاويات موضع الارتساء، اختبِر توافق CSS مع @supports (container-type: anchored).

@supports (container-type: anchored) {
  .tooltip-content::before {
    content: "▼";
  }
}

الخيارات الاحتياطية وتوافق المتصفّحات مع Popover

تعتمد واجهة Popover API في الغالب على التحسين التدريجي، ولكن سلوكياتها المحدّدة، مثل الترقية إلى الطبقة العليا والإغلاق البسيط واستدعاء popovertarget، ليس لها مكافئ في CSS فقط. تحتاج المتصفّحات القديمة إلى polyfill أو إلى إجراء احتياطي يدوي إذا كنت تفضّل عدم شحنها.

Polyfill: لإتاحة السمة popover في المتصفّحات القديمة، يمكنك تحميل @oddbird/popover-polyfill بشكل مشروط. إجراء إلزامي: يجب رصد الميزة من خلال التحقّق من السمة popover في HTMLElement.prototype، وتحميل polyfill فقط في حال عدم توفّر الدعم الأصلي، ويجب عدم تحميله بدون شروط.

باستخدام حزمة أو خريطة استيراد:

// MANDATORY: Feature detect 'popover' on HTMLElement.prototype.
if (!("popover" in HTMLElement.prototype)) {
  import("@oddbird/popover-polyfill");
}

بدون حزمة، يمكنك الاستيراد من شبكة توصيل محتوى (CDN) داخل <script type="module">:

<script type="module">
  if (!("popover" in HTMLElement.prototype)) {
    import("https://unpkg.com/@oddbird/popover-polyfill@latest/dist/popover.min.js");
  }
</script>

تحذير بشأن التنسيق: لا يمكن لـ polyfill تحديد الفئة الزائفة :popover-open الحقيقية، لذا يتم تطبيق فئة .\:popover-open بدلاً من ذلك. إجراء إلزامي: ادمج السمتَين مع :is() أو :where()، وإلا ستتجاهل المتصفحات التي لا تتضمّن :popover-open القاعدة بأكملها:

[popover]:is(:popover-open, .\:popover-open) {
  display: block;
}

بدلاً من ذلك، يمكنك استخدام position: fixed واحتساب الإحداثيات يدويًا من خلال getBoundingClientRect() أو الاعتماد على تحديد الموضع التلقائي باستخدام inset: auto إذا كان ذلك مقبولاً لحالة الاستخدام، وذلك كحل بديل قديم بدون polyfill.

لا تتوافق المتصفّحات التي لا تتيح استخدام Popover API مع ميزة تحديد موضع الارتساء، لذا سيظهر التلميح في وسط الشاشة.