ميزات تصميم الويب الحالية والمستقبلية، كما تم عرضها في مؤتمر Google IO 2022، بالإضافة إلى بعض الميزات الإضافية
من المتوقّع أن يكون عام 2022 من أفضل الأعوام بالنسبة إلى CSS، سواء من حيث الميزات أو إصدارات ميزات المتصفّح التعاونية، وذلك بهدف تعاوني يتمثّل في تنفيذ 14 ميزة.
نظرة عامة
هذا المنشور هو نسخة مكتوبة من المحاضرة التي تم تقديمها في مؤتمر Google IO 2022. لا يهدف هذا الدليل إلى تقديم شرح تفصيلي لكل ميزة، بل يقدّم مقدمة ونظرة عامة موجزة لإثارة اهتمامك، مع التركيز على التنوّع بدلاً من التفصيل. إذا أثارت هذه المعلومات اهتمامك، يمكنك الاطّلاع على روابط المراجع في نهاية كل قسم للحصول على مزيد من المعلومات.
جدول المحتويات
استخدِم القائمة أدناه للانتقال إلى المواضيع التي تهمّك:
توافُق المتصفح
أحد الأسباب الرئيسية التي أدّت إلى إطلاق العديد من ميزات CSS بشكل تعاوني هو الجهود التي بذلتها Interop 2022. قبل دراسة جهود Interop، من المهم إلقاء نظرة على جهود Compat 2021.
Compat 2021
كانت أهداف عام 2021، المستندة إلى ملاحظات المطوّرين من خلال الاستطلاعات، هي تثبيت الميزات الحالية وتحسين مجموعة الاختبارات وزيادة نتائج النجاح للمتصفحات في خمس ميزات:
stickyتحديد موضع الإعلانaspect-ratioتحديد المقاس- التنسيق
flex - التنسيق
grid transformتحديد الموضع والصورة المتحركة
وقد ارتفعت نتائج الاختبارات على جميع المستويات، ما يدل على تحسُّن الثبات والموثوقية. تهانينا الحارّة للفِرق المشاركة!
Interop 2022
في هذا العام، اجتمعت فِرق المتصفحات لمناقشة الميزات والأولويات التي ستعمل عليها، وتوحيد جهودها. وقد خطّطوا لتوفير ميزات الويب التالية للمطوّرين:
@layer- مساحات الألوان والدوال
- الاحتواء
<dialog>- توافق النماذج
- الانتقال
- Subgrid
- فن الطباعة
- وحدات إطار العرض
- توافق الويب
هذه قائمة مثيرة وطموحة وأنا متشوّق لمشاهدة هذه الأفلام.
أغاني جديدة لعام 2022
ليس من المستغرب أنّ حالة CSS في 2022 تأثّرت بشكل كبير بجهود Interop 2022.
طبقات متتالية
قبل @layer، كان الترتيب الذي يتم به تحميل أوراق الأنماط المكتشفة مهمًا جدًا،
لأنّ الأنماط التي يتم تحميلها أخيرًا يمكن أن تحل محل الأنماط التي تم تحميلها سابقًا. وقد أدّى ذلك إلى إدارة دقيقة لأوراق الأنماط الخاصة بنقاط الدخول، حيث كان على المطوّرين تحميل الأنماط الأقل أهمية أولاً ثم الأنماط الأكثر أهمية لاحقًا. تتوفّر منهجيات كاملة لمساعدة المطوّرين في إدارة هذه الأهمية، مثل ITCSS.
باستخدام @layer، يمكن لملف الإدخال تحديد الطبقات وترتيبها مسبقًا. بعد ذلك، عند تحميل الأنماط أو تعريفها، يمكن وضعها ضمن طبقة، ما يتيح الحفاظ على أهمية تجاوز النمط ولكن بدون الحاجة إلى إدارة ترتيب التحميل بدقة.
يوضّح الفيديو كيف تتيح طبقات التتالي المحدّدة عملية إنشاء وتحميل أكثر حرية وبأسلوب حر، مع الحفاظ على التتالي حسب الحاجة.
تساعد "أدوات مطوّري البرامج في Chrome" في عرض الأنماط التي تأتي من الطبقات المختلفة:

