البحث بشكل أعمق في استعلامات نمط الحاوية

عقدة المصدر: 1765194

كتبت بعض الأفكار المبكرة حول استعلامات نمط الحاوية فترة وجيزة. ما زالت الأيام الأولى. لقد تم تحديدها بالفعل في ملف مواصفات المستوى 1 لوحدة الاحتواء CSS (حاليًا في حالة مسودة المحرر) ولكن لا تزال هناك بعض المناقشات المعلقة جارية.

الفكرة الأساسية هي أنه يمكننا تحديد حاوية ثم تطبيق الأنماط بشكل مشروط على أحفادها بناءً على تصميمها المحسوب.

@container ?  {
  /* conditional styles */
}

أفضل مثال رأيته حتى الآن هو إزالة الخط المائل من شيء مثل , و عند استخدامها في سياق يكون فيه المحتوى مائلًا بالفعل:

em, i, q {
  font-style: italic; /* default UA behavior */
}

/* When the container's font-style is italic, remove italics from these elements. */
@container style(font-style: italic) {
  em, i, q {
    font-style: normal;
  }
}

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

كل عنصر عبارة عن حاوية نمط

لا نحتاج حتى إلى تعيين ملف container-name or container-type لتعريف حاوية نمط لأن كل شيء عبارة عن حاوية نمط بشكل افتراضي.

إذن ، ترى هذا المثال أعلاه الذي يزيل الخط المائل؟ لاحظ أنه لا يحدد الحاوية. ينتقل مباشرة إلى الاستعلام باستخدام الامتداد style() وظيفة. إذن ، ما الحاوية التي يتم الاستعلام عنها؟ ستكون الأصل المباشر للعناصر تلقي الأنماط المطبقة. وإذا لم يكن الأمر كذلك ، فهو كذلك أقرب حاوية النسبية التالية التي لها الأسبقية.

أحب ذلك. من CSS-y للغاية أن يبحث الاستعلام عن تطابق ، ثم يستمر في الظهور حتى يجد شرطًا مطابقًا.

كان من الصعب على عقلي الصغير فهم سبب قدرتنا على الابتعاد عن حاوية ضمنية تستند إلى الأنماط ولكن ليس كثيرًا عندما نتعامل مع استعلامات الأبعاد ، مثل size و inline-size. تشرح ميريام ذلك بلطف:

تتطلب الاستعلامات ذات الأبعاد css الاحتواء على حجم الحاوية وتخطيطها ونمطها لمنع حلقات التخطيط. يعد الاحتواء أمرًا جائرًا لتطبيقه على نطاق واسع ، لذلك كان من المهم أن يتحكم المؤلفون بعناية في ماهية العناصر (أو ليست) حاويات بحجم.

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

(توكيد لي)

كل ذلك يعود إلى العواقب - التي لا يوجد منها أي شيء بقدر كون كل شيء عبارة عن حاوية استعلام نمط مباشرة خارج الصندوق.

  • إذا تم العثور على حاوية: يتم حل الشروط مقابل تلك الحاوية.
  • في حالة تطابق عدة حاويات: أقرب حاوية ذات صلة لها الأسبقية.
  • إذا لم يتم العثور على تطابقات: unknown عاد.

نفس الشيئ روح "التسامح" كبقية CSS.

يمكن أن تدعم الحاوية كلاً من استعلامات الأبعاد والنمط

لنفترض أننا نريد تعريف استعلام نمط بدون صريح container-name:

@container style(font-style: italic) {
  em {
    font-style: normal;
  }
}

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

علينا استخدام صريح container-type للاستعلامات ذات الأبعاد ، ولكن ليس كثيرًا لاستعلامات النمط لأن كل عنصر هو استعلام نمط. هذا يعني أيضًا أن هذه الحاوية عبارة عن نمط و استعلام الأبعاد:

.card-container {
  container: card / inline-size; /* implictly a style query container as well */
}

استبعاد حاوية من الاستعلام

ربما لا نريد حاوية للمشاركة في عملية المطابقة. هذا هو المكان الذي قد يكون من الممكن تعيينه فيه container-type: none على عنصر.

.some-element {
  container-type: none;
}

توفر حاويات استعلام النمط الصريح مزيدًا من التحكم في ما يتم الاستعلام عنه

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

لذلك ، في تلك الحالات ، يجب علينا استخدام container-name لإعلام المتصفح صراحةً بالحاويات التي يمكنهم السحب منها. يمكننا حتى إعطاء حاوية عدة أسماء صريحة لجعلها تتطابق مع المزيد من الشروط:

.card {
  container-name: card layout theme;
}

أوه، و container-name يقبل أي عدد من الاختيارية و قابلة لإعادة الاستخدام أسماء حاوية! هذا أكثر مرونة عندما يتعلق الأمر بمساعدة المتصفح على الاختيار عند البحث عن التطابقات.

.theme {
  container-name: theme;
}
.grid {
  container-name: layout;
}
.card {
  container-name: card layout theme;
}

