ربط العناصر ببعضها البعض من خلال تحديد موضع ارتساء CSS

.

كيف تربط عنصرًا بعنصر آخر حاليًا؟ يمكنك محاولة تتبُّع مواضعها أو استخدام شكل من أشكال عنصر الغلاف.

<!-- index.html -->
<div class="container">
  <a href="/link" class="anchor">I’m the anchor</a>
  <div class="anchored">I’m the anchored thing</div>
</div>
/* styles.css */
.container {
  position: relative;
}
.anchored {
  position: absolute;
}

وغالبًا ما تكون هذه الحلول غير مثالية. تحتاج إلى JavaScript أو إدخال علامات إضافية. تهدف واجهة برمجة التطبيقات CSS anchor positioning API إلى حلّ هذه المشكلة من خلال توفير واجهة برمجة تطبيقات CSS لربط العناصر. وتوفّر هذه الطريقة وسيلة لتحديد موضع عنصر واحد وحجمه استنادًا إلى موضع العناصر الأخرى وحجمها.

تعرض الصورة تصميمًا لمقترح نافذة متصفّح يوضّح تفاصيل بنية تلميح.

دعم المتصفح

يمكنك تجربة واجهة برمجة التطبيقات CSS anchor positioning API في Chrome Canary من خلال تفعيل العلامة "ميزات النظام الأساسي للويب التجريبية". لتفعيل هذه الميزة التجريبية، افتح Chrome Canary وانتقِل إلى chrome://flags. بعد ذلك، فعِّل العلامة "ميزات قاعدة الويب التجريبية".

هناك أيضًا polyfill قيد التطوير من قِبل فريق Oddbird. احرص على الاطّلاع على المستودع على الرابط github.com/oddbird/css-anchor-positioning.

يمكنك التحقّق من توفّر ميزة التثبيت باستخدام:

@supports(anchor-name: --foo) {
  /* Styles... */
}

يُرجى العِلم أنّ واجهة برمجة التطبيقات هذه لا تزال في مرحلة تجريبية وقد تتغيّر. تتناول هذه المقالة الأجزاء المهمة على مستوى عالٍ. ولا يتطابق التنفيذ الحالي أيضًا تمامًا مع مواصفات مجموعة عمل CSS.

المشكلة

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

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

الحلول الحالية

في الوقت الحالي، هناك بعض الطرق المختلفة التي يمكنك اتّباعها لحلّ المشكلة.

أولاً، إليك النهج الأساسي "لفّ العنصر الأساسي". تأخذ كلا العنصرَين وتلفّهما في حاوية. يمكنك بعد ذلك استخدام position لتحديد موضع التلميح التوضيحي بالنسبة إلى العنصر الأساسي.

<div class="containing-block">
  <div class="tooltip">Anchor me!</div>
  <a class="anchor">The anchor</a>
</div>
.containing-block {
  position: relative;
}

.tooltip {
  position: absolute;
  bottom: calc(100% + 10px);
  left: 50%;
  transform: translateX(-50%);
}

يمكنك نقل الحاوية وسيظلّ كل شيء في المكان الذي تريده في معظم الأحيان.

يمكنك أيضًا استخدام أسلوب آخر إذا كنت تعرف موضع علامتك أو كان بإمكانك تتبُّعها بطريقة ما. يمكنك تمريرها إلى التلميح باستخدام السمات المخصّصة.

<div class="tooltip">Anchor me!</div>
<a class="anchor">The anchor</a>
:root {
  --anchor-width: 120px;
  --anchor-top: 40vh;
  --anchor-left: 20vmin;
}

.anchor {
  position: absolute;
  top: var(--anchor-top);
  left: var(--anchor-left);
  width: var(--anchor-width);
}

.tooltip {
  position: absolute;
  top: calc(var(--anchor-top));
  left: calc((var(--anchor-width) * 0.5) + var(--anchor-left));
  transform: translate(-50%, calc(-100% - 10px));
}

ولكن ماذا لو لم تكن تعرف موضع العنصر الأساسي؟ من المحتمل أن تحتاج إلى التدخل باستخدام JavaScript. يمكنك إجراء ما يفعله الرمز البرمجي التالي، ولكن هذا يعني الآن أنّ أنماطك بدأت في الخروج من CSS والانتقال إلى JavaScript.

