حالة خدمة مقارنة الأسعار (CSS) لعام 2022

ميزات تصميم الويب الحالية والمستقبلية، كما تم عرضها في مؤتمر Google IO 2022، بالإضافة إلى بعض الميزات الإضافية

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

نظرة عامة

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

جدول المحتويات

استخدِم القائمة أدناه للانتقال إلى المواضيع التي تهمّك:

توافُق المتصفح

أحد الأسباب الرئيسية التي أدّت إلى إطلاق العديد من ميزات CSS بشكل تعاوني هو الجهود التي بذلت في إطار Interop 2022. قبل دراسة جهود Interop، من المهم إلقاء نظرة على جهود Compat 2021.

Compat 2021

كانت أهداف عام 2021، المستندة إلى ملاحظات المطوّرين من خلال الاستطلاعات، هي تثبيت الميزات الحالية وتحسين مجموعة الاختبارات وزيادة نتائج النجاح للمتصفحات في خمس ميزات:

  1. sticky تحديد موضع الإعلان
  2. aspect-ratio تحديد المقاس
  3. التنسيق flex
  4. التنسيق grid
  5. transform تحديد الموضع والصورة المتحركة

وقد ارتفعت نتائج الاختبارات بشكل عام، ما يدل على تحسّن الثبات والموثوقية. تهانينا الحارّة للفِرق المشاركة!

Interop 2022

في هذا العام، اجتمعت المتصفحات لمناقشة الميزات والأولويات التي تنوي العمل عليها، وتوحيد جهودها. وقد خطّطوا لتوفير ميزات الويب التالية للمطوّرين:

  1. @layer
  2. مساحات الألوان والدوال
  3. الاحتواء
  4. <dialog>
  5. توافق النماذج
  6. الانتقال
  7. Subgrid
  8. فن الطباعة
  9. وحدات إطار العرض
  10. توافق الويب

هذه قائمة مثيرة وطموحة وأتطلّع إلى رؤية نتائجها.

أغاني جديدة لعام 2022

ليس من المستغرب أنّ حالة CSS لعام 2022 تأثّرت بشكل كبير بجهود Interop 2022.

طبقات متتالية

Browser Support

  • Chrome: 99.
  • Edge: 99.
  • Firefox: 97.
  • Safari: 15.4.

Source

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

باستخدام @layer، يمكن لملف الإدخال تحديد الطبقات وترتيبها مسبقًا. بعد ذلك، عند تحميل الأنماط أو تعريفها، يمكن وضعها ضمن طبقة، ما يتيح الحفاظ على أهمية تجاهل الأنماط بدون الحاجة إلى إدارة ترتيب التحميل بدقة.

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

تساعد &quot;أدوات مطوّري البرامج في Chrome&quot; في عرض الأنماط التي تأتي من الطبقات المختلفة:

لقطة شاشة من الشريط الجانبي &quot;الأنماط&quot; في &quot;أدوات مطوّري البرامج في Chrome&quot;، توضّح كيفية ظهور الأنماط ضمن مجموعات &quot;الطبقات&quot; الجديدة

الموارد

Subgrid

Browser Support

  • Chrome: 117.
  • Edge: 117.
  • Firefox: 71.
  • Safari: 16.

Source

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

بعد subgrid، يمكن أن يعتمد عنصر ثانوي في شبكة الأعمدة أو الصفوف الخاصة بالعناصر الرئيسية، وأن يضبط موضع العنصر الثانوي أو العناصر الثانوية الأخرى بما يتناسب معها.

في العرض التوضيحي التالي، ينشئ عنصر body شبكة كلاسيكية من ثلاثة أعمدة: يُطلق على العمود الأوسط اسم main، ويُطلق على العمودَين الأيمن والأيسر اسم خطوطهما fullbleed. بعد ذلك، يتبنّى كل عنصر في النص، <nav> و<main>، الأسطر المسماة من النص من خلال ضبط grid-template-columns: subgrid.

​​body {
  display: grid;
  grid-template-columns:
    [fullbleed-start]
    auto [main-start] min(90%, 60ch) [main-end] auto
    [fullbleed-end]
  ;
}

body > * {
  display: grid;
  grid-template-columns: subgrid;
}

أخيرًا، يمكن للأطفال في عمر <nav> أو <main> عامًا محاذاة أنفسهم أو تحديد حجمهم باستخدام الأعمدة والخطوط fullbleed وmain.

.main-content {
  grid-column: main;
}

.fullbleed {
  grid-column: fullbleed;
}

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

لقطة شاشة لعرض توضيحي لشبكة فرعية، باستخدام أدوات تراكب الشبكة في Chrome DevTools لعرض الخطوط المحدّدة بواسطة CSS

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

لقطة شاشة للوحة &quot;العناصر&quot; في Chrome DevTools توضّح العناصر التي تتضمّن تنسيقات شبكة أو شبكة فرعية
لقطة شاشة من "أدوات مطوّري Firefox"

الموارد

طلبات الحاويات

Browser Support

  • Chrome: 105.
  • Edge: 105.
  • Firefox: 110.
  • Safari: 16.

Source

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

بعد @container، يمكن للعناصر الاستجابة لحجم الحاوية الرئيسية أو نمطها. الشرط الوحيد هو أن تعرّف الحاويات نفسها على أنّها أهداف محتملة لطلبات البحث، وهذا شرط بسيط مقابل فائدة كبيرة.