الموارد
- مواصفات CSS Cascade 5
- شرح طبقات التتالي
- طبقات متتالية على MDN
- Una Kravets: طبقات التتالي
- أحمد شديد: مرحبًا، طبقات CSS المتتالية
Subgrid
قبل 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 فقط في الوقت الحالي). في الصورة التالية، تمّت إضافة الشبكة الرئيسية والشبكات الفرعية فوق بعضها. أصبح الآن يشبه الطريقة التي كان يفكر بها المصممون بشأن التنسيق.

في لوحة "العناصر" ضمن "أدوات المطوّرين"، يمكنك الاطّلاع على العناصر التي تمثّل شبكات وشبكات فرعية، ما يساعدك كثيرًا في تصحيح الأخطاء أو التحقّق من صحة التنسيق.
الموارد
طلبات الحاويات
قبل @container، كان بإمكان عناصر صفحة الويب الاستجابة فقط لحجم إطار العرض بأكمله. هذا رائع للتصاميم الكبيرة، ولكن بالنسبة إلى التصاميم الصغيرة التي لا يشكّل الحاوية الخارجية فيها كامل مساحة العرض، لا يمكن تعديل التصميم وفقًا لذلك.
بعد @container، يمكن للعناصر الاستجابة لحجم أو نمط الحاوية الرئيسية.
الشرط الوحيد هو أن تحدّد الحاويات نفسها كاستهدافات محتملة لطلبات البحث، وهو شرط بسيط مقابل فائدة كبيرة.
/* establish a container */
.day {
container-type: inline-size;
container-name: calendar-day;
}
هذه الأنماط هي التي تتيح البحث عن الأعمدة "الاثنين" و"الثلاثاء" و"الأربعاء" و"الخميس" و"الجمعة" في الفيديو التالي باستخدام عناصر الحدث.
إليك رمز CSS للاستعلام عن حجم الحاوية calendar-day، ثم تعديل التنسيق وأحجام الخطوط:
@container calendar-day (max-width: 200px) {
.date {
display: block;
}
.date-num {
font-size: 2.5rem;
display: block;
}
}
في ما يلي مثال آخر: يتكيّف أحد مكوّنات الكتاب مع المساحة المتوفّرة في العمود الذي يتم سحبه إليه:
تصدق "أونا" في تقييمها للوضع على أنّه التصميم الجديد المتجاوب. هناك العديد من قرارات التصميم الرائعة والمهمة التي يجب اتخاذها عند استخدام @container.
الموارد
- مواصفات Container Queries
- شرح طلبات الحاوية
- استعلامات الحاويات على MDN
- التصميم المتجاوب الجديد على web.dev
- عرض توضيحي لـ "تقويم Google" من Una
- مجموعة رائعة من طلبات الحاويات
- كيفية إنشاء فعالية Designcember على web.dev
- أحمد شديد: مقدمة عن طلبات البحث في حاويات CSS
accent-color
قبل الإصدار accent-color، عندما كنت تريد نموذجًا بألوان متطابقة مع العلامة التجارية، كان بإمكانك استخدام مكتبات معقّدة أو حلول CSS يصعب إدارتها بمرور الوقت. على الرغم من أنّهم قدّموا لك جميع الخيارات، ونأمل أن يكونوا قد أدرجوا خيار تسهيل الاستخدام، يصبح اختيار استخدام المكوّنات المضمّنة أو اعتماد مكوّناتك الخاصة أمرًا مملًا.
بعد accent-color، يضيف سطر واحد من CSS لون العلامة التجارية إلى المكوّنات المضمّنة. بالإضافة إلى درجة اللون، يختار المتصفّح بذكاء ألوانًا متناقضة مناسبة للأجزاء الثانوية من المكوّن ويتكيّف مع أنظمة الألوان (الفاتحة أو الداكنة).
/* tint everything */
:root {
accent-color: hotpink;
}
/* tint one element */
progress {
accent-color: indigo;
}