أتساءل نوعًا ما إذا كان يمكن اعتبار ذلك أيضًا "احتياطيًا" في حالة مرور حاوية واحدة.

يمكن دمج استعلامات الأنماط

or و and يسمح لنا المشغلون بدمج wueries للحفاظ على الأشياء جافة:

@container bubble style(--arrow-position: start start) or style(--arrow-position: end start) {
  .bubble::after {
    border-block-end-color: inherit;
    inset-block-end: 100%;
  }
}

/* is the same as... */
@container bubble style(--arrow-position: start start) {
  /* etc. */
}
@container bubble style(--arrow-position: end start) {
  /* etc. */
}

تبديل الأنماط

يوجد تداخل بسيط بين استعلامات نمط الحاوية و العمل الجاري لتحديد أ toggle() وظيفة. على سبيل المثال ، يمكننا التنقل بين اثنين font-style القيم ، على سبيل المثال italic و normal:

em, i, q {
  font-style: italic;
}

@container style(font-style: italic) {
  em, i, q {
    font-style: normal;
  }
}

رائع. لكن اقتراح CSS Toggles يشير إلى أن ملف toggle() ستكون الوظيفة نهجًا أبسط:

em, i, q {
  font-style: toggle(italic, normal);
}

ولكن أي شيء يتجاوز هذا النوع من حالات الاستخدام الثنائي هو المكان toggle() أقل ملاءمة. ومع ذلك ، فإن الاستفسارات المتعلقة بالأسلوب جيدة. تحدد Miriam ثلاث حالات يكون فيها استعلامات النمط أكثر ملاءمة من a toggle():

/* When font-style is italic, apply background color. */
/* Toggles can only handle one property at a time. */
@container style(font-style: italic) {
  em, i, q {
    background: lightpink;
  }
}

/* When font-style is italic and --color-mode equals light */
/* Toggles can only evaluate one condition at a time */
@container style((font-style: italic) and (--color-mode: light)) {
  em, i, q {
    background: lightpink;
  }
}

/* Apply the same query condition to multiple properties */
/* Toggles have to set each one individually as separate toggles */
@container style(font-style: italic) {
  em, i, q {
    /* clipped gradient text */
    background: var(--feature-gradient);
    background-clip: text;
    box-decoration-break: clone;
    color: transparent;
    text-shadow: none;
  }
}

تحل استعلامات النمط "Custom Property Toggle Hack"

لاحظ أن استعلامات النمط هي حل رسمي لـ "خدعة تبديل خاصية CSS المخصصة". هناك ، قمنا بتعيين خاصية مخصصة فارغة (--foo: ;) واستخدم الطريقة الاحتياطية المفصولة بفواصل "لتبديل" الخصائص بين تشغيل وإيقاف تشغيل عند تعيين الخاصية المخصصة إلى قيمة حقيقية.

button {
  --is-raised: ; /* off by default */
  
  border: 1px solid var(--is-raised, rgb(0 0 0 / 0.1));
  box-shadow: var(
    --is-raised,
    0 1px hsl(0 0% 100% / 0.8) inset,
    0 0.1em 0.1em -0.1em rgb(0 0 0 / 0.2)
  );
  text-shadow: var(--is-raised, 0 -1px 1px rgb(0 0 0 / 0.3));
}

button:active {
  box-shadow: var(--is-raised, 0 1px 0.2em black inset);
}

#foo {
  --is-raised: initial; /* turned on, all fallbacks take effect. */
}

هذا رائع جدًا ، كما أن هناك الكثير من العمل الذي يجعل استعلامات حاوية النمط تافهة.

استعلامات النمط والمحتوى الذي تم إنشاؤه بواسطة CSS

للمحتوى الذي تم إنشاؤه من قبل content ممتلكات ::before و ::after العناصر الزائفة ، الحاوية المطابقة هي العنصر الذي يتم إنشاء المحتوى عليه.

.bubble {
  --arrow-position: end end;
  container: bubble;
  border: medium solid green;
  position: relative;
}

.bubble::after {
  content: "";
  border: 1em solid transparent;
  position: absolute;
}

@container bubble style(--arrow-position: end end) {
  .bubble::after {
    border-block-start-color: inherit;
    inset-block-start: 100%;
    inset-inline-end: 1em;
  }
}

استعلامات النمط ومكونات الويب

يمكننا تعريف مكون الويب على أنه حاوية والاستعلام عنه حسب النمط. أولاً ، لدينا ملف المكون:


  
… …

ثم نستخدم ملف :host العنصر الزائف كحاوية لتعيين ملف container-nameأو المعلم container-type، وبعض السمات عالية المستوى عليه:

:host {
  container: media-host / inline-size;
  --media-location: before;
  --media-style: square;
  --theme: light;
}

العناصر الموجودة داخل ملف يمكن الاستعلام عن معلمات جزء:

@container media-host style(--media-style: round) {
  [part='img'] {
    border-radius: 100%;
  }
}

ما هي الخطوة التالية؟

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

الطابع الزمني:

اكثر من الخدع المغلق