/* establish a container */
.day {
  container-type: inline-size;
  container-name: calendar-day;
}

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

عرض توضيحي من Una Kravets

إليك رمز CSS للاستعلام عن حجم الحاوية calendar-day، ثم تعديل التنسيق وأحجام الخطوط:

@container calendar-day (max-width: 200px) {
  .date {
    display: block;
  }

  .date-num {
    font-size: 2.5rem;
    display: block;
  }
}

في ما يلي مثال آخر: يتكيّف أحد مكونات الكتاب مع المساحة المتاحة في العمود الذي يتم سحبه إليه:

العرض التوضيحي من ماكس بوك

تصدق "أونا" في تقييمها للوضع على أنّه التصميم الجديد المتجاوب. هناك العديد من قرارات التصميم الرائعة والمهمة التي يجب اتخاذها عند استخدام @container.

الموارد

accent-color

Browser Support

  • Chrome: 93.
  • Edge: 93.
  • Firefox: 92.
  • Safari: 15.4.

Source

قبل الإصدار accent-color، عندما كنت تريد نموذجًا بألوان متطابقة مع العلامة التجارية، كان بإمكانك استخدام مكتبات معقّدة أو حلول CSS يصعب إدارتها بمرور الوقت. على الرغم من أنّهم قدّموا لك جميع الخيارات، ونأمل أن يكونوا قد أدرجوا خيار تسهيل الاستخدام، يصبح اختيار استخدام المكوّنات المضمّنة أو اعتماد مكوّناتك الخاصة أمرًا مملًا.

بعد accent-color، يضيف سطر واحد من CSS لونًا خاصًا بالعلامة التجارية إلى المكوّنات المضمّنة. بالإضافة إلى درجة اللون، يختار المتصفّح بذكاء ألوانًا مناسبة ومتباينة للأجزاء الثانوية من المكوّن ويتكيّف مع أنظمة الألوان (الفاتحة أو الداكنة).

/* tint everything */
:root {
  accent-color: hotpink;
}

/* tint one element */
progress {
  accent-color: indigo;
}

عناصر HTML مميّزة باللونين الفاتح والداكن جنبًا إلى جنب للمقارنة

لمزيد من المعلومات حول accent-color، يمكنك الاطّلاع على مشاركتي على web.dev حيث أستكشف العديد من الجوانب الأخرى لهذه السمة المفيدة في CSS.

الموارد

مستوى اللون 4 و5

لقد كان تنسيق sRGB هو السائد على الويب خلال العقود الماضية، ولكن مع التوسّع في استخدام شاشات العرض الرقمية عالية الدقة والأجهزة الجوّالة المزوّدة بشاشات OLED أو QLED، لم يعُد تنسيق sRGB كافيًا. بالإضافة إلى ذلك، من المتوقّع أن تكون الصفحات ديناميكية وتتكيّف مع خيارات المستخدمين المفضّلة، كما أنّ إدارة الألوان أصبحت مصدر قلق متزايد للمصمّمين وأنظمة التصميم والقائمين على صيانة الرموز البرمجية.

ولكن في عام 2022، أضافت CSS عددًا من دوال الألوان والمساحات الجديدة: - ألوان تستفيد من إمكانات الألوان العالية الدقة في الشاشات. - مساحات الألوان التي تتطابق مع هدف معيّن، مثل التوحيد الإدراكي - مساحات الألوان للتدرجات التي تغيّر نتائج الاستيفاء بشكل كبير - وظائف الألوان التي تساعدك في المزج والمقارنة واختيار مساحة العمل التي تريد استخدامها

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

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

@media (dynamic-range: high) {
  .neon-pink {
    --neon-glow: color(display-p3 1 0 1);
  }
}

@supports (color: lab(0% 0 0)) {
  .neon-pink {
    --neon-glow: lab(150% 160 0);
  }
}

hwb()

Browser Support

  • Chrome: 101.
  • Edge: 101.
  • Firefox: 96.
  • Safari: 15.

Source

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

يؤدي استخدام دالة الألوان هذه إلى عرض ألوان من مساحة الألوان sRGB، وهي المساحة نفسها التي تستخدمها نماذج HSL وRGB. في ما يتعلق بالميزات الجديدة لعام 2022، لا يوفّر لك هذا التنسيق ألوانًا جديدة، ولكنّه قد يسهّل بعض المهام على محبّي هذا التنسيق والنموذج الذهني.

الموارد

مساحات الألوان

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

من المفترض أن يوفّر CSS في عام 2022 عشر مساحات ألوان جديدة، لكل منها ميزات فريدة لمساعدة المصمّمين والمطوّرين في عرض الألوان واختيارها ودمجها. في السابق، كان sRGB هو الخيار الوحيد للتعامل مع الألوان، ولكن يتيح CSS الآن إمكانات جديدة ومساحة ألوان تلقائية جديدة، وهي LCH.

color-mix()

Browser Support

  • Chrome: 111.
  • Edge: 111.
  • Firefox: 113.
  • Safari: 16.2.

Source

قبل color-mix()، كان المطوّرون والمصمّمون بحاجة إلى معالجات مسبقة مثل Sass لدمج الألوان قبل أن يراها المتصفّح. لم تكن معظم دوال مزج الألوان توفّر خيار تحديد مساحة الألوان التي سيتم المزج فيها، ما كان يؤدي أحيانًا إلى نتائج مربكة.

