استعلامات العنصر ، وكيف يمكنك استخدامها اليوم
نشرت: 2022-03-10فكر للحظة في الهيكل المادي. إذا كنت تبني صرحًا كبيرًا بمواد ضعيفة ، فسيلزم الكثير من الدعم الخارجي لتماسكه معًا ، ويجب أن تكون الأشياء مبالغة في الثبات لتبقى متينة. عند إنشاء موقع ويب باستخدام HTML و CSS و JavaScript ، قد يبدو هذا الدعم الخارجي مثل أطر العمل والمكونات الإضافية والمعالجات التمهيدية والمحولات وأدوات التحرير ومديري الحزم وعمليات الإنشاء.
بدلاً من إضافة مكون إضافي آخر إلى الجزء العلوي من المجموعة ، تساءلت عما إذا كان بإمكاننا ، من خلال توسيع إحدى اللغات الأساسية ، CSS ، تقوية المواد التي تُبنى منها مواقع الويب ، وتطوير مواقع ويب أفضل وأقوى تتطلب دعمًا وأدوات خارجية أقل لبناء.
استعلامات الحالة الحالية للعنصر
باستخدام أدوات مثل معالجات CSS الأولية ، نكتب CSS باختصار ، ليتم توسيعها لاحقًا إلى شكلها الكامل (قبل عرضها في المتصفح). يمكن للمكونات الإضافية أن تعمل على الصفحة جنبًا إلى جنب مع العناصر التي تؤثر عليها ، ولكن لتطبيق الأنماط ، فإنها إما تكتب أنماط CSS مباشرة إلى HTML أو تقوم بتبديل أسماء الفئات التي تطبق قواعد CSS مختلفة. في كلتا الحالتين ، نحتاج إلى كتابة أو إنشاء CSS الذي سنحتاجه قبل تحميل الصفحة بالفعل.
المشكلة
تكمن مشكلة هذه الطريقة في أنه حتى أفضل المكونات الإضافية غالبًا ما تتطلب التخصيص والتهيئة في كل تخطيط تستخدمه. أيضًا ، عندما تكتب JavaScript أنماطًا لك ، قد يكون من الصعب الاحتفاظ بالمنطق القائم على المكون الإضافي وأنماط CSS معًا عند إعادة بناء التعليمات البرمجية أو إعادة استخدامها.
مشكلة أخرى مع المعالجات المسبقة هي أن أي أخطاء مكتوبة باختصار تتحول بسرعة إلى فوضى أكبر بمجرد توسيع CSS إلى شكله الكامل. عند استخدام المكونات الإضافية ، نضيف العديد من نقاط الفشل المحتملة. قد نستخدم مكونات إضافية متعددة لإنجاز عدد قليل من الأشياء المختلفة التي قد تكون جميعها غير ضرورية إذا كانت CSS أكثر قوة قليلاً. وهذا يشكل عبئًا إضافيًا على عاتق المطورين للمحافظة عليه ، وعلى المتصفحات لتقديمه وعلى المستخدمين لتنزيله.
هل هناك أي أمل لمستقبل تطوير الويب؟
في عام 2013 ، كتب Tyson Matanich مقالًا بعنوان "استعلامات الوسائط ليست الإجابة: Element Query Polyfill" ، والتي قدمت مفهوم استعلامات العناصر إلى جمهور كبير. لقد بدأ مناقشة حول كيفية إنشاء المكونات الإضافية و polyfills للتنقل حول أوجه القصور في CSS.
منذ ذلك الحين ، بينما ننتظر تقدم ميزات CSS ، تم إصدار عدد من المكونات الإضافية التي تسمح للمطورين باستخدام استعلامات العناصر بعدة طرق مختلفة.
ما هي استعلامات العنصر؟
تعتبر استعلامات العناصر مثل استعلامات الوسائط ، باستثناء أن قواعدها تنطبق على خصائص العناصر الفعلية ، بدلاً من تلك الخاصة بإطار عرض المتصفح.
كيف جاء EQCSS
في أواخر عام 2013 ، وجدت نفسي أعمل على الواجهة الأمامية لتطبيق ويب Ruby on Rails. كان التطبيق بحاجة إلى عرض معلومات مفصلة للمستخدمين ، وكان الهدف هو إنشاء واجهة سريعة الاستجابة تعمل بشكل جيد على الهواتف والأجهزة اللوحية ومتصفحات سطح المكتب. شكل هذا بعض التحديات ، كان أحدها أن الكثير من المحتوى المهم الذي سيتم عرضه كان أفضل عرض في الجداول - نعم ، عناصر table
الفعلية (لإظهار المعاملات المالية ، والسجلات الرياضية ، وما إلى ذلك).
لقد أنشأت أنماطًا سريعة الاستجابة باستخدام استعلامات الوسائط التي عرضت عنصر table
بشكل صحيح للمتصفحات ذات الأحجام المختلفة. ولكن بمجرد عرض أحد هذه الجداول سريعة الاستجابة في قالب يحتوي على شريط جانبي ، تحولت فجأة جميع نقاط التوقف المتجاوبة إلى نقاط توقف سريعة الاستجابة. إنهم ببساطة لم يأخذوا في الحسبان الشريط الجانبي الذي يبلغ عرضه 200 بكسل ، مما تسبب في تداخل الأشياء وظهورها مكسورة.
عقبة أخرى: تباينت أسماء المستخدمين في الطول من 3 إلى 20 حرفًا ، ووجدت نفسي أتمنى أن أتمكن تلقائيًا من ضبط حجم الخط لكل اسم مستخدم بناءً على عدد الأحرف التي يحتوي عليها. كنت بحاجة إلى وضع اسم كل مستخدم في الشريط الجانبي ، وكان من الصعب اختيار حجم خط صغير بما يكفي ليلائم اسم مستخدم مكونًا من 20 حرفًا ولكنه كبير بما يكفي لكي يرى المشاهد اسم مستخدم مكونًا من 3 أحرف.
للتغلب على مثل هذه المشكلات ، غالبًا ما أجد نفسي أنسخ استعلامات وسائط كاملة ، وأكرر أقسامًا كبيرة من قاعدة التعليمات البرمجية الخاصة بي ، وذلك ببساطة لأنني كنت بحاجة إلى طريقة أكثر ذكاءً لتطبيق الأنماط سريعة الاستجابة في كل تخطيط. لقد اعتمدت على JavaScript كحل مؤقت آخر ، حيث أكتب العديد من الوظائف المتطابقة تقريبًا التي من شأنها مشاهدة الصفحة وتطبيق الأنماط في الأماكن التي يتعذر على CSS الوصول إليها. بعد فترة ، بدأ العبء الإضافي لكل هذه التعليمات البرمجية المكررة يثقل كاهل قاعدة الشفرة وجعل التغييرات صعبة التنفيذ.
كنت أعلم أنه يجب أن يكون هناك حل أفضل ، وبعد فترة بدأت أفكر: لست بحاجة إلى استعلامات وسائط - ما أحتاجه هو استعلامات العناصر!
البحث والتطوير
خلال عام 2014 ، بدأت بتجربة طرق مختلفة لإبلاغ CSS بخصائص العناصر كما ظهرت على الصفحة ، حتى أتمكن من تطبيق أنماط أفضل. كنت آمل في اكتشاف طريقة تسمح لي بكتابة أنماط تجمع بين جمال CSS وقوة JavaScript.
تتضمن بعض الأساليب التي تم التخلي عنها إضافة سمات إلى علامات HTML من أجل إضافة دعم سريع الاستجابة ، ومحاولة إيجاد طرق لتضمين كتل كاملة من كود CSS داخل عبارات if
المستندة إلى JavaScript لإنتاج نوع من Frankenstein monster مصححة معًا من JavaScript و CSS.
ولكن بدلاً من جعل الأمور أسهل ، كان لكل مقاربي الفاشلة شيء واحد مشترك: لقد أضافوا المزيد من العمل! كنت أعلم أن الحل الصحيح من شأنه أن يبسط ويقلل من العمل المطلوب إنجازه ، لذلك واصلت البحث. من خلال هذه التجارب ، انتهى بي الأمر بفكرة مصقولة لنوع بناء الجملة الذي سيكون مطلوبًا لكي تعمل استعلامات العناصر بشكل جيد.
كما ذكرنا ، بالنسبة إلى موقع ويب تم إنشاؤه من HTML و CSS و JavaScript ، يأتي الدعم الخارجي في شكل أطر عمل ومكونات إضافية ومعالجات أولية و transpilers وأدوات التحرير ومديري الحزم وعمليات الإنشاء. بدلاً من إضافة مكون إضافي آخر إلى الجزء العلوي من المجموعة ، تساءلت عما إذا كان بإمكاننا ، من خلال توسيع إحدى اللغات الأساسية ، CSS ، تقوية المواد التي بنيت عليها مواقع الويب ، وبناء مواقع ويب أفضل وأقوى تتطلب دعمًا خارجيًا أقل و أدوات للبناء.
ولادة النحو
بحلول نهاية عام 2014 ، وبتجهيزه برؤية أفضل لبناء الجملة المطلوب ، اتصلت بـ Maxime Euziere ، لاعب غولف رائع في JavaScript وسألته عن إمكانية توسيع CSS باستخدام JavaScript في المتصفح في وقت التشغيل. لم يخبرني فقط أن ذلك ممكن ، لكنه عرض مساعدتي على القيام بذلك! أطلقنا على بناء الجملة EQCSS ، اختصارًا لـ "استعلام العنصر CSS". يعد الاسم أيضًا إشارة إلى كلمة "فائض" ، لأن كل ما يفعله يتجاوز ما يمكن أن يفعله CSS.
الحاجة
كان مطلب بناء الجملة هو أن يكون أقرب ما يكون إلى CSS - قريب جدًا من أن تُخدع أدوات تمييز بناء الجملة للاعتقاد بأنها CSS قياسية. لذلك ، قمت بتحديد بنية CSS لاستعلامات العناصر المنطقية - نوع البنية الذي يفاجأ الناس به غير موجود بالفعل.
كنت أعلم أنه إذا كنا سنقوم بتوسيع دعم المتصفح لـ CSS باستخدام JavaScript ، فيجب أن يكون المكون الإضافي خفيف الوزن ومباشرًا قدر الإمكان لإنجاز المهمة ، الأمر الذي يستبعد استخدام مكتبات مثل jQuery لبناء المكون الإضافي. كنت بحاجة إلى مكتبة JavaScript نقية تضيف الميزات التي أريدها في المستقبل إلى المتصفحات التي يجب أن أدعمها اليوم.
في هذا الوقت ، تركز المناقشة في مجتمع CSS على قواعد @
المخصصة ، ولا يزال الحديث عن استعلامات العناصر أولًا. من المحتمل أننا ما زلنا على بعد سنوات من أي مواصفات CSS رسمية لميزات مثل هذه ، وحتى بعد المواصفات ، سنظل بحاجة إلى انتظار دعم متصفح كافٍ قبل أن نتمكن من استخدام هذه الميزات في مواقع الويب.
لا يكون انتظار إضافة هذه الميزات إلى CSS منطقيًا عندما نحتاج إلى هذه الوظيفة لإنشاء مواقع الويب وإصلاحها اليوم.
النتائج
كانت نتيجة هذا البحث هي إنشاء بناء جملة يتضمن مجموعة جديدة من الشروط المتجاوبة المتقدمة ، والأنماط المحددة النطاق والمحددات الجديدة لعناصر الاستهداف ، بالإضافة إلى مكتبة JavaScript نقية باسم EQCSS.js. بالإضافة إلى ذلك ، تم توفير دعم لـ Internet Explorer (IE) 8 في polyfill خارجي اختياري. تم إصدار كل من المكون الإضافي و polyfill بموجب ترخيص MIT وهما مجانيان للاستخدام للجميع.
حالات الاستخدام لاستعلامات العنصر
مطورو البرنامج المساعد
عند إنشاء عناصر واجهة المستخدم وعناصر واجهة المستخدم ، غالبًا ما يجد المطورون أنفسهم مقيدين باستعلامات الوسائط. غالبًا ما يتعين علينا الاختيار بين إنشاء العديد من التنسيقات المختلفة التي يمكن تكوينها بواسطة الشخص الذي يستخدم المكون الإضافي ، وتبسيط الواجهة لدرجة أنه يمكنك إنشاء حل واحد يناسب أكثر.
ولكن عند تصميم المكونات الإضافية والواجهات باستخدام استعلامات العناصر ، يمكننا بسهولة كتابة أنماط متجاوبة تغطي جميع المواقف التي نتوقعها ، مما يجعلها مقاومة للرصاص حقًا ، بغض النظر عن المحتوى الذي يضعه المستخدم في الداخل أو حيث يظهر المكون الإضافي. لنفترض أنه يمكننا تصميم عنصر واجهة مستخدم بتنسيقات تتراوح من 150 إلى 2000 بكسل. بعد ذلك ، بغض النظر عن مكان عرض هذه الأداة على موقع ويب ، فإنها ستبدو رائعة دائمًا.
بناة القوالب
عند إنشاء نموذج أولي لموقع ويب ، من الشائع إعادة تنظيم عناصر التصميم على الصفحة والتفكير في التصميم كمجموعة من المكونات المعيارية. إذا كنت قد كتبت استعلامات وسائط CSS ، فقد يكون هذا أحيانًا حالة من التحسين المبكر . من خلال التصميم باستخدام استعلامات العناصر ، فإنك تحافظ على استجابة الظروف المستقلة عن التخطيط ، مما يمنحك المزيد من المرونة لتحريك الأشياء دون الحاجة إلى إعادة صياغة الأنماط بنفس القدر.
الأشياء التي وجدتها مفيدة بشكل خاص في التصميم أو الاستهزاء باستخدام استعلامات العناصر تشمل:
- أشرطة التنقل ،
- مشروط
- نماذج الاشتراك وتسجيل الدخول ،
- تذييلات
- مخططات التسعير ،
- الصفحات المقصودة
- الجداول،
- مربعات التبويب
- الأكورديون
- الحاجيات الشريط الجانبي ،
- مشغلات الوسائط ،
- أقسام الشهادة.
يمكن "تحديد نطاق" أي عنصر تصميم ونقله في أي مكان - من صفحة إلى صفحة أو من موقع ويب إلى موقع ويب.
دعم الجهاز
إحدى المشكلات التي تواجهها عند دعم الويب على الأجهزة المحمولة هي وفرة الأجهزة. أصبح سوق الأجهزة مجزأًا أكثر من أي وقت مضى ، وتظهر أجهزة جديدة كل يوم. لم يعد بإمكاننا الاحتفاظ بقائمة بالمتصفحات والأجهزة التي ندعمها ، لذلك من الضروري معرفة أن التصميم يعمل في كل مكان ، حتى على الأجهزة التي لم يتم إصدارها بعد.
باستخدام استعلامات العناصر ، يمكنك تصميم مواقع الويب بطريقة أفضل والتخلص من بعض هذه الاختلافات عبر المستعرضات.
توضح العديد من المقالات المكتوبة مؤخرًا حول الحاجة إلى استعلامات العناصر العديد من حالات الاستخدام بالتفصيل. لذا ، دعنا نبدأ في كيفية استخدامها!
كيفية كتابة استعلامات العنصر
إن بدء استخدام EQCSS أمر سهل. كل ما تحتاجه لبدء استخدام بناء جملة EQCSS هو تضمين JavaScript في مكان ما في HTML الخاص بك.
تنزيل EQCSS.js
إذا كنت تريد استنساخ مشروع EQCSS من GitHub ، فيمكنك كتابة:
git clone https://github.com/eqcss/eqcss.git
إذا كنت تستخدم npm ، فيمكنك إضافة EQCSS إلى مشروعك باستخدام الأمر التالي:
npm install eqcss
إضافة EQCSS.js إلى HTML الخاص بك
بمجرد تنزيل EQCSS ، يمكنك إضافته إلى HTML باستخدام علامة script
:
<script src="EQCSS.js"></script>
يتضمن هذا الملف ( EQCSS.js
) دعمًا لجميع المتصفحات الحالية ، بما في ذلك IE 9 والإصدارات الأحدث. لدعم IE 8 ، كان علينا استخدام الكثير من polyfills الأخرى. ضع في اعتبارك أن IE 8 لا يدعم حتى استعلامات وسائط CSS بدون تعبئة ، لذلك من المدهش جدًا أننا تمكنا من الحصول على استعلامات عن العناصر تعمل هناك أيضًا. لتضمين دعم IE 8 لموقع ويب باستخدام EQCSS ، أضف الرابط التالي قبل الارتباط الخاص بك إلى المكون الإضافي الرئيسي:
<!‐‐[if lt IE 9]><script src="EQCSS‐polyfills.js"></script><![endif]‐‐>
تشغيل EQCSS
افتراضيًا ، يحسب المكون الإضافي EQCSS أي أنماط يعثر عليها بمجرد تحميل الصفحة ، وأيضًا عندما يكتشف تغيير حجم المتصفح ، على غرار استعلامات الوسائط. يمكنك أيضًا استدعاء EQCSS.apply()
يدويًا باستخدام JavaScript لإعادة حساب الأنماط في أي وقت ، مما قد يكون مفيدًا بمجرد تحديث المحتوى على الصفحة.
استعلام عنصر الكتابة CSS
يمكن أن يقرأ المكون الإضافي EQCSS.js الأنماط بعدة طرق مختلفة. يمكنك تضمين EQCSS في أي علامات style
على صفحة HTML. يمكنك أيضًا كتابة EQCSS في ورقة أنماط CSS خارجية.
إذا كنت ترغب في الاحتفاظ بكودك المدعوم من EQCSS منفصلاً عن CSS ، فيمكنك تحميل بناء جملة EQCSS باستخدام علامة script
مع ضبط النوع على text/eqcss
. يمكنك إضافة أنماط مضمنة في علامة مثل هذه ، أو الارتباط بورقة أنماط .eqcss
خارجية مع <script type=“text/eqcss” src=styles.eqcss></script>
، والتي من شأنها تحميل ملف باسم styles.eqcss
.
تشريح عنصر الاستعلام
تحديد النطاق
يشبه بناء الجملة في EQCSS لكتابة استعلامات العناصر تنسيق استعلامات وسائط CSS ، ولكن بدلاً من @media
، نبدأ الاستعلام بـ @element
. المعلومة الأخرى الوحيدة التي نحتاج إلى توفيرها هي محدد واحد على الأقل يجب أن تنطبق عليه هذه الأنماط. إليك كيفية إنشاء نطاق جديد لعنصر يسمى <div class=“widget”>
:
@element '.widget' { }
قد يكون العنصر الموجود بين علامتي الاقتباس (في هذه الحالة ، .widget
) أي محدد CSS صالح. باستخدام هذا الاستعلام ، أنشأنا نطاقًا جديدًا على عنصر .widget
. لم نقم بتضمين أي شروط متجاوبة للنطاق حتى الآن ، لذا فإن أي أنماط في استعلام مثل هذا ستنطبق على عنصر النطاق في جميع الأوقات.
بدون القدرة على تحديد أنماط لعنصر واحد أو أكثر (بدلاً من الصفحة بأكملها مرة واحدة) ، لن نتمكن من تطبيق الاستعلامات سريعة الاستجابة على تلك العناصر فقط. بمجرد إنشاء هذا النطاق على مستوى العنصر ، يصبح استخدام الميزات الأكثر تقدمًا لبناء جملة parentNode
أمرًا سهلاً - مثل محدد meta $parent
، على سبيل المثال - لأن JavaScript لديها الآن نقطة مرجعية يمكن من خلالها حساب أشياء مثل الأصل جزء. هذا ضخم!
صحيح ، يتضمن CSS بالفعل محددًا تابعًا مباشرًا ، مع >
، والذي يسمح لنا بتحديد العناصر التي هي عناصر فرعية مباشرة للعنصر المحدد. لكن CSS لا تقدم حاليًا أي طريقة للانتقال في الاتجاه الآخر لأعلى شجرة العائلة ، لتحديد عنصر يحتوي على عنصر آخر ، والذي قد يسميه المرء العنصر الأصل. تتضمن مواصفات "CSS Selectors Level 4" الآن :has()
selector ، والذي يعمل بطريقة مشابهة لمحدد jQuery :has()
، لكن دعم المتصفح حاليًا لا شيء. يجعل CSS محدد النطاق نوعًا مختلفًا من المحدد الرئيسي ممكنًا.
الآن بعد أن فتحنا نطاقًا في سياق عنصر .widget
، يمكننا كتابة أنماط من وجهة نظره لاستهداف العنصر الأصلي الخاص به:
@element '.widget' { $parent { /* These styles apply to the parent of .widget */ } }
مثال آخر على المحددات الخاصة التي يمكن استخدامها في أي استعلام عنصر هو المحددات $prev
و $next
، والتي تمثل العناصر الشقيقة السابقة والتالية. على الرغم من أن CSS يمكنها الوصول إلى الشقيق التالي لعنصر واجهة المستخدم الخاص بنا باستخدام محدد مثل .widget + *
، لا توجد طريقة في CSS للوصول إلى الخلف وتحديد العنصر الذي يأتي مباشرة قبل عنصر آخر.
<section> <div>This will be the previous item</div> <div class="widget">This is the scoped element</div> <div>This will be the next item</div> </section> <style> @element '.widget' { $prev { /* These styles apply to the element before .widget */ } $next { /* These styles apply to the element after .widget */ } } </style>
استعلامات العنصر
يستخدم المطورون في أغلب الأحيان استعلامات وسائط CSS للتصميم سريع الاستجابة من خلال تطبيق الأنماط بناءً على ارتفاع أو عرض إطار عرض المتصفح. يدعم بناء جملة EQCSS العديد من الأنواع الجديدة من الظروف سريعة الاستجابة. بدلاً من العمل مع عرض المستعرض وارتفاعه وحده ، يمكنك كتابة أنماط تنطبق على العناصر بناءً على خصائصها الخاصة ، مثل عدد العناصر الفرعية التي يحتوي عليها أو عدد الأحرف أو سطور النص الموجودة في العنصر في الوقت الحالي .
تشبه إضافة هذه الشروط المتجاوبة إلى الأنماط المحددة النطاق طريقة تنسيق استعلامات الوسائط: يمكنك إضافة and (condition: value)
لكل شرط تريد التحقق منه. في هذا المثال ، سوف نتحقق مما إذا كانت أي من عناصر .widget
تعرض على الأقل 500 بكسل عرضًا على الصفحة.
@element '.widget' and (min‐width: 500px) { /* CSS rules here */ }
ينقسم بناء جملة استعلام عنصر كما يلي:
- الاستعلام عن عنصر
@element selector_list [ condition_list ] { css_code }
- قائمة المحدد
" css selector [ "," css selector ]* "
- قائمة الشروط
and ( query_condition : value ) [ "and (" query condition ":" value ")" ]*
- رقم القيمة
number [ css unit ]
- شرط الاستعلام
min-height | max-height | min-width | max-width | min-characters | max-characters | min-lines | max-lines | min-children | max-children | min-scroll-y | max-scroll-y | min-scroll-x | max-scroll-x
min-height | max-height | min-width | max-width | min-characters | max-characters | min-lines | max-lines | min-children | max-children | min-scroll-y | max-scroll-y | min-scroll-x | max-scroll-x
- وحدة css
% | px | pt | em | cm | mm | rem | ex | ch | pc | vw | vh | vmin | vmax
% | px | pt | em | cm | mm | rem | ex | ch | pc | vw | vh | vmin | vmax
كمثال آخر ، إليك كيفية كتابة استعلام يحول عنصر النص body
إلى اللون الأحمر عندما يصل عرض عنصر .widget
إلى 500 بكسل:
@element '.widget' and (min‐width: 500px) { body { background: red; } }
لاحظ أن عنصر النص body
يتغير عندما يصل .widget
إلى عرض معين ، وليس عنصر .widget
نفسه!
شروط استعلام العنصر
فيما يلي القائمة الكاملة للشروط سريعة الاستجابة التي يدعمها EQCSS.
العرض على أساس الظروف
-
min-width
للبكسل ، تجريبي للنسب المئوية -
max-width
للبكسل ، تجريبي للنسب المئوية
الظروف القائمة على الارتفاع
- عرض
min-height
للبكسل ، عرض توضيحي للنسب المئوية - عرض
max-height
للبكسل ، عرض توضيحي للنسب المئوية
الشروط القائمة على العد
-
min-characters
demo لعناصر الكتلة ، تجريبي لمدخلات النموذج - عرض
max-characters
لعناصر الكتلة ، عرض لمدخلات النموذج -
min-lines
تجريبي -
max-lines
التجريبية -
min-children
demo -
max-children
التجريبي
شروط قائمة على التمرير
-
min-scroll-y
-
max-scroll-y
-
min-scroll-x
-
max-scroll-x
يمكنك دمج أي عدد من هذه الشروط في استعلامات العناصر للحصول على أنماط استجابة متعددة الأبعاد حقًا. يمنحك هذا المزيد من المرونة والتحكم في كيفية عرض العناصر. على سبيل المثال ، لتقليص حجم خط رأس يحتوي على أكثر من 15 حرفًا عند توفر مساحة أقل من 600 بكسل للعرض ، يمكنك دمج الشروط max‐characters: 15
و max‐width: 600px
:
h1 { font‐size: 24pt; } @element 'h1' and (min‐characters: 16) and (max‐width: 600px) { h1 { font‐size: 20pt; } }
محددات ميتا
تتمثل إحدى المشكلات التي قد تواجهها بمجرد بدء كتابة أنماط محددة النطاق بشروط متجاوبة في أنه عند وجود مثيلات متعددة لنفس المحدد على الصفحة ، فإن استخدام هذا المحدد في استعلام العنصر الخاص بك سيطبق أنماطًا على جميع مثيلات ذلك المحدد في الصفحة عندما يتطابق أي منها مع الشروط. بأخذ أمثلة .widget
بنا من وقت سابق ، افترض أن لدينا عنصرين على الصفحة (ربما واحدة في الشريط الجانبي والأخرى معروضة بالعرض الكامل) وكتبنا استعلام العنصر كما يلي:
@element '.widget' and (min‐width: 500px) { .widget h2 { font‐size: 14pt; } }
قد يعني هذا أنه عندما يكون عرض أي من عناصر .widget
على الصفحة 500 بكسل على الأقل ، فإن النمط سينطبق على كلا .widget
. ربما ليس هذا ما نريد أن يحدث في معظم الحالات. هذا هو المكان الذي تأتي فيه محددات التعريف!
الجزءان اللذان يشكلان استعلام العنصر لدينا هما المحدد والشرط المتجاوب. لذلك ، إذا أردنا استهداف العناصر الموجودة على الصفحة فقط والتي تتطابق مع كل من المحدِّد والشروط سريعة الاستجابة في نفس الوقت ، فيمكننا استخدام المُحدِّد الوصفي $this
. يمكننا إعادة كتابة مثالنا الأخير بحيث ينطبق النمط فقط على عناصر .widget
التي تطابق شرط min‐width: 500px
:
@element '.widget' and (min‐width: 500px) { $this h2 { font‐size: 14pt; } }
يتم دعم عدد من المحددات الجديدة بواسطة بنية EQCSS غير الموجودة في CSS العادي. ستجد هنا لائحة كاملة:
-
$this
العرض - عرض
$parent
-
$root
التجريبي -
$prev
التجريبي - العرض التوضيحي
$next
ستعمل هذه المحددات فقط في استعلام عنصر.
فتح البوابة بين JavaScript و CSS
-
eval(')
تجريبي
الميزة الأخيرة والأخيرة لـ EQCSS هي الأكثر جموحًا على الإطلاق: eval(')
. من خلال هذا المدخل تكمن كل قوة JavaScript التي يمكن الوصول إليها من CSS. على الرغم من أن JavaScript يمكن أن تطبق أنماطًا على العناصر ، إلا أنها تواجه حاليًا صعوبة في الوصول إلى بعض الأشياء ، مثل :before
و :after
العناصر الزائفة. ولكن ماذا لو تمكنت CSS من الوصول إلى JavaScript من الاتجاه الآخر؟ بدلاً من إعداد JavaScript لخصائص CSS ، ماذا لو كان CSS مدركًا لـ JavaScript؟
هذا هو المكان الذي يأتي فيه eval(')
. يمكنك الوصول إلى أي JavaScript وتقييمه ، سواء كنت تستخدم قيمة متغير JavaScript في CSS الخاص بك ، لتنفيذ سطر واحد من JavaScript (مثل eval('new Date().getFullYear()')
) ، للتأكد من القيم المتعلقة بالمتصفح والعناصر الأخرى التي يمكن لـ JavaScript قياسها (مثل eval('innerHeight')
) أو لتشغيل وظيفة JavaScript واستخدام القيمة التي ترجعها في أنماط CSS الخاصة بك. في ما يلي مثال يُخرج 2016
في عنصر <footer>
:
@element 'footer' { $this:after { content: " eval('new Date().getFullYear()')"; } }
استخدام $ it داخل EVAL (')
أثناء تقييم JavaScript ، تعمل قيمة eval(')
أيضًا من سياق العنصر المحدد النطاق ، وهو نفس العنصر الذي تنطبق عليه أنماط $this
. يمكنك استخدام $it
في JavaScript مكتوب في eval(')
كعنصر نائب للعنصر المحدد إذا كان يساعدك على هيكلة الكود ، ولكن إذا تم حذفه ، فسيعمل بنفس الطريقة. على سبيل المثال ، لنفترض أن لدينا div
به كلمة "hello". ستخرج الكود التالي "hello hello":
<div>hello</div> <style> @element 'div' { div:before { content: "eval('$it.textContent') "; } } </style>
هنا ، يشير $it
إلى div
لأنه محدد النطاق حاليًا. يمكنك أيضًا حذف $it
وكتابة الكود التالي لعرض نفس الشيء:
@element 'div' { div:before { content: "eval('textContent') "; } }
يمكن أن تكون قيمة eval(')
مفيدة في المواقف التي لا يكون فيها CSS على علم بالقياسات أو الأحداث التي تحدث على الصفحة بعد تحميلها. على سبيل المثال ، تأتي عناصر iframe المستخدمة لتضمين مقاطع فيديو YouTube بعرض وارتفاع محددين. بينما يمكنك ضبط العرض على auto
في CSS ، لا توجد طريقة سهلة للحفاظ على نسبة العرض إلى الارتفاع الصحيحة عند توسيع الفيديو لملء المساحة المتاحة.
الحل الشائع للحفاظ على نسب العرض إلى الارتفاع سريعة الاستجابة أثناء القياس هو وضع المحتوى الذي يحتاج إلى الحفاظ على نسبة العرض إلى الارتفاع في غلاف ، ثم إضافة حشوة إلى الغلاف بقيمة تستند إلى نسبة العرض إلى الارتفاع التي تريد الاحتفاظ بها. يعمل هذا ، لكنه يتطلب منك معرفة نسبة العرض إلى الارتفاع لجميع مقاطع الفيديو مسبقًا ، كما يتطلب المزيد من ترميز HTML (عنصر مجمّع) لكل مقطع فيديو تريد تضمينه بشكل متجاوب. ضاعف ذلك في كل موقع ويب يحتوي على مقاطع فيديو سريعة الاستجابة ، وهذا كثير من المعلومات التي لن تحتاج إلى أن تكون موجودة إذا كانت CSS أكثر ذكاءً قليلاً.
ربما تتضمن الطريقة الأفضل لنسب العرض إلى الارتفاع سريعة الاستجابة وضع كل فيديو في غلاف بدون حشوة ثم كتابة مكتبة JavaScript تحسب نسبة العرض إلى الارتفاع لكل مقطع فيديو يعثر عليه وتطبق المقدار الصحيح من الحشو على كل غلاف.
ولكن ماذا لو تمكن CSS من الوصول إلى تلك القياسات مباشرة؟ لا يمكننا فقط دمج CSS لجميع نسب العرض إلى الارتفاع المختلفة في قاعدة واحدة ، ولكن إذا تمكنا من تقييمها بمجرد تحميل الصفحة ، فيمكننا كتابة قاعدة واحدة تعمل على تغيير حجم أي فيديو نقدمه في المستقبل بشكل متجاوب. ويمكننا القيام بكل ذلك بدون أي أغلفة!
إذا كان هذا يبدو جيدًا لدرجة يصعب تصديقها ، فتحقق من ذلك. إليك مدى بساطة كتابة عناصر إطار iframe خالية من الغلاف بشكل سريع الاستجابة في EQCSS:
@element 'iframe' { $this { margin: 0 auto; width: 100%; height: eval('clientWidth/(width/height)'); } }
هنا ، يشير width
height
إلى سمات width=“”
height=“”
في iframe في HTML. يمكن لـ JavaScript إجراء حساب (width/height)
، مما يعطينا نسبة العرض إلى الارتفاع ؛ ولتطبيقه بأي عرض ، سنقسم العرض الحالي لعنصر iframe على النسبة.
هذا له إيجاز ووضوح CSS ، وكل قوة JavaScript. لا توجد أغلفة إضافية مطلوبة ، ولا فئات إضافية ولا CSS إضافية.
كن حذرًا مع eval(')
، على الرغم من ذلك. هناك سبب لكون تعبيرات CSS تعتبر خطيرة في الماضي ، وهناك أيضًا سبب لتجربنا الفكرة. إذا لم تكن حريصًا على عدد العناصر التي تقوم بتطبيقها عليها على الصفحة أو مع تكرار إعادة حساب الأنماط ، فقد ينتهي الأمر بجافا سكريبت بتشغيل الأشياء مئات المرات أكثر مما تحتاجه. لحسن الحظ ، يتيح لنا EQCSS استدعاء EQCSS.apply()
أو EQCSS.throttle()
لإعادة حساب الأنماط يدويًا ، بحيث يكون لدينا المزيد من التحكم في وقت تحديث الأنماط.
منطقة الخطر!
يمكن أن تحدث مشكلات أخرى إذا قمت بإنشاء استعلامات بشروط أو أنماط متعارضة. تتم قراءة EQCSS ، مثل CSS ، من أعلى إلى أسفل باستخدام تسلسل هرمي للخصوصية. على الرغم من أن CSS هي لغة تعريفية ، إلا أنها تحتوي على بعض الميزات المتقدمة. إنه على بعد خطوتين فقط من أن تكون Turing-Complete كلغة برمجة. حتى الآن ، كان تصحيح أخطاء CSS أمرًا بسيطًا جدًا ، ولكن EQCSS يحول CSS من مجرد لغة توضيحية مفسرة إلى لغة نمط ديناميكية مع طبقة إضافية من التفسير بين CSS والمتصفح. تأتي مع هذه المنطقة الجديدة مجموعة متنوعة من المخاطر الجديدة المحتملة.
في ما يلي مثال على حلقة متبادلة في EQCSS ، وهو أمر تحصن استعلامات وسائط CSS العادية عنه حسب التصميم:
@element '.widget' and (min‐width: 300px) { $this { width: 200px; } }
أسمي هذا jekyll: hide;
CSS. ولكن بالإضافة إلى أسلوب واحد يحفز نفسه باستمرار ، هناك أيضًا إمكانية كتابة استعلامات متعددة تثير بعضها البعض ، في ما نسميه "حلقة متبادلة مزدوجة المقلوب" ، وهي الأكثر سوءًا على الإطلاق:
@element '.widget' and (min‐width: 400px) { $this { width: 200px; } } @element '.widget' and (max‐width: 300px) { $this { width: 500px; } }
من الناحية النظرية ، سيتم تعليق هذه الأداة المؤسفة في حلقة ، وتغيير حجمها بين 200 و 500 بكسل حتى نهاية الوقت ، غير قادر على الاستقرار على العرض. في مثل هذه الحالات ، يحسب EQCSS القواعد بالترتيب الذي تم تقييمها به ، ويمنح الفائز ويمضي قدمًا. إذا كنت ستعيد ترتيب الترتيب الذي تظهر به هذه القواعد ، فإن النمط الأخير سيفوز دائمًا إذا كانت ذات خصوصية متساوية.
يقول بعض الناس أن القدرة على إنشاء حلقات (أو حتى حلقات متبادلة مزدوجة معكوسة) هي عيب في التصميم ، ولكن من أجل منع الحلقات من أن تكون ممكنة ، ستحتاج إلى الحد من قوة EQCSS بطريقة من شأنها أن تزيل معظم القيمة التي يوفرها بناء الجملة. من ناحية أخرى ، يعد إنشاء حلقات لا نهائية في JavaScript أمرًا سهلاً للغاية ، لكن لا يُنظر إلى ذلك على أنه عيب في اللغة - بل يُنظر إليه على أنه دليل على قوتها! الأمر نفسه مع استعلامات العناصر.
استعلامات عنصر التصحيح
في الوقت الحالي ، يمكن أن يشبه تصحيح استعلامات العناصر إلى حد ما تصحيح أخطاء استعلامات الوسائط قبل أن يكون لدينا أدوات مثل مفتش الويب لإظهار الأنماط كما تم حسابها على الصفحة. في الوقت الحالي ، يتطلب تصحيح الأخطاء وتطوير استعلامات العناصر من المطور الاحتفاظ بنموذج عقلي لما يجب أن يحدث السلوك المتجاوب. في المستقبل ، قد يكون من الممكن إنشاء أدوات مطور مدرك لـ EQCSS ، ولكن حتى الآن ، فإن أدوات المطور في جميع المتصفحات الرئيسية تدرك فقط الأنماط التي طبقها EQCSS بالفعل على العناصر الموجودة في الصفحة ، وهم ليسوا على دراية بها الظروف المستجيبة التي يشاهدها EQCSS.
كيفية التصميم باستخدام استعلامات العنصر
إن أبسط طريقة للاستفادة من استعلامات العناصر هي تحويل التصميمات الحالية باستخدام استعلامات الوسائط إلى استعلامات عنصر ، وعناصر "تحرير" وأنماطها المتجاوبة من تخطيط واحد وتسهيل إعادة استخدام هذا الرمز في صفحات ومشاريع أخرى. قد يعني الاستعلام عن الوسائط واستعلام العنصر التالي نفس المعنى:
footer a { display: inline-block; } @media (max‐width: 500px) { footer a { display: block; } }
footer a { display: inline-block; } @element 'footer' and (max‐width: 500px) { $this a { display: block; } }
الفرق هو أنه في المثال الأصلي ، تظل روابط التذييل على شكل display: block
حتى يبلغ عرض المتصفح 500 بكسل على الأقل. سيبدو المثال الثاني ، باستخدام استعلامات العناصر ، كما هو ولكن فقط إذا كان عنصر footer
بعرض كامل.
بعد تحرير هذا النمط من استعلام الوسائط الأصلي الخاص به ، يمكننا الآن وضع التذييل في حاوية بأي عرض والتأكد من أنه عندما يحتاج التذييل إلى تطبيق النمط سريع الاستجابة (أي عندما يكون أضيق من 500 بكسل) ، فسيكون كذلك مطبق.
- تأكد من أن
EQCSS.js
موجود في HTML للمستند الوجهة. - استبدل
@media
بـ@element
في CSS. - أضف محدد CSS إلى نطاق كل استعلام
@element
. - اختياري: استبدل تكرارات العنصر المحدد النطاق بـ
$this
في استعلامات العناصر.
ما لم يكن مكون التصميم الذي تقوم بتحويله مصممًا في الأصل للعرض باستخدام العرض الكامل لإطار عرض المتصفح ، فمن المحتمل أن تضطر إلى تعديل نقاط التوقف بعد التحويل إلى استعلامات العناصر.
تجنب الانغلاق
تشبه تجربة تأليف أنماط EQCSS تجربة كتابة CSS العادية: لا تزال جميع خصائص وتقنيات CSS المفضلة لديك موجودة ، فقط مع بعض الميزات الإضافية التي تساعدهم على العمل معًا بطرق جديدة. نظرًا لأن EQCSS يخرج CSS قياسيًا إلى المتصفح ، فإن أي ميزة CSS يدعمها المستعرض لديك ستعمل عند استخدامها مع EQCSS. إذا تم تحديد ميزات ذات يوم مثل استعلامات العناصر وأنماط النطاق في CSS ودعمها في المتصفحات ، فستتمكن من البدء في استخدامها في رمز EQCSS الخاص بك على الفور ، مع الاستمرار في الاعتماد على EQCSS للميزات الأخرى التي لا يفعلها المتصفح بعد دعم أصلا.
نظرًا لأنه يمكنك استخدام بناء جملة EQCSS في كل من CSS مباشرةً وكذلك في البرنامج النصي الخاص به ، باستخدام text/eqcss
، إذا طور CSS في أي وقت بناء جملة لاستعلامات العناصر الأصلية ، فستظل قادرًا على تحميل EQCSS كبرنامج نصي وتجنب التعارضات .
بالنظر إلى المستقبل ، أحد الحلول التي يختبرها مطورو المستعرضات الآن هو Houdini ، والذي من شأنه أن يفتح الوصول لمطوري المكونات الإضافية لتوسيع CSS بطرق جديدة ، مثل إضافة دعم إلى المتصفح نفسه. في يوم من الأيام ، قد يكون من الممكن كتابة مكونات إضافية أكثر فاعلية تفسر بناء جملة EQCSS وتجلب هذه الميزات إلى المتصفحات بطريقة مباشرة وأداء أكثر مما تسمح به مكتبة JavaScript الحالية.
لذا ، هل يجب علينا الاستمرار في استخدام الاستعلامات الإعلامية؟
نعم ، على الرغم من أن استعلامات العناصر توفر العديد من الطرق الجديدة والمثيرة لاستهداف العناصر ذات الأنماط ، فإن استعلامات الوسائط (على الرغم من محدوديتها) ستعمل دائمًا بشكل أسرع في المتصفح مقارنة بالأسلوب الذي يعتمد على JavaScript للحساب. ومع ذلك ، فإن استعلامات وسائط CSS هي لأكثر من مجرد تصميم HTML للشاشات. تدعم استعلامات وسائط CSS أيضًا الاستعلامات المطبوعة والطرق الأخرى التي تعرض بها مواقع الويب المعلومات. يمكن استخدام EQCSS جنبًا إلى جنب مع استعلامات الوسائط لأشياء مثل أنماط الطباعة ، لذلك ليست هناك حاجة لإيقاف استعلام الوسائط لمجرد أنه يمكن الآن أيضًا استخدام استعلامات العناصر!
تصميم برؤية 20 20
أفضل شيء يمكننا القيام به لمستقبل CSS هو تجربة هذه الأفكار قدر الإمكان اليوم. لن يكون أي قدر من العصف الذهني والتنظير حول هذه الميزات مفيدًا مثل المحاولة الفعلية لتنفيذها واستخدامها ، واكتشاف التقنيات التي تجعلها مفيدة وقوية.
بالإضافة إلى توفير حل لاستعلامات العناصر ، نأمل أن يعمل EQCSS.js أيضًا كمنصة لتجارب أخرى في توسيع CSS. If you have an idea for a new responsive condition, a new CSS property or a new selector to use in your code, forking EQCSS.js and modifying it to include your idea can get you most of the way there with little effort.
Modular Design
In designing layouts using element queries, the biggest shift is learning how to stop viewing the DOM from the top down and from the perspective of only the root HTML element, and to start thinking about individual elements on the page from their own perspectives within the document.
The old paradigms of “desktop-first” and “mobile-first” responsive design aren't relevant any longer — the new way of building layouts approaches design “element-first.” Using element queries enables you to work on the individual parts that make up a layout, in isolation from one another, styling them to a greater level of detail. If you are using a modular approach for your back-end code already but have so far been unable to package your CSS with your modules because of the difficulties of styling with media queries alone, then element queries will finally allow you to modularize your styles in the same way.
Thinking Element-First
Element-first design is in the same spirit as the atomic design principle but looks different in practice from how most people have implemented atomic design in the past.
For example, let's say you have some HTML like the following, and the desired responsive behavior can be explained as, “The search input and button are displayed side by side until the form gets too narrow. Then, both the input and the button should be stacked on top of each other and displayed full width.”
<form> <input type=search> <input type=button value=Search> </form>
Desktop-First Approach
In a desktop-first mindset, you would write styles for the desktop layout first and then add responsive support for smaller screens.
input { width: 50%; float: left; } @media (max‐width: 600px) { input { width: 100%; float: none; } }
Mobile-First Approach
In a mobile-first mindset, you would design the mobile view first and add support for the side-by-side view only when the screen is wide enough.
input { width: 100%; } @media (min‐width: 600px) { input { width: 50%; float: left; } }
Element-First Approach
In the first two examples, the media breakpoint was set to 600 pixels, and not because that's how wide the inputs will be when they switch. Chances are, the search input is probably inside at least one parent element that would have margins or padding. So, when the browser is 600 pixels wide, those inputs might be somewhere around 550 or 525 pixels wide on the page. In a desktop-first or mobile-first approach, you're always setting breakpoints based on the layout and how elements show up within it. With an element-first layout, you're saying, “I don't care how wide the browser is. I know that the sweet spot for where I want the inputs to stack is somewhere around 530 pixels wide.” Instead of using a media query to swap that CSS based on the browser's dimensions, with element-first design, we would scope our responsive style to the form
element itself, writing a style like this:
input { width: 100% } @element 'form' and (min‐width: 530px) { $this input { width: 50%; float: left; } }
The code is similar to that of the two previous methods, but now we are free to display this search input anywhere — in a sidebar or full width. We can use it in any layout on any website, and no matter how wide the browser is, when the form itself doesn't have enough room to display the inputs side by side, it will adapt to look its best.
Resources For Getting Started
EQCSS-Enabled Template
<!DOCTYPE html> <html> <head> <meta charset="utf‐8"> <title></title> <style></style> </head> <body> <!‐‐[if lt IE 9]><script src="https://elementqueries.com/EQCSS‐polyfills.min.js"></script><![endif]‐‐> <script src="https://elementqueries.com/EQCSS.min.js"></script> </body> </html>
Demos
- Responsive Aspect Ratio
- Sticky Scroll Header
- Blockquote Style
- التقويم
- Content Demo
- Counting Children Demo
- Date Demo
- Zastrow-style Element Query Demo Demo
- Flyout Demo
- Headline Demo
- Media Player Demo
- Message Style Demo
- Modal Demo
- Nav Demo
- Parent Selector Demo
- Pricing Chart Demo
- Responsive Tables Demo
- Scroll-triggered Blocker Demo
- Signup Form Demo
- Testimonials Block Demo
- Tweet-Counter Demo
- JS Variables Demo
- Responsive Scaling Demo
- Geometric Design Demo
- Responsive Order Form
- Element Query Grid
- JS Functions in CSS
- Responsive Content Waterfall
قراءة متعمقة
You can find the EQCSS project on GitHub, demos, documentation and articles on the EQCSS website. An ever-growing number of Codepens use EQCSS, and you can create your own pen by forking the batteries-included template that comes hooked up with EQCSS. You can also play with the EQCSS tool that I built to preview if your EQCSS code is working as expected.
Happy hacking!