const setAnchorPosition = (anchored, anchor) => {
  const bounds = anchor.getBoundingClientRect().toJSON();
  for (const [key, value] of Object.entries(bounds)) {
    anchored.style.setProperty(`--${key}`, value);
  }
};

const update = () => {
  setAnchorPosition(
    document.querySelector('.tooltip'),
    document.querySelector('.anchor')
  );
};

window.addEventListener('resize', update);
document.addEventListener('DOMContentLoaded', update);

يطرح هذا الأمر بعض الأسئلة:

  • متى يمكنني احتساب الأنماط؟
  • كيف يمكنني احتساب الأنماط؟
  • كم مرة يجب احتساب الأنماط؟

هل تم حلّ المشكلة؟ قد يكون ذلك مناسبًا لحالة الاستخدام الخاصة بك، ولكن هناك مشكلة واحدة: لا يمكن تكييف حلّنا. لا يستجيب. ماذا يحدث إذا تم اقتطاع العنصر المرتبط بإطار العرض؟

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

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

في ما يلي الشكل الذي قد يبدو عليه الرمز لاستخدام "floating-ui"، وهي حزمة رائجة لحلّ هذه المشكلة:

import {computePosition, flip, offset, autoUpdate} from 'https://cdn.jsdelivr.net/npm/@floating-ui/dom@1.2.1/+esm';

const anchor = document.querySelector('.anchor')
const tooltip = document.querySelector('.tooltip')

const updatePosition = () => {  
  computePosition(anchor, tooltip, {
    placement: 'top',
    middleware: [offset(10), flip()]
  })
    .then(({x, y}) => {
      Object.assign(tooltip.style, {
        left: `${x}px`,
        top: `${y}px`
      })
  })
};

const clean = autoUpdate(anchor, tooltip, updatePosition);

حاوِل إعادة وضع العنصر الثابت في هذا الإصدار التجريبي الذي يستخدم هذا الرمز.

قد لا يعمل "مساعد التلميحات" على النحو المتوقّع. ويتفاعل مع الخروج من إطار العرض على محور y ولكن ليس على محور x. اطّلِع على المستندات، ومن المرجّح أن تعثر على حلّ يناسبك.

ولكن قد يستغرق العثور على حزمة مناسبة لمشروعك الكثير من الوقت. هذه قرارات إضافية وقد تؤدي إلى الإحباط إذا لم تعمل بالطريقة التي تريدها.

استخدام موضع الرابط

أدخِل واجهة برمجة التطبيقات لتحديد موضع عنصر الربط في CSS. الفكرة هي الاحتفاظ بأنماطك في CSS وتقليل عدد القرارات التي عليك اتخاذها. أنت تأمل في تحقيق النتيجة نفسها، ولكن الهدف هو تحسين تجربة المطوّر.

  • لا يلزم استخدام JavaScript.
  • يمكنك السماح للمتصفّح بتحديد أفضل موضع استنادًا إلى إرشاداتك.
  • عدم الاعتماد على أي أدوات تابعة لجهات خارجية
  • لا تتضمّن أي عناصر غلاف.
  • تعمل هذه الأداة مع العناصر التي تكون في الطبقة العليا.

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

أولاً، عليك اختيار طريقة تعريف العنصر الأساسي. يمكنك إجراء ذلك في CSS من خلال ضبط السمة anchor-name على عنصر الربط. يمكن إدخال قيمة dashed-ident.

.anchor {
  anchor-name: --my-anchor;
}

بدلاً من ذلك، ستتمكّن من تحديد رابط في ملف HTML باستخدام السمة anchor. قيمة السمة هي معرّف عنصر الربط. يؤدي ذلك إلى إنشاء رابط ضمني.

<a id="my-anchor" class="anchor"></a>
<div anchor="my-anchor" class="boat">I’m a boat!</div>

بعد تحديد عنصر ربط، يمكنك استخدام الدالة anchor. تأخذ الدالة anchor 3 وسيطات:

  • عنصر الربط: anchor-name العنصر المراد استخدامه، أو يمكنك حذف القيمة لاستخدام عنصر ربط implicit. ويمكن تحديدها من خلال علاقة HTML أو باستخدام سمة anchor-default مع قيمة anchor-name.
  • جانب الربط: كلمة رئيسية للموقع الذي تريد استخدامه. يمكن أن يكون top أو right أو bottom أو left أو center أو غير ذلك، أو يمكنك إدخال نسبة مئوية. على سبيل المثال، تكون النسبة المئوية% 50 مساوية center.
  • القيمة الاحتياطية: هذه قيمة احتياطية اختيارية تقبل طولًا أو نسبة مئوية.