بعد color-mix()، يمكن للمطوّرين والمصمّمين مزج الألوان في المتصفّح، إلى جانب جميع الأنماط الأخرى، بدون تنفيذ عمليات الإنشاء أو تضمين JavaScript. بالإضافة إلى ذلك، يمكنهم تحديد مساحة اللون التي سيتم فيها المزج، أو استخدام مساحة اللون التلقائية للمزج وهي LCH.

في كثير من الأحيان، يتم استخدام لون العلامة التجارية كأساس ويتم إنشاء أشكال مختلفة منه، مثل ألوان أفتح أو أغمق لأنماط التمرير. إليك الشكل الذي سيبدو عليه مع color-mix():

.color-mix-example {
  --brand: #0af;

  --darker: color-mix(var(--brand) 25%, black);
  --lighter: color-mix(var(--brand) 25%, white);
}

وإذا أردت مزج هذه الألوان في مساحة ألوان مختلفة، مثل srgb، يمكنك تغييرها:

.color-mix-example {
  --brand: #0af;

  --darker: color-mix(in srgb, var(--brand) 25%, black);
  --lighter: color-mix(in srgb, var(--brand) 25%, white);
}

في ما يلي عرض توضيحي لتطبيق سمة باستخدام color-mix(). حاوِل تغيير لون العلامة التجارية وشاهِد عملية تعديل المظهر:

نتطلّع إلى أن تستمتع بمزج الألوان في مساحات ألوان مختلفة في أوراق الأنماط خلال عام 2022.

الموارد

color-contrast()

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

لقطة شاشة لثلاث لوحات ألوان Material تعرض 14 لونًا وألوان التباين المناسبة باللون الأبيض أو الأسود للنص
مثال من لوحات ألوان التصميم المتعدّد الأبعاد لعام 2014

بعد color-contrast()، يمكن لمؤلفي أوراق الأنماط نقل المهمة بالكامل إلى المتصفّح. لا يقتصر الأمر على إمكانية استخدام المتصفّح لاختيار لون أسود أو أبيض تلقائيًا، بل يمكنك أيضًا تزويده بقائمة من الألوان المناسبة لنظام التصميم، وسيتولّى اختيار اللون الأول الذي يستوفي نسبة التباين المطلوبة.

في ما يلي لقطة شاشة لعرض مجموعة لوحة ألوان HWB حيث يختار المتصفّح ألوان النص تلقائيًا استنادًا إلى لون العيّنة:

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

تبدو أساسيات بناء الجملة على النحو التالي، حيث يتم تمرير اللون الرمادي إلى الدالة ويحدّد المتصفّح ما إذا كان اللون الأسود أو الأبيض يحقّق أعلى تباين:

color: color-contrast(gray);

يمكن أيضًا تخصيص الدالة باستخدام قائمة بالألوان، والتي سيتم من خلالها اختيار اللون الأكثر تباينًا من بين الألوان المحددة:

color: color-contrast(gray vs indigo, rebeccapurple, hotpink);

أخيرًا، في حال كان من الأفضل عدم اختيار اللون الأعلى تباينًا من القائمة، يمكن تقديم نسبة تباين مستهدَفة، وسيتم اختيار اللون الأول الذي يستوفيها:

color: color-contrast(
  var(--bg-blue-1)
  vs
  var(--text-lightest), var(--text-light), var(--text-subdued)
  to AA /* 4.5 could also be passed */
);

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

الموارد

بنية الألوان النسبية

Browser Support

  • Chrome: 111.
  • Edge: 111.
  • Firefox: 113.
  • Safari: 15.

Source

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

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

في مثال الصيغة التالي، يتم توفير قيمة أساسية بنظام الأرقام الست عشرية ويتم إنشاء لونين جديدين بالنسبة إليها. ينشئ اللون الأول --absolute-change لونًا جديدًا في LCH من اللون الأساسي، ثم يستبدل درجة سطوع اللون الأساسي بالقيمة 75%، مع الحفاظ على درجة اللون (c) ودرجة الصبغة (h). ينشئ اللون الثاني --relative-change لونًا جديدًا في LCH من اللون الأساسي، ولكن هذه المرة يتم تقليل درجة اللون (c) بنسبة %20.

.relative-color-syntax {
  --color: #0af;
  --absolute-change: lch(from var(--color) 75% c h);
  --relative-change: lch(from var(--color) l calc(c-20%) h);
}

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

في العرض التوضيحي التالي، استخدمتُ بنية الألوان النسبية لإنشاء أشكال أفتح وأغمق من لون أساسي، واستخدمتُ color-contrast() لضمان توفّر التباين المناسب في التصنيفات:

لقطة شاشة تحتوي على 3 أعمدة، كل عمود أغمق أو أفتح من العمود الأوسط
تجربة العرض التوضيحي

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