لمزيد من المعلومات حول accent-color، يمكنك الاطّلاع على مشاركتي على
web.dev حيث أستكشف العديد من الجوانب الأخرى
لهذه السمة المفيدة في CSS.
الموارد
- مواصفات accent-color
- accent-color على MDN
- accent-color على web.dev
- Bramus: تلوين عناصر التحكّم في واجهة المستخدم باستخدام السمة accent-color في 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()
يشير HWB إلى تدرّج اللون والأبيض والأسود. وهي تقدّم نفسها كطريقة سهلة الاستخدام للتعبير عن اللون، إذ إنّها مجرد تدرّج لون وكمية من الأبيض أو الأسود لتفتيح اللون أو تغميقه. قد يستفيد الفنانون الذين يمزجون الألوان مع الأبيض أو الأسود من هذه الإضافة إلى بنية الألوان.
يؤدي استخدام دالة الألوان هذه إلى عرض ألوان من مساحة ألوان sRGB، وهي المساحة نفسها التي تستخدمها HSL وRGB. في ما يتعلّق بالميزات الجديدة لعام 2022، لا يوفّر لك هذا الخيار ألوانًا جديدة، ولكنّه قد يسهّل بعض المهام على محبّي بنية الجملة والنموذج الذهني.
الموارد
مساحات الألوان
يتم تمثيل الألوان باستخدام مساحة ألوان. تقدّم كل مساحة ألوان ميزات مختلفة ومفاضلات للتعامل مع الألوان. قد يجمع البعض كل الألوان الزاهية معًا، وقد يرتبها البعض الآخر أولاً استنادًا إلى درجة سطوعها.
من المفترض أن يوفّر CSS في عام 2022 عشر مساحات ألوان جديدة، لكل منها ميزات فريدة لمساعدة المصمّمين والمطوّرين في عرض الألوان واختيارها ودمجها. في السابق، كان sRGB هو الخيار الوحيد للتعامل مع الألوان، ولكن يتيح CSS الآن إمكانات جديدة ومساحة ألوان تلقائية جديدة، وهي LCH.
color-mix()
قبل 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-mix()
- color-mix() على MDN
- عرض توضيحي للمظاهر
- عرض توضيحي آخر حول تغيير المظهر
- Fabio Giolito: إنشاء مظهر ألوان باستخدام ميزات CSS القادمة هذه
color-contrast()
قبل color-contrast()، كان على مؤلفي أوراق الأنماط معرفة الألوان المناسبة لذوي الاحتياجات الخاصة مسبقًا. في كثير من الأحيان، تعرض لوحة الألوان نصًا أسود أو أبيض على عيّنة لونية،
لتوضيح لون النص الذي يجب استخدامه مع نظام الألوان
لتحقيق التباين المناسب مع تلك العيّنة.
بعد color-contrast()، يمكن لمؤلفي أوراق الأنماط نقل المهمة بالكامل إلى المتصفّح. لا يقتصر الأمر على إمكانية استخدام المتصفّح لاختيار لون أسود أو أبيض تلقائيًا، بل يمكنك أيضًا تزويده بقائمة بالألوان المناسبة لنظام التصميم، وسيقوم المتصفّح باختيار اللون الأول الذي يستوفي نسبة التباين المطلوبة.
في ما يلي لقطة شاشة لعرض مجموعة لوحة ألوان 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 نفسها.
الموارد
بنية الألوان النسبية
قبل توفّر صيغة الألوان النسبية، كان يجب وضع قنوات الألوان بشكل فردي في خصائص مخصّصة من أجل إجراء العمليات الحسابية على الألوان وإجراء التعديلات. وقد جعلت هذه القيود نموذج 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() لضمان توفّر التباين المناسب في التصنيفات:
يمكن استخدام هذه الدالة أيضًا لإنشاء لوحة ألوان. إليك عرضًا توضيحيًا يتم فيه إنشاء لوحات ألوان كاملة من لون أساسي محدّد. تتيح مجموعة 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);
}
نأمل أن تكون قد أدركت الآن كيف يمكن استخدام مساحات الألوان ووظائف الألوان المختلفة لأغراض متنوعة، استنادًا إلى نقاط القوة والضعف فيها.
الموارد
- مواصفات بنية الألوان النسبية
- إنشاء لوحات ألوان باستخدام بنية الألوان النسبية
- إنشاء خيارات ألوان باستخدام بنية الألوان النسبية
مساحات الألوان المتدرّجة
قبل مساحات الألوان المتدرجة، كانت مساحة ألوان sRGB هي مساحة الألوان التلقائية المستخدَمة. وعلى الرغم من أنّ sRGB موثوقة بشكل عام، إلا أنّها تتضمّن بعض نقاط الضعف، مثل منطقة اللون الرمادي غير النشطة.