يمكنك استخدام الدالة anchor كقيمة لسمات الحشو (top أو right أو bottom أو left أو ما يعادلها منطقيًا) للعنصر المرتبط. يمكنك أيضًا استخدام الدالة anchor في calc:

.boat {
  bottom: anchor(--my-anchor top);
  left: calc(anchor(--my-anchor center) - (var(--boat-size) * 0.5));
}

 /* alternative with anchor-default */
.boat {
  anchor-default: --my-anchor;
  bottom: anchor(top);
  left: calc(anchor(center) - (var(--boat-size) * 0.5));
}

لا تتوفّر سمة center inset، لذا يمكنك استخدام calc إذا كنت تعرف حجم العنصر المرتبط. لماذا لا يمكن استخدام translate؟ يمكنك استخدام ما يلي:

.boat {
  anchor-default: --my-anchor;
  bottom: anchor(top);
  left: anchor(center);
  translate: -50% 0;
}

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

ربما لاحظت استخدام السمة المخصّصة --boat-size أعلاه. ولكن إذا أردت أن يستند حجم العنصر المرتبط إلى حجم العنصر الأساسي، يمكنك أيضًا الوصول إلى هذا الحجم. بدلاً من احتسابها بنفسك، يمكنك استخدام الدالة anchor-size. على سبيل المثال، لجعل قاربنا أكبر بأربعة أضعاف من عرض المرساة:

.boat {
  width: calc(4 * anchor-size(--my-anchor width));
}

يمكنك أيضًا الاطّلاع على الارتفاع باستخدام anchor-size(--my-anchor height). ويمكنك استخدامها لضبط حجم أي محور أو كليهما.

ماذا لو أردت الارتساء على عنصر بوضع absolute؟ والقاعدة هي أنّ العناصر لا يمكن أن تكون أخوة. في هذه الحالة، يمكنك لفّ العنصر النائب بحاوية ذات موضع relative. وبعد ذلك، يمكنك الربط بها.

<div class="anchor-wrapper">
  <a id="my-anchor" class="anchor"></a>
</div>
<div class="boat">I’m a boat!</div>

اطّلِع على هذا العرض التوضيحي الذي يمكنك من خلاله سحب المرساة حولها وسيتبعها القارب.

تتبُّع موضع الانتقال للأعلى أو للأسفل

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

.boat { anchor-scroll: --my-anchor; }

جرِّب هذا العرض التوضيحي الذي يمكنك من خلاله تفعيل anchor-scroll وإيقافه باستخدام مربّع الاختيار في الزاوية.

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

راجِع هذا الإصدار التجريبي الذي يتضمّن حاوية لفائف تحتوي على عناصر تثبيت تتضمّن نصائح. قد لا تكون عناصر التلميح التي تكون مربّعات معلومات منبثقة في الموقع نفسه مع عناصر الربط:

ولكن ستلاحظ كيف تتتبّع النوافذ المنبثقة روابط الربط الخاصة بها. يمكنك تغيير حجم حاوية التمرير هذه وسيتم تعديل المواضع نيابةً عنك.

موضع الإعلان الاحتياطي والموضع التلقائي للإعلان

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

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

إذا اطّلعت على رمز العرض التجريبي الأخير، لاحظت أنّه كان هناك موقع position-fallback قيد الاستخدام. إذا اطّلعت على الحاوية، ربما لاحظت أنّ النوافذ المنبثقة المرسَخة هذه قفزت. وقد حدث ذلك عندما اقتربت نقاط الربط الخاصة بكل منها من حدود إطار العرض. في هذه اللحظة، تحاول النوافذ المنبثقة تعديل حجمها للبقاء في مساحة العرض.

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

.tooltip {
  position: absolute;
  bottom: anchor(--my-anchor auto);
  top: auto;
}

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

قد يبدو position-fallback الذي يحاول عرض التلميحَين أعلاه ثم تحته على النحو التالي:

@position-fallback --top-to-bottom {
  @try {
    bottom: anchor(top);
    left: anchor(center);
  }

  @try {
    top: anchor(bottom);
    left: anchor(center);
  }
}

يظهر تطبيق ذلك على نصائح التلميح على النحو التالي:

.tooltip {
  anchor-default: --my-anchor;
  position-fallback: --top-to-bottom;
}

يعني استخدام anchor-default أنّه يمكنك إعادة استخدام position-fallback لعناصر أخرى. يمكنك أيضًا استخدام سمة مخصّصة على مستوى النطاق لضبط anchor-default.

يمكنك مشاهدة هذا العرض التوضيحي باستخدام القارب مرة أخرى. تم ضبط position-fallback. عند تغيير موضع المرساة، سيتم تعديل القارب ليبقى داخل الحاوية. حاوِل أيضًا تغيير قيمة الحشو التي تعمل على ضبط الحشو في النص. لاحظ كيف يصحّح المتصفّح موضع الإعلان. يتم تغيير المواضع من خلال تغيير محاذاة الشبكة للحاوية.

يحاول position-fallback هذه المرة استخدام أوضاع مختلفة باتجاه عقارب الساعة.

.boat {
  anchor-default: --my-anchor;
  position-fallback: --compass;
}

@position-fallback --compass {
  @try {
    bottom: anchor(top);
    right: anchor(left);
  }

  @try {
    bottom: anchor(top);
    left: anchor(right);
  }

  @try {
    top: anchor(bottom);
    right: anchor(left);
  }

  @try {
    top: anchor(bottom);
    left: anchor(right);
  }
}


أمثلة

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

قوائم السياقات

لنبدأ بقائمة سياق باستخدام واجهة برمجة التطبيقات Popover API. الفكرة هي أنّ النقر على الزر الذي يتضمّن سهمًا متّجهًا للأسفل سيؤدي إلى عرض قائمة سياقات. وستحتوي هذه القائمة على قائمة أخرى لتوسيع نطاقها.

إنّ الترميز ليس هو الجزء المهم هنا. ولكن لديك ثلاثة أزرار يستخدم كلٌّ منها popovertarget. بعد ذلك، لديك ثلاثة عناصر تستخدم السمة popover. يمنحك ذلك إمكانية فتح قوائم السياقات بدون أي لغة JavaScript. قد يبدو ذلك على النحو التالي:

<button popovertarget="context">
  Toggle Menu
</button>        
<div popover="auto" id="context">
  <ul>
    <li><button>Save to your Liked Songs</button></li>
    <li>
      <button popovertarget="playlist">
        Add to Playlist
      </button>
    </li>
    <li>
      <button popovertarget="share">
        Share
      </button>
    </li>
  </ul>
</div>
<div popover="auto" id="share">...</div>
<div popover="auto" id="playlist">...</div>

يمكنك الآن تحديد position-fallback ومشاركته بين قوائم السياقات. ونحرص أيضًا على عدم ضبط أي أنماط inset للنوافذ المنبثقة.

[popovertarget="share"] {
  anchor-name: --share;
}

[popovertarget="playlist"] {
  anchor-name: --playlist;
}

[popovertarget="context"] {
  anchor-name: --context;
}

#share {
  anchor-default: --share;
  position-fallback: --aligned;
}

#playlist {
  anchor-default: --playlist;
  position-fallback: --aligned;
}

#context {
  anchor-default: --context;
  position-fallback: --flip;
}

@position-fallback --aligned {
  @try {
    top: anchor(top);
    left: anchor(right);
  }

  @try {
    top: anchor(bottom);
    left: anchor(right);
  }

  @try {
    top: anchor(top);
    right: anchor(left);
  }

  @try {
    bottom: anchor(bottom);
    left: anchor(right);
  }

  @try {
    right: anchor(left);
    bottom: anchor(bottom);
  }
}

@position-fallback --flip {
  @try {
    bottom: anchor(top);
    left: anchor(left);
  }

  @try {
    right: anchor(right);
    bottom: anchor(top);
  }

  @try {
    top: anchor(bottom);
    left: anchor(left);
  }

  @try {
    top: anchor(bottom);
    right: anchor(right);
  }
}

يمنحك ذلك واجهة مستخدم قائمة سياق متداخلة قابلة للتكيّف. جرِّب تغيير موضع المحتوى باستخدام أداة الاختيار. يؤدي الخيار الذي تختاره إلى تعديل محاذاة الشبكة. ويؤثّر ذلك في كيفية تحديد موضع عناصر النافذة المنبثقة من خلال موضع العنصر الأساسي.

التركيز والمتابعة