:root {
  --_color-base: #339af0;

  --color-0:  lch(from var(--_color-base) 98% 10 h);
  --color-1:  lch(from var(--_color-base) 93% 20 h);
  --color-2:  lch(from var(--_color-base) 85% 40 h);
  --color-3:  lch(from var(--_color-base) 75% 46 h);
  --color-4:  lch(from var(--_color-base) 66% 51 h);
  --color-5:  lch(from var(--_color-base) 61% 52 h);
  --color-6:  lch(from var(--_color-base) 55% 57 h);
  --color-7:  lch(from var(--_color-base) 49% 58 h);
  --color-8:  lch(from var(--_color-base) 43% 55 h);
  --color-9:  lch(from var(--_color-base) 39% 52 h);
  --color-10: lch(from var(--_color-base) 32% 48 h);
  --color-11: lch(from var(--_color-base) 25% 45 h);
  --color-12: lch(from var(--_color-base) 17% 40 h);
  --color-13: lch(from var(--_color-base) 10% 30 h);
  --color-14: lch(from var(--_color-base) 5% 20 h);
  --color-15: lch(from var(--_color-base) 1% 5 h);
}
لقطة شاشة تضم 15 لوحة ألوان تم إنشاؤها ديناميكيًا باستخدام CSS
جرِّب العرض التوضيحي

نأمل أن تكون قد أدركت الآن كيف يمكن استخدام مساحات الألوان ووظائف الألوان المختلفة لأغراض مختلفة، استنادًا إلى نقاط قوتها وضعفها.

الموارد

مساحات الألوان المتدرّجة

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

4 تدرّجات في شبكة، وكلها من اللون السماوي إلى اللون الوردي الداكن تتسم مساحتا الألوان LCH وLAB بمستوى سطوع أكثر اتساقًا، بينما تنخفض درجة تشبّع الألوان في مساحة sRGB قليلاً في المنتصف.

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

تتم إضافة البنية بعد اتجاه التدرّج، وتستخدم البنية الجديدة in، وهي اختيارية:

background-image: linear-gradient(
  to right in hsl,
  black, white
);

background-image: linear-gradient(
  to right in lch,
  black, white
);

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

‫11 مساحة ألوان معروضة تقارن بين الأسود والأبيض

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

يتم عرض 11 مساحة ألوان تقارن بين اللون الأزرق والأسود.

لمزيد من الاستكشافات المتعمّقة والأمثلة والتعليقات، يمكنك قراءة سلسلة المحادثات هذه على Twitter.

الموارد

inert

Browser Support

  • Chrome: 102.
  • Edge: 102.
  • Firefox: 112.
  • Safari: 15.5.

Source

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

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

من الأمثلة الجيدة على ذلك الدالة alert() في JavaScript:

يتم عرض الموقع الإلكتروني على أنّه تفاعلي، ثم يتم استدعاء alert()، وتتوقف الصفحة عن النشاط.

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

في ما يلي نموذج رمز برمجي صغير يوضّح طريقة عملها:

<body>
  <div class="modal">
    <h2>Modal Title</h2>
    <p>...<p>
    <button>Save</button>
    <button>Discard</button>
  </div>
  <main inert>
    <!-- cannot be keyboard focused or clicked -->
  </main>
</body>

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

الموارد

خطوط COLRv1

قبل خطوط COLRv1، كانت هناك خطوط OT-SVG على الويب، وهي أيضًا تنسيق مفتوح للخطوط يتضمّن تدرّجات وألوانًا وتأثيرات مدمجة. ومع ذلك، يمكن أن تصبح هذه البطاقات كبيرة جدًا، وعلى الرغم من أنّها كانت تتيح تعديل النص، لم يكن هناك مجال كبير للتخصيص.

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

تصوّر مقارنة ورسم بياني شريطي يوضّحان أنّ خطوط COLRv1 أكثر حدة وأصغر حجمًا
تم الحصول على الصورة من https://developer.chrome.com/blog/colrv1-fonts/

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

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

