بواسطة كيليان فالخوف نشرت على
من فضلك لا تشعر بالعداء من عنوان هذا المقال. أنا لا أكره جافا سكريبت، أنا أحبها. أنا أكتب كميات كبيرة منه كل يوم. لكنني أيضًا أحب CSS، وأحبها أيضًا JSX لغة البرمجة. السبب الذي يجعلني أحب هذه التقنيات الثلاثة هو ما يسمى:
قاعدة القوة الأقل
إنه أحد المبادئ الأساسية لتطوير الويب ويعني أنه يجب عليك ذلك اختر اللغة الأقل قوة والمناسبة لغرض معين.
على الويب، يعني هذا تفضيل HTML على CSS، ثم CSS على JS. JS هي اللغة الأكثر تنوعًا من بين اللغات الثلاثة لأنك أنت من يصف كيفية عمل المتصفح، ولكنها يمكن أن تتعطل أيضًا، ويمكن أن يفشل التحميل ويتطلب موارد إضافية للتنزيل والتحليل والتشغيل. ومن السهل أيضًا استبعاد مستخدمي لوحة المفاتيح والأشخاص الذين يستخدمون التقنيات المساعدة معها.
على عكس JS، وهو أمر ضروري، فإن HTML وCSS تعريفيتان. أنت تقول للمتصفح ماذا للقيام به الآن كيف للقيام بذلك. وهذا يعني أن على المتصفح أن يختار كيفية القيام بذلك، ويمكنه القيام بذلك بأكثر الطرق الممكنة كفاءة.
نظرًا لأنه يتم التعامل مع ميزات HTML وCSS بواسطة المتصفح، فيمكن أن تكون أكثر أداءً وأكثر أصالة وأكثر قابلية للتكيف مع تفضيلات المستخدم وبشكل عام، أكثر سهولة في الوصول إليها. هذا لا يعني أنه سيكون كذلك دائمًا (خاصة عندما يتعلق الأمر بإمكانية الوصول) ولكن عندما يقوم المتصفح بالمهمة الثقيلة نيابةً عنك، سيحصل المستخدمون النهائيون بشكل عام على تجربة أفضل.
لكنني بحاجة إلى JS لذلك!
قد تفكر في “كل الأشياء التي أستخدم JS من أجلها، أنا يحتاج شبيبة ل”. قد يكون هذا صحيحًا، ولكن من الجيد معرفة أن صانعي المتصفحات وكتاب المواصفات قاموا بنقل الكثير من الوظائف إلى CSS وHTML التي كانت تحتاج إلى JS قبل بضع سنوات. وهذا ما يدور حوله هذا المقال.
الشيء الصعب في الويب هو أنه بمجرد أن تتعلم كيفية بناء شيء ما، لن يكون هناك أي سبب لتعلمه مرة أخرى. هذا هو العقد المبرم بيننا: الويب متوافق مع الإصدارات السابقة. (تنطبق استثناءات قليلة جدًا، لكن صفحة الويب الأولى لا تزال تعمل بشكل جيد في جميع المتصفحات الحديثة.)
وهذا يعني أيضًا أن الحل الذي تعلمته مرة واحدة يصبح جزءًا من صندوق الأدوات الخاص بك، ويمكنك الاستمرار في إعادة تنفيذه وسيظل يعمل في كل مرة. لذا فإن الأمثلة التي سأقدمها أدناه رائعة (ولهذا السبب أدرجتها) ولكن ما أريدك أن تستخلصه من هذه المقالة هو أنه فقط لأنك يعرف شيء يحتاج إلى جافا سكريبت، لا يعني أنه لا يزال يحتاج. يمكنك إنشاء مواقع ويب أفضل إذا قمت باختبار هذه الافتراضات بين الحين والآخر.
مفاتيح مخصصة
سنبدأ هذه المقالة بشيء كان علينا جميعًا تنفيذه في مرحلة ما، وهو المفاتيح المخصصة. بدلاً من استخدام مربع اختيار عادي، يستدعي التصميم مفتاحًا جميل المظهر. بدلاً من التوصل إلى حل JS باستخدام divs ومعالجات onclick والحالة الداخلية، سنستفيد من مربع الاختيار العادي و :checked
الطبقة الزائفة. إليك HTML الذي سنستخدمه:
<label>
<input type="checkbox" />
My awesome feature
label>
يوجد عنصر تسمية، وبداخله مربع اختيار. والشيء الجميل في هذا هو أن المتصفح يقوم بالفعل بأشياء لنا. نظرًا لأن الإدخال موجود داخل الملصق، فقد ربطه المتصفح ويمكننا الآن النقر في أي مكان على الملصق لتبديل مربع الاختيار، ولا يوجد معالج عند النقر في الأفق. المتصفح يعطينا هذا مجانا. من ناحية الميزات، لقد انتهينا.
بالطبع، قد لا يعجب المصممين بالطريقة التي يبدو بها هذا ونريد إنشاء مفتاح مخصص رائع المظهر. لذلك دعونا نضيف مجموعة من CSS:
input {
appearance: none;
position: relative;
display: inline-block;
background: lightgrey;
height: 1.65rem;
width: 2.75rem;
vertical-align: middle;
border-radius: 2rem;
box-shadow: 0px 1px 3px #0003 inset;
transition: 0.25s linear background;
}
input::before {
content: "";
display: block;
width: 1.25rem;
height: 1.25rem;
background: #fff;
border-radius: 1.2rem;
position: absolute;
top: 0.2rem;
left: 0.2rem;
box-shadow: 0px 1px 3px #0003;
transition: 0.25s linear transform;
transform: translateX(0rem);
}
جميع تفاصيل التصميم هنا لا تهم كثيرًا، ولكن أريدك أن تلقي نظرة على القاعدة الأولى: appearance: none
.
عناصر النموذج، جنبًا إلى جنب مع الصور، هي ما يسمى “المحتوى المستبدل”. وهذا يعني أنها ليست في الواقع جزءًا من HTML الخاص بك، ولكن يتم توفيرها بواسطة المتصفح. عندما يعرض المتصفح HTML الخاص بك ويعثر على محتوى تم استبداله، فإنه يترك مربعًا له، ثم يستبدل هذا المربع بالمحتوى الفعلي. ولهذا السبب، على سبيل المثال، لا يمكن أن تحتوي الصور وعناصر النموذج على عناصر زائفة: يتم استبدالها عندما يستبدل المتصفح العنصر بأكمله.
appearance
هي طريقة لإخبار المتصفح بالتوقف عن القيام بذلك. إنه يخبر المتصفح: “شكرًا، ولكنني أريد تصميم التحكم في النموذج الخاص بي”. وهذا يسمح بعد ذلك باستخدام ::before
عنصر زائف. أصبح الإدخال نفسه الآن خلفية لمفتاحنا، و ::before
العنصر الزائف هو النقطة الصغيرة الموجودة بداخله والتي تقوم بالتبديل.
يؤدي النقر فوق هذا إلى استمرار تحديد خانة الاختيار وإلغاء تحديدها، ولكن لأننا استبدلنا العنصر، نحتاج إلى القيام بعمل جعل ذلك مرئيًا بأنفسنا. هذا هو المكان الذي :checked
الطبقة الزائفة تأتي في:
:checked {
background: green;
}
:checked::before {
transform: translateX(1rem);
}
عند النقر فوق خانة الاختيار، ذلك :checked
تبدأ الفئة الزائفة في التطابق مما يؤدي إلى تحديث التصميم.
لذا، لدينا محول مخصص ذو مظهر رائع يستخدم عناصر HTML الأصلية وقليلًا من CSS، لكننا لم ننته بعد. بينما بالنسبة لمستخدمي الماوس، فمن الواضح تمامًا التحكم في النموذج الذي يتفاعلون معه (نظرًا لأنهم يشيرون إليه وينقرون)، أما بالنسبة للأشخاص الذين يستخدمون لوحة المفاتيح، فإن الأمر ليس بهذه السهولة.
أنا متأكد من أنك على دراية بهذا الجزء من CSS. للتخلص من هذا المخطط القبيح المنقط الذي يشبه الصندوق.
input:focus {
outline: none;
}
إذا كنت تقرأ هذا، فاعلم أن هذه ليست فكرة جيدة. ولكن كيف نجعلها تبدو أجمل؟ هنا أيضًا تم تحديث المتصفحات لتحسين الأمور بالنسبة لنا. ال outline
يتبع الآن نصف القطر الحدودي للعنصر، ويمكننا أيضًا إزاحته بعيدًا عن العنصر أو داخله:
input:focus-visible {
outline: 2px solid dodgerblue;
outline-offset: 2px;
}
الآن، عندما يتفاعل المستخدم مع عنصر ما باستخدام لوحة المفاتيح (يمكنك محاولة الضغط على شريط المسافة بعد النقر عليه، أو النقر عليه)، :focus-visible
سوف يتطابق (لن يحدث ذلك عند استخدام الماوس) وسيحصلون على مخطط أزرق جميل المظهر قليلاً حول العنصر.
وأخيرا، أريد منك أن تحل محل ذلك outline: none
بشيء آخر:
input:focus {
outline-color: transparent;
}
سيكون لهذا نفس النتيجة: بدلاً من عدم ظهور المخطط التفصيلي لأنه مخفي، فإنه غير مرئي لأنه شفاف. بالنسبة للمستخدمين الذين لديهم وضع التباين العالي (وتسمى أيضًا الألوان القسرية) قيد التشغيل، يصبح هذا المخطط التفصيلي مرئيًا مرة أخرى لأنه في وضع التباين العالي، يتم استبدال هذا اللون الشفاف باللون الذي اختاره المستخدم، مما يساعدهم على رؤية ما يتفاعلون معه حتى إذا كانوا يستخدمون الماوس.
هذه المقالة ليست طويلة بما يكفي للتطرق أيضًا إلى ما تفعله الألوان القسرية، ولكن إذا كنت تريد معرفة المزيد، فراجع مقالتي وأوضح الألوان القسرية.
Datalist، اقتراح تلقائي أصلي
بدلا من التثبيت $your-framework-autosuggest
، جرب datalist في مشروعك القادم. Datalist هي طريقة مدمجة في المتصفح لعرض قائمة من الخيارات أثناء قيام المستخدم بالكتابة في أحد الإدخالات.
<input list="frameworks" />
<datalist id="frameworks">
<option>Bootstrapoption>
<option>Tailwind CSSoption>
<option>Foundationoption>
<option>Bulmaoption>
<option>Skeletonoption>
datalist>
لاستخدامه، يمكنك إضافة عنصر datalist بمعرف ومجموعة من الخيارات إلى HTML الخاص بك. لا تقلق، العنصر لن يكون مرئيًا. ثم تستخدم list
السمة على مدخلات لربط الاثنين.
عندما يقوم المستخدم الآن بالكتابة في الإدخال، سيعرض المتصفح قائمة البيانات كقائمة منسدلة، مما يؤدي إلى تصفية الخيارات تلقائيًا أثناء قيام المستخدم بالكتابة. نظرًا لأنه إدخال عادي، لا يزال لدى المستخدمين خيار كتابة القيمة الخاصة بهم. وأخيرًا، يمكنهم رؤية جميع الخيارات عن طريق تحديد الإدخال واستخدام مفاتيح الأسهم للتنقل في القائمة، أو النقر فوق رمز القائمة المنسدلة الذي يضيفه المتصفح.
منتقي الألوان الذي يفعل المزيد
هناك الكثير من أدوات التقاط الألوان ذات المظهر الجيد، مع واجهات مستخدم قماشية جميلة وشرائح تمرير تم إنشاؤها باستخدام 100 سطر من JavaScript. ولكن هل تعلم أنه يمكنك أيضًا استخدام منتقي الألوان الأصلي؟
<label> <input type="color" /> Color label>
يمنحك هذا السطر الفردي من HTML أيضًا منتقي الألوان بواجهة مستخدم لطيفة، مما يوفر لك بالفعل مجموعة من JS. ولكن لأننا نسمح للمتصفح بالتعامل معه، فإننا نحصل في الواقع على المزيد من الوظائف مجانًا. في متصفحات Chromium، يتيح لك منتقي الألوان الأصلي أيضًا اختيار لون، ليس فقط من موقعك الخاص ولكن من أي مكان على الشاشة. أنيق جدا!
ملاحظة سريعة هنا هي أنه على الرغم من أن المتصفحات تعرض منتقي ألوان لطيفًا، فقد لا يتمكن جميع المستخدمين من استخدامه. لذا فإن تقديم طريقة مختلفة لاختيار اللون (مثل إدخال النص العادي) لا يزال فكرة جيدة.
الأكورديون
تعد الأكورديون طريقة رائعة لجعل الصفحة التي تحتوي على الكثير من المحتوى أكثر تنظيمًا ومرتبة عن طريق إبعاد المحتوى عن الطريق حتى يحتاجه المستخدم. والمتصفحات تمنحك إياها مجانًا مع details
و summary
عناصر:
<details>
<summary>My accordionsummary>
<p>My accordion contentp>
details>
بلدي الأكورديون
محتوى الأكورديون الخاص بي
بشكل افتراضي، كل شيء داخل ملف details
العنصر مخفي باستثناء summary
. ثم عندما ينقر المستخدم على summary
العنصر سيعرض المتصفح بقية المحتوى.
ما ستراه غالبًا هو أن أحد عناصر الأكورديون مفتوح بالفعل، والباقي مغلق. يمكنك أن تفعل ذلك مع open
يصف:
<details open>
<summary>My accordionsummary>
<p>My accordion contentp>
details>
بلدي الأكورديون
محتوى الأكورديون الخاص بي
إذا كنت قادمًا من عالم React، فقد تنظر إلى هذا الكود وتفكر “حسنًا، هذا رائع، الآن لديه open
support ولن يتم إغلاقه بعد الآن” ولكن لحسن الحظ، هذا ليس هو الحال. الذي – التي open
السمة هي حالة البداية فقط، وسيتم تحديثها عندما يتفاعل المستخدم مع الأكورديون.
عندما يتعلق الأمر بالتصميم، فإن details
لقد قمت بتغطية العنصر أيضًا. هذا المثلث الصغير (الذي سيرغب مصممك في استبداله فور رؤيته) هو أ ::marker
عنصر زائف يمكنك تصميمه:
summary::marker {
font-size: 1.5em;
content: "📬";
}
[open] summary::marker {
font-size: 1.5em;
content: "📭";
}
بلدي الأكورديون
محتوى الأكورديون الخاص بي
ضع في اعتبارك أن تغيير المحتوى يمكن أن يؤثر على كيفية إعلان التقنيات المساعدة عن الأكورديون الخاص بك. اقرأ مقال مانويل حول ذلك هنا: التفاصيل/التناقضات الموجزة.
لا يمكن تصميم عنصر العلامة الزائف على نطاق واسع مثل العناصر الأخرى (العديد من خصائص CSS لا تعمل عليه، مثل وضعه في مكان مختلف تمامًا)، ولكن يمكنك استبدال محتواه، على سبيل المثال، برموز تعبيرية، أو تعيين لون الخلفية أو الصورة وتغيير حجم الخط.
مع ال open
السمة التي يمكنك منحها بسهولة تصميمًا مختلفًا عن الحالة المغلقة.
وأخيرًا، نريد أن نفعل شيئًا حيال عنصر التلخيص هذا. إنه قابل للنقر عليه، ولكنه على عكس الرابط لا يحتوي على مؤشر، وعلى عكس الزر، فهو لا يبدو كزر. لذلك أعتقد أننا يجب أن نضيف إليها حالة التمرير والتركيز ونساعد زوارنا على إدراك أنها قابلة للنقر عليها:
summary:hover,
summary:focus {
cursor: pointer;
background: deeppink;
}
بلدي الأكورديون
محتوى الأكورديون الخاص بي
أنا أتجنب مناقشة “الروابط الوحيدة التي يجب أن تحتوي على مؤشرات مؤشر” هنا، والنقطة الرئيسية التي أطرحها هي ما عليك القيام به شئ ما.
مشروط الحوار
في بعض الأحيان تحتاج إلى إبلاغ المستخدم بشيء ما، أو سؤاله عن شيء ما أو إقناعه بتأكيد شيء ما. في جافا سكريبت، هذا ما alert()
, prompt()
و confirm()
يفعل. لكن لديهم جانبًا سلبيًا كبيرًا جدًا: فهم يقومون بقفل الموضوع الرئيسي، مما يعني أن صفحتك لا يمكنها فعل أي شيء آخر. كما أنها متوافقة مع المتصفح، لذا لا يمكنك تصميمها لتتناسب مع تصميمك.
يتطلب إنشاء مربع الحوار الخاص بك أيضًا مشكلة: تحتاج إلى إبقاء التركيز داخل مربع الحوار لإمكانية الوصول، والإعلان عن نمطه، والتأكد من عدم تمكن المستخدمين من الخروج منه عن طريق الخطأ، وسيتعين عليك القتال مع أي أداة دردشة مشغولة الفهرس z لـ 2147483647 (إذا كنت تعلم فأنت تعلم).
ولهذا السبب تأتي المتصفحات الآن مزودة بعنصر حوار أصلي:
<dialog>
<form method="dialog">
<h3>This is a pretty dialogh3>
<button type="submit">Closebutton>
form>
dialog>
لا يتم عرض هذا العنصر افتراضيًا، وفي الوقت الحالي، سأقوم بالغش قليلًا واستخدام JavaScript:
document.querySelector("button").addEventListener("click", () => {
document.querySelector("dialog").showModal();
});
هناك الآن تغييرات في الأعمال ستتيح لك فتح مربعات حوار بدون JavaScript، لكنها لم يتم تحديدها بالكامل بعد، ناهيك عن تنفيذها. لذا، نحتاج الآن إلى استخدام JavaScript لفتح مربع الحوار. ولكن هذا كل شيء، والباقي هو HTML وCSS الأصلي.
يحتوي عنصر الحوار على showModal()
الوظيفة التي يعرضها ومعها تفتح مربع الحوار. يتم فتح مربع الحوار هذا على شيء يسمى top-layer
وهو مفهوم جديد في المتصفحات. للحصول على كتاب تمهيدي، راجع الشرح على MDN: الطبقة العليا.
الطبقة العليا عبارة عن طبقة جديدة منفصلة عن HTML الخاص بك، ويمكنك “ترويج” العناصر إليها. وهذا يعني أن العناصر الموجودة في الطبقة العليا ستكون دائمًا فوق كل شيء آخر ، بغض النظر عن الفهرس z للعنصر وتداخل سياق التراص.
والآن بعد أن أصبح مفتوحًا، قد تلاحظ أن المتصفح لا يوفر لك أي واجهة مستخدم. يعد مربع الحوار عبارة عن div إلى حد كبير (وليس زرًا!) والأمر متروك لك لتوفير واجهة المستخدم للإغلاق. هذا ما يفعله النموذج الموجود في الكود أعلاه. ربما لاحظت أن لديها طريقة “الحوار”. عندما يتم إرسال هذا النموذج، يأخذ المتصفح ذلك كإشارة لإغلاق مربع الحوار مرة أخرى.
مع ذلك، يمكنك أيضًا إنشاء مربعات حوار التأكيد من خلال توفير زرين، لكل منهما قيمه الخاصة:
<dialog>
<form method="dialog">
<p>Tabs or spaces?p>
<button type="submit" value="wrong">Tabsbutton>
<button type="submit" value="correct">Spacesbutton>
form>
dialog>
يمكن العثور على الزر الذي نقر عليه المستخدم من خلال الاستماع إلى close
الحدث في مربع الحوار وقراءة خاصية “returnValue”:
dialog.addEventListener("close", function () {
console.log(dialog.returnValue);
});
إذا كان لديك أي بيانات نموذج أخرى هناك، فيمكنك أيضًا قراءتها باسم formData
.
نظرًا لأن مربع الحوار عبارة عن div في الأساس فيما يتعلق بتصميمه، فيمكنك تصميمه بالطريقة التي تريدها. سيقوم المتصفح تلقائيًا بوضعه في منتصف الشاشة لك، ولكن كل شيء آخر متروك لك.
يأتي الحوار أيضًا مع عنصر زائف جديد يسمى ::backdrop
. هذه هي الطبقة التي تقع بين مربع الحوار وبقية الصفحة، ويمكنك تصميمها لتعتيم بقية الصفحة على سبيل المثال أو توجيه انتباه المستخدمين إلى مربع الحوار. على سبيل المثال، يمكنك تراكب طبقة بيضاء وطمس الصفحة:
dialog::backdrop {
background: #fff5;
backdrop-filter: blur(4px);
}
تمامًا مثل عنصر الحوار نفسه، يتم تحديد موضع الخلفية بواسطة المتصفح، لذلك لن تحتاج إلى القلق بشأن التمرير والعناصر الثابتة وتغيير حجم المتصفح. كل هذا يتم التعامل معه من خلال المتصفح.
في الختام
أتمنى أن تجد بعض الأشياء في هذه المقالة التي جعلتك تدرك أنه يمكنك استخدام كمية أقل قليلاً من جافا سكريبت في مشروعك التالي. كلما قمت بتغيير تطبيق معروف تم اختباره في المعركة إلى شيء جديد، فمن الجيد اختباره، خاصة عندما يتعلق الأمر بإمكانية الوصول، للتأكد من أنك لا تستبعد أي شخص.
هناك العشرات من الأمثلة الأخرى التي كان بإمكاني إضافتها إلى هذه المقالة، إليك بعض الأمثلة التي يمكنك الاطلاع عليها:
- التمرير السلس الأصلي مع
scroll-behavior: smooth
(ولكن فقط عندماprefers-reduced-motion: no preference
اعواد الكبريت!)، - دوارات أصلية مع أداة التمرير المفاجئة،
- عناصر “في العرض” مع
position: sticky
- …عدم ذكر المفهوم الكامل لاستعلامات الحاوية.
وإذا نظرنا إلى المستقبل، فسنحصل على المزيد من الأشياء الرائعة:
- انتقل الرسوم المتحركة مدفوعة
- تخطيطات البناء بدون masonry.js ولكن مع
grid-template-rows: masonry
- تصميم أنيق بالكامل
select
مع الجديدselectlist
العنصر (حيث يمكنك تصميم كل جزء من التحديد دون تدمير جميع الوظائف الأصلية التي تأتي معه) - ال
:has()
المحدد الذي سيؤدي إلى إزالة فئة كاملة من اختيار JS
هذه المقالة مقتبسة من محاضرة ألقيتها في مؤتمر والتي تتناول المزيد من التفاصيل حول هذه المواضيع وغيرها، ويمكنك مشاهدتها هنا: توقف عن استخدام JavaScript لذلك: نقل الميزات من JS إلى CSS وHTML.
لذلك اسمحوا لي أن أكرر النقطة الرئيسية في هذه المقالة:
فقط لأنك يعرف شيء يحتاج إلى جافا سكريبت، لا يعني أنه لا يزال يحتاج. يمكنك إنشاء مواقع ويب أفضل إذا قمت باختبار هذه الافتراضات بين الحين والآخر.
عن كيليان فالخوف
مطور ويب ومنشئ Polypane.app، المتصفح للمطورين.
مدونة: kilianvalkhof.com
المستودون: @ كيليان
العاشر: @kilianvalkhof
بوليبان: Polypane.app