يجمع هذا الإصدار التجريبي بين العناصر الأساسية في CSS من خلال استخدام :has()‎. والفكرة هي نقل مؤشر مرئي للعنصر input الذي يجذب الانتباه.

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

#email {
    anchor-name: --email;
  }
  #name {
    anchor-name: --name;
  }
  #password {
    anchor-name: --password;
  }
:root:has(#email:focus) {
    --active-anchor: --email;
  }
  :root:has(#name:focus) {
    --active-anchor: --name;
  }
  :root:has(#password:focus) {
    --active-anchor: --password;
  }

:root {
    --active-anchor: --name;
    --active-left: anchor(var(--active-anchor) right);
    --active-top: calc(
      anchor(var(--active-anchor) top) +
        (
          (
              anchor(var(--active-anchor) bottom) -
                anchor(var(--active-anchor) top)
            ) * 0.5
        )
    );
  }
.form-indicator {
    left: var(--active-left);
    top: var(--active-top);
    transition: all 0.2s;
}

ولكن كيف يمكنك تحسين هذه الميزة؟ يمكنك استخدامها لبعض أشكال التراكب التعليمي. يمكن أن ينتقل تلميح المعلومات بين نقاط الاهتمام ويُعدّل محتواه. يمكنك استخدام ميزة تمويه المحتوى. يمكن استخدام صور متحركة منفصلة تتيح لك تحريك display أو عرض الانتقالات.

حساب الرسم البياني الشريطي

يمكنك أيضًا استخدام رمز calc مع موضع العنصر الأساسي. تخيل رسمًا بيانيًا يتضمّن بعض النوافذ المنبثقة التي تضيف تعليقات توضيحية إلى الرسم البياني.

يمكنك تتبُّع أعلى القيم وأدناها باستخدام min وmax في CSS. يمكن أن يبدو رمز CSS على النحو التالي:

.chart__tooltip--max {
    left: anchor(--chart right);
    bottom: max(
      anchor(--anchor-1 top),
      anchor(--anchor-2 top),
      anchor(--anchor-3 top)
    );
    translate: 0 50%;
  }

يتم استخدام بعض لغة JavaScript لتعديل قيم الرسم البياني وبعض تنسيقات CSS لتصميم الرسم البياني. ولكنّ موضع الربط يهتم بتعديلات التنسيق نيابةً عنا.

مقابض تغيير الحجم

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

يمكنك التعامل مع نقاط الربط مثل مقابض تغيير الحجم المخصّصة والاعتماد على قيمة inset.

.container {
   position: absolute;
   inset:
     anchor(--handle-1 top)
     anchor(--handle-2 right)
     anchor(--handle-2 bottom)
     anchor(--handle-1 left);
 }

في هذا الاختبار التجريبي، تجعل أداة GreenSock Draggable الأيدي قابلة للسحب. ولكن يتم تغيير حجم عنصر <img> لملء الحاوية التي يتم تعديلها لملء الفجوة بين مقابض العنصر.

هل هو SelectMenu؟

هذه الميزة الأخيرة هي لمحة عن الميزات القادمة. ولكن يمكنك إنشاء نافذة منبثقة يمكن التركيز عليها، وبذلك يمكنك تحديد موضع العنصر الأساسي. يمكنك إنشاء أسس عنصر <select> قابل للتنسيق.

<div class="select-menu">
<button popovertarget="listbox">
 Select option
 <svg>...</svg>
</button>
<div popover="auto" id="listbox">
   <option>A</option>
   <option>Styled</option>
   <option>Select</option>
</div>
</div>

سيسهّل ذلك استخدام anchor ضمني. ولكن يمكن أن يظهر تنسيق CSS لنقطة بداية أساسية على النحو التالي:

[popovertarget] {
 anchor-name: --select-button;
}
[popover] {
  anchor-default: --select-button;
  top: anchor(bottom);
  width: anchor-size(width);
  left: anchor(left);
}

يمكنك الجمع بين ميزات Popover API مع CSS Anchor positioning (تحديد موضع العنصر) للوصول إلى النتيجة المطلوبة.

من الرائع أن تبدأ بتقديم محتوى مثل :has(). يمكنك تدوير العلامة عند فتحها:

.select-menu:has(:open) svg {
  rotate: 180deg;
}

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


هذا كل ما في الأمر.

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

صورة من CHUTTERSNAP على Unsplash