بعد مساحات ألوان التدرّج، عليك إخبار المتصفّح بمساحة الألوان التي يجب استخدامها في استيفاء الألوان. يمنح ذلك المطوّرين والمصمّمين القدرة على اختيار التدرّج اللوني المفضّل لديهم. تتغيّر مساحة الألوان التلقائية أيضًا إلى LCH بدلاً من sRGB.
تتم إضافة البنية بعد اتجاه التدرّج، وتستخدم البنية الجديدة in، وهي اختيارية:
background-image: linear-gradient(
to right in hsl,
black, white
);
background-image: linear-gradient(
to right in lch,
black, white
);
إليك تدرّجًا أساسيًا وضروريًا من الأسود إلى الأبيض. اطّلِع على نطاق النتائج في كل مساحة ألوان. يصل البعض إلى اللون الأسود الداكن قبل غيرهم، بينما يتلاشى البعض الآخر إلى اللون الأبيض في وقت متأخر جدًا.

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

لمزيد من الاستكشافات المتعمّقة والأمثلة والتعليقات، يمكنك قراءة سلسلة المحادثات هذه على Twitter.
الموارد
- مواصفات الاستيفاء التدريجي
- عرض توضيحي لمقارنة التدرّجات في المساحات
- مقارنة تدرّجات الألوان في دفتر ملاحظات Observable
inert
قبل inert، كان من الممارسات الجيدة توجيه تركيز المستخدم إلى مناطق الصفحة أو التطبيق التي تحتاج إلى اهتمام فوري. أصبحت استراتيجية التركيز الموجّه هذه تُعرف باسم "حصر التركيز" لأنّ المطوّرين كانوا يوجّهون التركيز إلى مساحة تفاعلية، ويستمعون إلى أحداث تغيير التركيز، وإذا خرج التركيز من المساحة التفاعلية، يتم إعادته إليها. يتم توجيه المستخدمين الذين يستعينون بلوحات المفاتيح أو قارئات الشاشة إلى المساحة التفاعلية للتأكّد من إكمال المهمة قبل الانتقال إلى الخطوة التالية.
بعد inert، لن تحتاج إلى منع التفاعل لأنّه يمكنك تجميد أو حماية أقسام كاملة من الصفحة أو التطبيق. ولن تكون محاولات النقر وتغيير التركيز متاحة ببساطة أثناء عدم نشاط هذه الأجزاء من المستند. يمكن أيضًا التفكير في هذا الأمر على أنّه يشبه الحراس بدلاً من الفخ، حيث لا يهدف inert إلى إبقائك في مكان معيّن، بل إلى إتاحة أماكن أخرى.
من الأمثلة الجيدة على ذلك الدالة alert() في JavaScript:
لاحظ في الفيديو السابق كيف كان من الممكن الوصول إلى الصفحة باستخدام الماوس ولوحة المفاتيح
إلى أن تم استدعاء 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، أصبح بإمكان الويب استخدام خطوط أصغر حجمًا، وقابلة للتوسيع المستند إلى المتجهات، وقابلة لإعادة التموضع، وتتضمّن تدرّجات، وتعمل باستخدام وضع المزج، كما أنّها تقبل المَعلمات لتخصيص الخط حسب حالة الاستخدام أو لمطابقة هوية العلامة التجارية.
في ما يلي مثال من مشاركة مدوّنة "مطوّرو 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;
}
مع توفّر المزيد من الخطوط المتغيرة وخطوط الألوان، تتّجه الطباعة على الويب نحو مسار رائع يتيح تخصيصًا غنيًا وتعبيرًا إبداعيًا.
الموارد
وحدات إطار العرض