@import url(https://fonts.googleapis.com/css2?family=Bungee+Spice);

يتم تخصيص خط COLRv1 باستخدام @font-palette-values، وهي قاعدة CSS خاصة at-rule لتجميع مجموعة من خيارات التخصيص وتسميتها في حزمة يمكن الرجوع إليها لاحقًا. لاحظ كيف تحدّد اسمًا مخصّصًا تمامًا مثل السمة المخصّصة، بدءًا من --:

@import url(https://fonts.googleapis.com/css2?family=Bungee+Spice);

@font-palette-values --colorized {
  font-family: "Bungee Spice";
  base-palette: 0;
  override-colors: 0 hotpink, 1 cyan, 2 white;
}

باستخدام --colorized كاسم مستعار للتخصيصات، الخطوة الأخيرة هي تطبيق لوحة الألوان على عنصر يستخدم عائلة خطوط الألوان:

@import url(https://fonts.googleapis.com/css2?family=Bungee+Spice);

@font-palette-values --colorized {
  font-family: "Bungee Spice";
  base-palette: 0;
  override-colors: 0 hotpink, 1 cyan, 2 white;
}

.spicy {
  font-family: "Bungee Spice";
  font-palette: --colorized;
}
لقطة شاشة لخط Bungee Spice مع الكلمة DUNE
خط Bungee Spice مع ألوان مخصّصة، المصدر: https://developer.chrome.com/blog/colrv1-fonts/

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

الموارد

وحدات إطار العرض

رسم توضيحي يبيّن كيف أنّ شاشة الجهاز ونافذة المتصفّح وإطار iframe كلها تحتوي على منافذ عرض مختلفة

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

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

.original-viewport-units {
  height: 100vh;
  width: 100vw;
  --size: 100vmin;
  --size: 100vmax;
}

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

رسم يتضمّن ثلاثة هواتف للمساعدة في توضيح DVH وLVH وSVH يحتوي الهاتف المعروض في مثال DVH
   على خطَّين عموديَّين، أحدهما بين أسفل شريط البحث
   وأسفل نافذة العرض، والآخر بين أعلى شريط البحث (أسفل
   شريط حالة النظام) وأسفل نافذة العرض، ما يوضّح كيف يمكن أن يكون طول DVH أحد هذين الطولَين. يظهر LVH في المنتصف مع سطر واحد بين أسفل شريط حالة الجهاز وزر منفذ عرض الهاتف. آخرها هو مثال وحدة SVH، حيث يعرض خطًا من أسفل شريط بحث المتصفح إلى أسفل إطار العرض

في ما يلي قائمة كاملة بجميع خيارات وحدات عرض الإعلانات الجديدة التي أصبحت متاحة مع صيغ وحدات عرض الإعلانات الجديدة:

وحدات ارتفاع إطار العرض
​​.new-height-viewport-units {
  height: 100vh;
  height: 100dvh;
  height: 100svh;
  height: 100lvh;
  block-size: 100vb;
  block-size: 100dvb;
  block-size: 100svb;
  block-size: 100lvb;
}
وحدات عرض إطار العرض
.new-width-viewport-units {
  width: 100vw;
  width: 100dvw;
  width: 100svw;
  width: 100lvw;
  inline-size: 100vi;
  inline-size: 100dvi;
  inline-size: 100svi;
  inline-size: 100lvi;
}
أصغر وحدات جانبية لإطار العرض
.new-min-viewport-units {
  --size: 100vmin;
  --size: 100dvmin;
  --size: 100svmin;
  --size: 100lvmin;
}
أكبر وحدات جانبية في إطار العرض
.new-max-viewport-units {
  --size: 100vmax;
  --size: 100dvmax;
  --size: 100svmax;
  --size: 100lvmax;
}

نأمل أن تمنح هذه الميزات المطوّرين والمصمّمين المرونة اللازمة لتحقيق تصميمات سريعة الاستجابة في إطار العرض.

الموارد

:has()

Browser Support

  • Chrome: 105.
  • Edge: 105.
  • Firefox: 121.
  • Safari: 15.4.

Source

قبل :has()، كان موضوع أداة الاختيار يظهر دائمًا في النهاية. على سبيل المثال، موضوع أداة الاختيار هذه هو عنصر قائمة: ul > li. يمكن أن تغيّر أدوات الاختيار الزائفة أداة الاختيار، ولكنّها لا تغيّر الموضوع: ul > li:hover أو ul > li:not(.selected).

بعد :has()، يمكن أن يبقى موضوع أعلى في شجرة العناصر هو الموضوع مع تقديم طلب بحث عن العناصر الثانوية: ul:has(> li). من السهل فهم سبب تسمية :has() بـ "أداة اختيار العنصر الأصل"، لأنّ موضوع أداة الاختيار هو العنصر الأصل في هذه الحالة.

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

.parent:has(.child) {...}

في ما يلي مثال على عنصر <section> يمثّل الموضوع، ولكن لا يتطابق المحدد إلا إذا كان أحد العناصر الثانوية يتضمّن :focus-visible:

section:has(*:focus-visible) {...}

تبدأ أداة الاختيار :has() في أن تصبح أداة رائعة مرة أخرى عندما تصبح حالات الاستخدام الأكثر عملية واضحة. على سبيل المثال، لا يمكن حاليًا اختيار علامات <a> عندما تكون الصور مضمّنة فيها، ما يصعّب تعليم علامة الرابط كيفية تغيير أنماطها في حالة الاستخدام هذه. يمكن إجراء ذلك باستخدام :has() باتّباع الخطوات التالية:

a:has(> img) {...}

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

figure:has(figcaption) img {...}

والمجموعات المحتملة لا حصر لها على ما يبدو. يمكنك الجمع بين :has() وطلبات البحث quantity queries وتعديل تخطيطات شبكة CSS استنادًا إلى عدد العناصر الفرعية. يمكنك الجمع بين :has() وحالات فئة псевдо التفاعلية وإنشاء تطبيقات تستجيب بطرق إبداعية جديدة.

يمكنك التحقّق من التوافق بسهولة باستخدام الدالتَين @supports و selector()، اللتين تختبران ما إذا كان المتصفّح يفهم بنية الجملة قبل استخدامها:

@supports (selector(:has(works))) {
  /* safe to use :has() */
}

الموارد

‫2022 وما بعده

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

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

الخصائص المخصّصة ذات الأنواع غير المحدّدة

Browser Support

  • Chrome: 85.
  • Edge: 85.
  • Firefox: 128.
  • Safari: 16.4.

Source

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

لنفترض سيناريو يستخدم فيه box-shadow سمات مخصّصة لقيمه:

box-shadow: var(--x) var(--y) var(--blur) var(--spread) var(--color);

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

هنا يأتي دور @property: يمكن أن يصبح --x سمة مخصّصة ذات نوع، أي لم يعُد مرنًا وغير محدد، بل أصبح آمنًا مع بعض الحدود المحدّدة:

@property --x {
  syntax: '<length>';
  initial-value: 0px;
  inherits: false;
}

الآن، عندما يستخدم box-shadow var(--x) ثم تتم محاولة استخدام --x: red، سيتم تجاهل red لأنّه ليس <length>. وهذا يعني أنّ الظل يواصل العمل، حتى إذا تم تقديم قيمة غير صالحة لإحدى خصائصه المخصّصة. بدلاً من أن يتعذّر، يعود إلى initial-value من 0px.

Animation

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

اطّلِع على مثال العرض التوضيحي هذا، حيث يتم استخدام تدرّج شعاعي لإنشاء جزء من تراكب، ما يؤدي إلى إنشاء تأثير تركيز على بقعة ضوء. يضبط JavaScript موضعَي الماوس x وy عند الضغط على المفتاح Alt/Opt، ثم يغيّر حجم التركيز إلى قيمة أصغر مثل %25، ما يؤدي إلى إنشاء دائرة التركيز في موضع الماوس:

جرِّب العرض التوضيحي
.focus-effect {
  --focal-size: 100%;
  --mouse-x: center;
  --mouse-y: center;

  mask-image: radial-gradient(
    circle at var(--mouse-x) var(--mouse-y),
    transparent 0%,
    transparent var(--focal-size),
    black 0%
  );
}

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

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

@property --focal-size {
  syntax: '<length-percentage>';
  initial-value: 100%;
  inherits: false;
}

.focus-effect {
  --focal-size: 100%;
  --mouse-x: center;
  --mouse-y: center;

  mask-image: radial-gradient(
    circle at var(--mouse-x) var(--mouse-y),
    transparent 0%,
    transparent var(--focal-size),
    black 0%
  );

  transition: --focal-size .3s ease;
}
جرِّب العرض التوضيحي

أصبح بإمكان المتصفّح الآن تحريك حجم التدرّج اللوني لأنّنا قلّلنا مساحة التعديل لتشمل سمة واحدة فقط، وحدّدنا نوع القيمة ليتمكّن المتصفّح من استيفاء الأطوال بذكاء.

يمكن أن يقدّم @property الكثير من المساعدة، ولكن هذه الإمكانات الصغيرة يمكن أن تكون مفيدة جدًا.

الموارد

زيارة min-width أو max-width

قبل نطاقات طلبات البحث عن الوسائط، كان طلب البحث عن الوسائط في CSS يستخدم min-width وmax-width لتحديد الشروط التي تزيد عن قيمة معيّنة أو تقلّ عنها. قد يبدو على النحو التالي:

@media (min-width: 320px) {
  
}

بعد نطاقات طلبات البحث عن الوسائط، يمكن أن يبدو طلب البحث نفسه عن الوسائط على النحو التالي:

@media (width >= 320px) {
  
}

قد يبدو طلب البحث عن الوسائط في CSS الذي يستخدم min-width وmax-width على النحو التالي:

@media (min-width: 320px) and (max-width: 1280px) {
  
}

بعد نطاقات طلبات البحث عن الوسائط، يمكن أن يبدو طلب البحث نفسه عن الوسائط على النحو التالي:

@media (320px <= width <= 1280px) {
  
}

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

الموارد

ما مِن متغيرات لاستعلامات الوسائط

قبل @custom-media، كان يجب تكرار طلبات البحث عن الوسائط مرارًا وتكرارًا، أو الاعتماد على المعالجات المسبقة لإنشاء الناتج المناسب استنادًا إلى متغيرات ثابتة أثناء وقت الإنشاء.

بعد @custom-media، تسمح CSS بتعريف أسماء مستعارة لاستعلامات الوسائط والإشارة إليها، تمامًا مثل الموقع المخصّص.

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

@custom-media --OSdark  (prefers-color-scheme: dark);
@custom-media --OSlight (prefers-color-scheme: light);

@custom-media --pointer (hover) and (pointer: coarse);
@custom-media --mouse   (hover) and (pointer: fine);

@custom-media --xxs-and-above (width >= 240px);
@custom-media --xxs-and-below (width <= 240px);

بعد تحديدها، يمكنني استخدام إحداها على النحو التالي:

@media (--OSdark) {
  :root {
    
  }
}

يمكنك الاطّلاع على قائمة كاملة بطلبات البحث المخصّصة عن الوسائط التي أستخدمها داخل مكتبة الخصائص المخصّصة لـ CSS Open Props.

الموارد

تداخل أدوات الاختيار أمرٌ رائع

قبل @nest، كان هناك الكثير من التكرار في أوراق الأنماط. وأصبح الأمر صعبًا بشكل خاص عندما كانت المحدّدات طويلة وكان كل منها يستهدف اختلافات صغيرة. تُعد سهولة التداخل من الأسباب الأكثر شيوعًا لاستخدام معالج مسبق.

بعد @nest، لن يتم تكرار الإعلان. سيتم توفير كل ميزة تقريبًا من ميزات التداخل المتوافق مع المعالج المسبق في CSS.

article {
  color: darkgray;
}

article > a {
  color: var(--link-color);
}

/* with @nest becomes */

article {
  color: darkgray;

  & > a {
    color: var(--link-color);
  }
}

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

ويمكن أيضًا اعتبار الملكية بمثابة مركزية. بدلاً من البحث في ورقة أنماط عن الأنماط ذات الصلة، يمكن العثور عليها جميعًا مضمّنة معًا ضمن سياق. ويعمل ذلك مع علاقات الوالدَين بالأطفال، وكذلك مع علاقات الأطفال بالوالدَين.

لنفترض أنّ هناك عنصرًا فرعيًا يريد تعديل نفسه عندما يكون في سياق عنصر رئيسي مختلف، بدلاً من أن يمتلك العنصر الرئيسي النمط ويغيّر العنصر الفرعي:

/* parent owns this, adjusting children */
section:focus-within > article {
  border: 1px solid hotpink;
}

/* with @nest becomes */

/* article owns this, adjusting itself when inside a section:focus-within */
article {
  @nest section:focus-within > & {
     border: 1px solid hotpink;
  }
}

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

الموارد

يصعب جدًا تحديد نطاق الأنماط

Browser Support

  • Chrome: 118.
  • Edge: 118.
  • Firefox: behind a flag.
  • Safari: 17.4.

Source

قبل @scope، كانت هناك العديد من الاستراتيجيات لأنّ الأنماط في CSS تتتالى وتتوارث، ويتم تحديد نطاقها على مستوى العالم تلقائيًا. تُعدّ هذه الميزات في CSS مفيدة جدًا في العديد من الحالات، ولكن بالنسبة إلى المواقع الإلكترونية والتطبيقات المعقّدة التي قد تتضمّن العديد من الأنماط المختلفة للمكوّنات، يمكن أن يؤدي المساحة العامة وطبيعة التتالي إلى ظهور الأنماط وكأنّها تتسرّب.

بعد @scope، لن يقتصر نطاق الأنماط على سياق معيّن، مثل فئة، بل يمكن أيضًا تحديد موضع انتهاء الأنماط وعدم استمرارها في التتالي أو الوراثة.

في المثال التالي، يمكن عكس نطاق اصطلاح التسمية BEM إلى الغرض الفعلي. يحاول أداة اختيار BEM تحديد نطاق لون العنصر header ضمن الحاوية .card باستخدام اصطلاحات التسمية. ويتطلّب ذلك أن يحتوي العنوان على اسم الفئة هذا، ما يؤدي إلى إكمال الهدف. باستخدام @scope، لا تكون هناك حاجة إلى اصطلاحات تسمية لإكمال الهدف نفسه بدون ترميز عنصر العنوان:

.card__header {
  color: var(--text);
}

/* with @scope becomes */

@scope (.card) {
  header {
    color: var(--text);
  }
}

في ما يلي مثال آخر أقل تحديدًا للمكوّن وأكثر تركيزًا على طبيعة النطاق العام لملفات CSS. يجب أن يتواجد المظهران الداكن والفاتح معًا في ورقة أنماط، حيث يكون الترتيب مهمًا في تحديد النمط الفائز. يعني هذا عادةً أنّ أنماط المظهر الداكن تأتي بعد المظهر الفاتح، ما يتيح ضبط المظهر الفاتح كإعداد تلقائي والمظهر الداكن كنمط اختياري. تجنَّب ترتيب العناصر وتحديد نطاقها باستخدام @scope:

​​@scope (.light-theme) {
  a { color: purple; }
}

@scope (.dark-theme) {
  a { color: plum; }
}

لإكمال القصة هنا، يسمح @scope أيضًا بتحديد موضع انتهاء نطاق النمط. لا يمكن تنفيذ ذلك باستخدام أي اصطلاح تسمية أو معالج أولي، بل هو أمر خاص يمكن تنفيذه فقط باستخدام CSS المضمّنة في المتصفّح. في المثال التالي، يتم تطبيق النمطين img و.content حصريًا عندما يكون العنصر الفرعي من .media-block عنصرًا شقيقًا أو عنصرًا رئيسيًا لـ .content:

@scope (.media-block) to (.content) {
  img {
    border-radius: 50%;
  }

  .content {
    padding: 1em;
  }
}

الموارد

لا توجد طريقة CSS لتصميم تخطيط البناء

قبل توفّر CSS masonry مع الشبكة، كانت JavaScript أفضل طريقة لتحقيق تصميم بنمط البناء الحر، لأنّ أيًا من طرق CSS التي تستخدم الأعمدة أو مربّعات العرض المرنة كانت ستعرض ترتيب المحتوى بشكل غير دقيق.

بعد استخدام CSS masonry مع الشبكة، لن تكون هناك حاجة إلى مكتبات JavaScript، وسيكون ترتيب المحتوى صحيحًا.

لقطة شاشة لتصميم البناء الذي يعرض أرقامًا تنتقل على طول الجزء العلوي، ثم تنزل إلى الأسفل
صورة وعرض توضيحي من Smashing Magazine
https://www.smashingmagazine.com/native-css-masonry-layout-css-grid/

يمكن تحقيق العرض التوضيحي السابق باستخدام CSS التالي:

.container {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: masonry;
}

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

الموارد

لا يمكن أن تساعد صفحات الأنماط المتتالية (CSS) المستخدمين في تقليل البيانات

Browser Support

  • Chrome: behind a flag.
  • Edge: behind a flag.
  • Firefox: not supported.
  • Safari: not supported.

Source

قبل طلب البحث عن الوسائط prefers-reduced-data، كان بإمكان JavaScript والخادم تغيير سلوكهما استنادًا إلى نظام التشغيل أو خيار "توفير البيانات" في المتصفّح لدى المستخدم، ولكن لم يكن بإمكان CSS إجراء ذلك.

بعد طلب البحث عن الوسائط prefers-reduced-data، يمكن أن ينضم CSS إلى تحسين تجربة المستخدم ويؤدي دوره في حفظ البيانات.

@media (prefers-reduced-data: reduce) {
  picture, video {
    display: none;
  }
}

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

لقطة شاشة لواجهة لوحة عرض دوّارة لبرنامج تلفزيوني تعرض العديد من الصور المصغّرة والعناوين.

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

لقطة شاشة لواجهة لوحة عرض دوّارة لبرنامج تلفزيوني بدون صور مصغّرة وعرض العديد من العناوين

تتضمّن تجربة البيانات المخفَّضة مزايا أخرى غير توفير البيانات. يمكن رؤية المزيد من العناوين، ولا توجد صور غلاف مشتّتة للانتباه. يستخدم العديد من المستخدمين وضع توفير البيانات لأنّهم يدفعون مقابل كل ميغابايت من البيانات، لذا من الرائع أن نرى أنّ CSS يمكن أن يساعد في هذا الصدد.

الموارد

ميزات "المحاذاة عند التمرير" محدودة جدًا

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

واجهات برمجة تطبيقات جديدة

snapChanging()

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

document.querySelector('.snap-carousel').addEventListener('snapchanging', event => {
  console.log('Snap is changing', event.snappedTargetsList);
});
snapChanged()

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

document.querySelector('.snap-carousel').addEventListener('snapchanged', event => {
  console.log('Snap changed', event.snappedTargetsList);
});
scroll-start

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

:root { --nav-height: 100px }

.snap-scroll-y {
  scroll-start-y: var(--nav-height);
}
:snap-target

ستطابق أداة اختيار CSS هذه العناصر في حاوية محاذاة التمرير السريع التي تتم محاذاتها حاليًا بواسطة المتصفح.

.card {
  --shadow-distance: 5px;
  box-shadow: 0 var(--shadow-distance) 5px hsl(0 0% 0% / 25%);
  transition: box-shadow 350ms ease;
}

.card:snapped {
  --shadow-distance: 30px;
}

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

لا تزال هذه الميزات في مراحلها الأولى، ولكن ننصحك بالبحث عن polyfills التي يمكن أن تساعد في استخدامها واختبارها قريبًا.

الموارد

التنقّل بين الحالات المعروفة

قبل toggle()، كان يمكن الاستفادة فقط من الحالات المضمّنة في المتصفّح للتصميم والتفاعل. يحتوي عنصر إدخال مربّع الاختيار، مثلاً، على :checked، وهي حالة متصفّح تتم إدارتها داخليًا لعنصر الإدخال ويمكن أن تستخدمها CSS لتغيير العنصر بصريًا.

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

في المثال التالي، يتم تحقيق التأثير نفسه الخاص بتشطيب عنصر قائمة عند اكتماله، ولكن بدون أي عناصر مربّع اختيار:

<ul class='ingredients'>
   <li>1 banana
   <li>1 cup blueberries
  ...
</ul>

وأنماط CSS toggle() ذات الصلة:

li {
  toggle-root: check self;
}

li:toggle(check) {
  text-decoration: line-through;
}

إذا كنت معتادًا على استخدام آلات الحالة، قد تلاحظ التشابه الكبير بينها وبين toggle(). ستتيح هذه الميزة للمطوّرين إنشاء المزيد من حالاتهم في CSS، ما سيؤدي إلى طرق أكثر وضوحًا ودلالة لتنظيم التفاعل والحالة.

الموارد

تخصيص عناصر الاختيار

قبل <selectmenu>، لم تكن لغة CSS تتيح تخصيص عناصر <option> باستخدام HTML المنسّق أو تغيير الكثير بشأن طريقة عرض قائمة الخيارات. وقد دفع ذلك المطوّرين إلى تحميل مكتبات خارجية تعيد إنشاء الكثير من وظائف <select>، وهو ما تطلّب الكثير من الجهد.

بعد <selectmenu>، يمكن للمطوّرين توفير HTML غني لعناصر الخيارات وتنسيقها حسب الحاجة، مع استيفاء متطلبات تسهيل الاستخدام وتوفير HTML دلالي.

في المثال التالي، المأخوذ من <selectmenu>صفحة الشرح، يتم إنشاء قائمة اختيار جديدة تتضمّن بعض الخيارات الأساسية:

<selectmenu>
  <option>Option 1</option>
  <option>Option 2</option>
  <option>Option 3</option>
</selectmenu>

يمكن أن تستهدف CSS أجزاء العنصر وتصمّمها:

.my-select-menu::part(button) {
  color: white;
  background-color: red;
  padding: 5px;
  border-radius: 5px;
}

.my-select-menu::part(listbox) {
  padding: 10px;
  margin-top: 5px;
  border: 1px solid red;
  border-radius: 5px;
}

قائمة أنيقة ذات ألوان حمراء بارزة

يمكنك تجربة عنصر <selectmenu> على Chromium في Canary مع تفعيل العلامة web experiments. ترقَّب في عام 2023 وما بعده عناصر قائمة قابلة للتخصيص.

الموارد

تثبيت عنصر بعنصر آخر

قبل anchor()، كان الموضع المطلق والموضع النسبي من استراتيجيات المواضع التي تم توفيرها للمطوّرين كي يتمكّنوا من تحريك العناصر الثانوية داخل عنصر رئيسي.

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

يتضمّن الشرح بعض الأمثلة الرائعة وعيّنات الرموز البرمجية، إذا كنت مهتمًا بمعرفة المزيد.

الموارد