قبل توفّر خيارات إطار العرض الجديدة، كان الويب يوفّر وحدات مادية للمساعدة في ملاءمة إطارات العرض. كان هناك واحد للارتفاع والعرض وأصغر حجم (vmin) وأكبر جانب (vmax). كانت هذه الطريقة فعّالة في العديد من الحالات، ولكن متصفّحات الأجهزة الجوّالة أضافت تعقيدًا.
عند تحميل صفحة على جهاز جوّال، يظهر شريط الحالة الذي يتضمّن عنوان URL، ويستهلك هذا الشريط بعض مساحة إطار العرض. بعد بضع ثوانٍ وبعض التفاعلات، قد ينزلق شريط الحالة بعيدًا للسماح للمستخدم بتجربة أكبر في إطار العرض. ولكن عند انزلاق شريط الإعلانات هذا، يكون ارتفاع إطار العرض قد تغيّر، وبالتالي ستتغير مواضع وحدات vh وأحجامها مع تغيّر حجمها المستهدَف.
في السنوات اللاحقة، كان على وحدة vh تحديد حجم إطار العرض الذي ستستخدمه، لأنّها كانت تتسبّب في مشاكل مزعجة في التنسيق المرئي على الأجهزة الجوّالة. تم تحديد أنّ vh سيمثّل دائمًا أكبر مساحة عرض.
.original-viewport-units {
height: 100vh;
width: 100vw;
--size: 100vmin;
--size: 100vmax;
}
بعد توفّر صيغ إطار العرض الجديدة، وهي إطار العرض الصغير والكبير والديناميكي، تمت إضافة مكافئات منطقية إلى المكافئات المادية. الفكرة هي منح المطوّرين والمصمّمين القدرة على اختيار الوحدة التي يريدون استخدامها في السيناريو المحدّد. قد يكون من المقبول حدوث تغيير بسيط في تنسيق الصفحة
عند إزالة شريط الحالة، وبالتالي يمكن استخدام dvh (ارتفاع إطار العرض الديناميكي) بدون قلق.

في ما يلي قائمة كاملة بجميع خيارات وحدات عرض الإعلانات الجديدة التي أصبحت متاحة مع صيغ وحدات عرض الإعلانات الجديدة:
.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()
قبل :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
وتعديل
تخطيطات شبكة CSS استنادًا إلى عدد العناصر الفرعية. يمكنك الجمع بين :has() وحالات فئة псевдо التفاعلية وإنشاء تطبيقات تستجيب بطرق إبداعية جديدة.
يمكنك التحقّق من التوافق بسهولة باستخدام الدالة
@supports
والدالة
selector()
التابعة لها، والتي تتحقّق مما إذا كان المتصفّح يفهم بنية الجملة قبل استخدامها:
@supports (selector(:has(works))) {
/* safe to use :has() */
}
الموارد
2022 وما بعده
ستبقى بعض الإجراءات صعبة التنفيذ حتى بعد طرح كل هذه الميزات الرائعة في 2022. يتناول القسم التالي بعض المشاكل المتبقية والحلول التي يتم العمل على تطويرها حاليًا لحلّها. هذه الحلول تجريبية، حتى إذا تم تحديدها أو توفيرها خلف علامات في المتصفحات.
يجب أن تمنحك الأقسام التالية شعورًا بالراحة لأنّ العديد من الأشخاص من العديد من الشركات يسعون إلى حلّ المشاكل المدرَجة، وليس لأنّ هذه الحلول سيتم إصدارها في عام 2023.
الخصائص المخصّصة ذات الأنواع غير المحدّدة
الخصائص المخصّصة في 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.
الصور المتحركة
بالإضافة إلى أمان الأنواع، يتيح لك ذلك أيضًا إمكانات عديدة للرسوم المتحركة. تتسبب مرونة بنية 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 الكثير من المساعدة، ولكن هذه الإمكانات الصغيرة يمكن أن يكون لها تأثير كبير.
الموارد
- @property specification
- @property on MDN
- @property على web.dev
- الإصدار التجريبي من ميزة "التركيز مع التكبير/التصغير"
- CSS Tricks: Exploring @property and its animating powers
زيارة 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) {
…
}
استنادًا إلى خبرتك في الترميز، سيكون أحد الخيارَين أكثر وضوحًا من الآخر. بفضل الإضافات إلى المواصفات، سيتمكّن المطوّرون من اختيار المواصفات التي يفضّلونها، أو حتى استخدامها بالتبادل.
الموارد
- مواصفات بنية نطاق طلب البحث عن الوسائط
- بنية نطاق طلبات البحث عن الوسائط على شبكة مطوّري Mozilla (MDN)
- Media query range syntax PostCSS plugin
ما مِن متغيرات لاستعلامات الوسائط
قبل الإصدار @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 بشكل عام في تنظيم الأنماط وتوحيدها وتحديد مالكها بشكل أفضل. يمكن للمكوّنات تجميع أنماطها الخاصة وامتلاكها، بدلاً من توزيعها بين كتل الأنماط الأخرى. قد يبدو صغيرًا في هذه الأمثلة، ولكن يمكن أن يكون له تأثير كبير جدًا، سواء من ناحية سهولة الاستخدام أو الوضوح.
الموارد
يصعب جدًا تحديد نطاق الأنماط
قبل @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 أفضل طريقة لتحقيق تصميم masonry، لأنّ أيًا من طرق CSS التي تستخدم الأعمدة أو flexbox كانت تعرض ترتيب المحتوى بشكل غير دقيق.
بعد استخدام CSS masonry مع الشبكة، لن تكون هناك حاجة إلى مكتبات JavaScript، وسيكون ترتيب المحتوى صحيحًا.
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.
الموارد
- مواصفات تنسيق Masonry
- تفعيل التنسيق المتجانب على شبكة مطوّلي Mozilla
- Smashing Magazine: Native CSS Masonry Layout with CSS Grid
لا يمكن أن تساعد صفحات الأنماط المتتالية (CSS) المستخدمين في تقليل البيانات
قبل طلب البحث عن الوسائط 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 يمكن أن يساعد في هذا الصدد.
الموارد
- مواصفات prefers-reduced-data
- prefers-reduced-data على MDN
- prefers-reduced-data في واجهة مستخدم رسومية تحدّي
- Smashing Magazine: Improving Core Web Vitals, A Smashing Magazine Case Study
ميزات المحاذاة عند التمرير محدودة جدًا
قبل هذه الاقتراحات بشأن ميزة "المحاذاة عند التمرير"، كان من الممكن أن يصبح إنشاء رمز JavaScript خاص بك لإدارة لوحة عرض دوّارة أو شريط تمرير أو معرض أمرًا معقّدًا بسرعة، وذلك بسبب جميع أدوات المراقبة وإدارة الحالة. بالإضافة إلى ذلك، إذا لم يتم توخّي الحذر، قد يتم تعديل سرعات التمرير الطبيعية بواسطة البرنامج النصي، ما يجعل تفاعل المستخدم يبدو غير طبيعي بعض الشيء وربما غير سلس.
واجهات برمجة تطبيقات جديدة
snapChanging()
يتم إطلاق هذا الحدث فور أن يحرّر المتصفّح عنصرًا ثانويًا تم التقاطه. يسمح ذلك لواجهة المستخدم بعرض عدم توفّر عنصر ثانوي في المحاذاة وحالة المحاذاة غير المحدّدة لأداة التمرير، لأنّه يتم استخدامها الآن وسيتم عرضها في مكان جديد.
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;
}
بعد هذه الاقتراحات بشأن ميزة "المحاذاة عند التمرير"، أصبح إنشاء شريط تمرير أو لوحة عرض دوّارة أو معرض أسهل بكثير لأنّ المتصفّح يوفّر الآن تسهيلات لهذه المهمة، ما يغني عن استخدام أدوات المراقبة ورمز تنظيم التمرير لصالح استخدام واجهات برمجة التطبيقات المضمّنة.
لا تزال هذه الميزات في مراحلها الأولى، ولكن ننصحك بالبحث عن 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()، يمكن للمطوّرين تحديد موضع العناصر بالنسبة إلى عناصر أخرى، بغض النظر عمّا إذا كانت العناصر ثانوية أم لا. ويتيح أيضًا للمطوّرين تحديد الحافة التي سيتم تحديد موضع العنصر بالنسبة إليها، بالإضافة إلى ميزات أخرى لإنشاء علاقات تحديد الموضع بين العناصر.
يتضمّن الشرح بعض الأمثلة الرائعة وعيّنات الرموز البرمجية، إذا كنت مهتمًا بمعرفة المزيد.