نظرة عامة أساسية حول كيفية إنشاء مكوّن إعدادات لأشرطة التمرير ومربّعات الاختيار
في هذه المشاركة، أريد مشاركة أفكاري حول إنشاء مكوّن "الإعدادات" للويب يكون متجاوبًا ويتيح إدخالات متعددة للأجهزة ويعمل على جميع المتصفّحات. جرِّب العرض التوضيحي.
إذا كنت تفضّل مشاهدة فيديو أو تريد معاينة واجهة المستخدم/تجربة المستخدم لما ننشئه، إليك دليل إرشادي أقصر على YouTube:
نظرة عامة
لقد قسّمت جوانب هذا المكوّن إلى الأقسام التالية:
التنسيقات
هذا هو أول عرض توضيحي في تحدّي واجهة المستخدم الرسومية (GUI) يستخدم شبكة CSS بالكامل. في ما يلي كل شبكة مميّزة باستخدام أدوات مطوّري البرامج في Chrome للشبكة:

Just for gap
التنسيق الأكثر شيوعًا:
foo {
display: grid;
gap: var(--something);
}
أسمّي هذا التنسيق "للفجوات فقط" لأنّه يستخدم الشبكة فقط لإضافة فجوات بين الوحدات.
تستخدم خمسة تنسيقات هذه الاستراتيجية، وفي ما يلي جميعها:

يستخدم العنصر fieldset، الذي يحتوي على كل مجموعة إدخال (.fieldset-item)، السمة gap: 1px لإنشاء حدود رفيعة بين العناصر. لا داعي للقلق بشأن الحدود!
.grid { display: grid; gap: 1px; background: var(--bg-surface-1); & > .fieldset-item { background: var(--bg-surface-2); } }
.grid { display: grid; & > .fieldset-item { background: var(--bg-surface-2); &:not(:last-child) { border-bottom: 1px solid var(--bg-surface-1); } } }
التفاف الشبكة الطبيعي
كان التنسيق الأكثر تعقيدًا هو التنسيق الكلي، وهو نظام التنسيق المنطقي بين <main> و<form>.
توسيط المحتوى الملتف
يتيح كل من Flexbox وGrid إمكانية align-items أو
align-content، وعند التعامل مع عناصر الالتفاف، ستوزّع محاذاة تنسيق content
المساحة بين العناصر الثانوية كمجموعة.
main {
display: grid;
gap: var(--space-xl);
place-content: center;
}
يستخدم العنصر الرئيسي place-content: center اختصار المحاذاة بحيث يتم توسيط العناصر الفرعية عموديًا وأفقيًا في كل من تخطيطات العمود الواحد والعمودين.
شاهِد في الفيديو أعلاه كيف يبقى "المحتوى" في الوسط، على الرغم من حدوث التفاف.
تكرار الضبط التلقائي للحد الأدنى والأقصى
يستخدم <form> تنسيق شبكة تكيُّفي لكل قسم.
يتحوّل هذا التنسيق من عمود واحد إلى عمودَين استنادًا إلى المساحة المتاحة.
form {
display: grid;
gap: var(--space-xl) var(--space-xxl);
grid-template-columns: repeat(auto-fit, minmax(min(10ch, 100%), 35ch));
align-items: flex-start;
max-width: 89vw;
}
تحتوي هذه الشبكة على قيمة مختلفة لـ row-gap (--space-xl) عن column-gap (--space-xxl)
لإضافة هذه اللمسة المخصصة على التخطيط سريع الاستجابة. عندما تتراكم الأعمدة، نريد فجوة كبيرة، ولكن ليس بحجم ما إذا كنا على شاشة عريضة.
تستخدم السمة grid-template-columns ثلاث دوال CSS، وهي: repeat() وminmax() وmin(). نشرت أونا كرافيتس منشورًا رائعًا على مدونتها حول التنسيق، وأطلقت عليه اسم RAM.
هناك 3 إضافات خاصة في التنسيق، إذا قارنته بتنسيق "أونا":
- نمرّر دالة
min()إضافية. - نحدّد
align-items: flex-start. - يتوفّر نمط واحد (
max-width: 89vw).
يقدّم "إيفان مينتو" شرحًا وافيًا للدالة min() الإضافية في مدونته في المنشور شبكة CSS المتجاوبة بطبيعتها مع minmax() وmin().
أنصحك بقراءة هذا المنشور. تصحيح المحاذاة flex-start هو
إزالة تأثير التمدد التلقائي، بحيث لا تحتاج العناصر الفرعية لهذا التخطيط
إلى ارتفاعات متساوية، يمكن أن يكون لها ارتفاعات طبيعية وجوهرية. يتضمن فيديو على YouTube تفصيلاً سريعًا لإضافة المحاذاة هذه.
يستحق "max-width: 89vw" شرحًا موجزًا في هذا المنشور.
دعني أريك التخطيط مع تطبيق النمط وبدونه:
ماذا يحدث؟ عند تحديد max-width، يتم توفير سياق
أو حجم صريح أو حجم
محدّد لخوارزمية التنسيق
auto-fit لمعرفة عدد
التكرارات التي يمكن أن تتسع لها المساحة. على الرغم من أنّه يبدو واضحًا أنّ المساحة هي "العرض الكامل"، يجب توفير حجم محدّد أو الحد الأقصى للحجم وفقًا لمواصفات شبكة CSS. لقد قدّمتُ الحد الأقصى للحجم.
إذًا، لماذا 89vw؟ لأنّها "نجحت" في تنسيقي.
أنا وبعض الزملاء الآخرين في فريق Chrome نحقّق في سبب عدم كفاية قيمة أكثر منطقية،
مثل 100vw، وما إذا كان هذا في الواقع خطأ.
المسافات
غالبية تناغم هذا التخطيط من لوحة محدودة من التباعد، 7 على وجه الدقة.
:root {
--space-xxs: .25rem;
--space-xs: .5rem;
--space-sm: 1rem;
--space-md: 1.5rem;
--space-lg: 2rem;
--space-xl: 3rem;
--space-xxl: 6rem;
}
يتوافق استخدام هذه الميزة بشكل جيد مع الشبكة وCSS @nest وبنية المستوى 5 من @media. إليك مثال على مجموعة أنماط التنسيق <main> بالكامل.
main {
display: grid;
gap: var(--space-xl);
place-content: center;
padding: var(--space-sm);
@media (width >= 540px) {
& {
padding: var(--space-lg);
}
}
@media (width >= 800px) {
& {
padding: var(--space-xl);
}
}
}
شبكة تتضمّن محتوى في الوسط، مع مساحة متروكة معتدلة تلقائيًا (كما هو الحال على الأجهزة الجوّالة) ولكن مع توفر مساحة أكبر في إطار العرض، ينتشر عن طريق زيادة المساحة المتروكة. 2021 CSS is looking pretty good!
هل تتذكر التخطيط السابق، "فقط للفجوة"؟ في ما يلي نسخة أكثر اكتمالاً من كيفية ظهورها في هذا المكوّن:
header {
display: grid;
gap: var(--space-xxs);
}
section {
display: grid;
gap: var(--space-md);
}
اللون
ساعد الاستخدام المتحكّم فيه للألوان في إبراز هذا التصميم على أنّه معبّر وبسيط. أفعل ذلك على النحو التالي:
:root {
--surface1: lch(10 0 0);
--surface2: lch(15 0 0);
--surface3: lch(20 0 0);
--surface4: lch(25 0 0);
--text1: lch(95 0 0);
--text2: lch(75 0 0);
}
أُسمّي ألوان السطح والنص بأرقام بدلاً من أسماء مثل
surface-dark وsurface-darker لأنّه في الاستعلام عن الوسائط، سأقلبها
ولن يكون للون الفاتح والداكن أي معنى.
أقلبها في الاستعلام عن الوسائط المفضّل مثل هذا:
:root {
...
@media (prefers-color-scheme: light) {
& {
--surface1: lch(90 0 0);
--surface2: lch(100 0 0);
--surface3: lch(98 0 0);
--surface4: lch(85 0 0);
--text1: lch(20 0 0);
--text2: lch(40 0 0);
}
}
}
من المهم إلقاء نظرة سريعة على الصورة العامة والاستراتيجية قبل التعمّق في تفاصيل بنية الألوان. ولكن، بما أنّني سبقت الأحداث قليلاً، دعوني أعود إلى الوراء قليلاً.
LCH؟
بدون التعمّق في نظرية الألوان، LCH هي بنية موجّهة نحو الإنسان، تراعي كيفية إدراكنا للألوان، وليس كيفية قياس الألوان باستخدام العمليات الحسابية (مثل 255). وهذا يمنحها ميزة واضحة حيث يمكن للبشر كتابتها بسهولة أكبر وسيكون البشر الآخرون متناغمين مع هذه التعديلات.
في هذا العرض التوضيحي، سنركّز على البنية والقيم التي أبدّلها لإنشاء المظهرَين الفاتح والداكن. لنلقِ نظرة على لون سطح واحد ولون نص واحد:
:root {
--surface1: lch(10 0 0);
--text1: lch(95 0 0);
@media (prefers-color-scheme: light) {
& {
--surface1: lch(90 0 0);
--text1: lch(40 0 0);
}
}
}
تتم ترجمة --surface1: lch(10 0 0) إلى 10% من الإضاءة و0 من صفاء اللون و0 من تدرّج اللون: رمادي داكن جدًا عديم اللون. بعد ذلك، في الاستعلام عن الوسائط للوضع الفاتح، يتم قلب الإضاءة إلى 90% باستخدام --surface1: lch(90 0 0);. وهذا هو جوهر الاستراتيجية. ابدأ بتغيير الإضاءة بين المظهرَين، مع الحفاظ على نِسب التباين التي يتطلّبها التصميم أو التي يمكنها الحفاظ على سهولة الاستخدام.
تكمن ميزة lch() في أنّ الإضاءة موجّهة نحو المستخدم، ويمكننا الشعور بالرضا تجاه تغييرها بمقدار %، لأنّها ستكون مختلفة بمقدار % من حيث الإدراك والاتساق. على سبيل المثال، hsl() ليست
موثوقة.
يمكنك الاطّلاع على مزيد من المعلومات حول الفضاءات اللونية و"lch()" إذا أردت. ستتوفّر قريبًا.
لا يمكن لـ CSS حاليًا الوصول إلى هذه الألوان على الإطلاق. أكرر: لا يمكننا الوصول إلى ثلث الألوان في معظم الشاشات الحديثة. وهذه ليست مجرد ألوان عادية، بل هي الألوان الأكثر حيوية التي يمكن للشاشة عرضها. تظهر مواقعنا الإلكترونية باهتة لأنّ أجهزة الشاشات تطوّرت بشكل أسرع من مواصفات CSS وعمليات تنفيذ المتصفّحات.
ليا فيرو
عناصر تحكّم في النماذج التكيّفية مع نظام الألوان
توفّر العديد من المتصفّحات عناصر تحكّم في المظهر الداكن، مثل Safari وChromium حاليًا، ولكن عليك تحديد أنّ تصميمك يستخدمها في CSS أو HTML.
يوضّح ما سبق تأثير السمة من لوحة "الأنماط" في "أدوات مطوّري البرامج". يستخدم العرض التوضيحي علامة HTML، والتي في رأيي هي بشكل عام موقع أفضل:
<meta name="color-scheme" content="dark light">
يمكنك الاطّلاع على كل المعلومات حول هذا الموضوع في هذه color-scheme
المقالة التي كتبها توماس
شتاينر. هناك الكثير مما يمكن كسبه
أكثر من مدخلات مربعات الاختيار المظلمة!
خدمة مقارنة الأسعار (CSS) "accent-color"
تم تسجيل نشاط
حديث حول
accent-color في عناصر النماذج، وهو نمط CSS واحد يمكنه تغيير
درجة اللون المستخدَمة في عنصر الإدخال في المتصفّحات. يمكنك الاطّلاع على مزيد من المعلومات هنا على GitHub. لقد أدرجته في الأنماط
الخاصة بهذا المكوّن. بما أنّ المتصفّحات تتيح استخدام هذه السمة، ستكون مربّعات الاختيار
أكثر تناسقًا مع المظهر العام من خلال استخدام اللونَين الوردي والبنفسجي.
input[type="checkbox"] {
accent-color: var(--brand);
}

تأثيرات البقع الملوّنة مع تدرّجات ثابتة وتركيز داخلي
يبرز اللون أكثر عندما يتم استخدامه باعتدال، وإحدى الطرق التي أحب تحقيقها هي من خلال تفاعلات واجهة المستخدم الملونة.
هناك العديد من طبقات الملاحظات والتفاعل في واجهة المستخدم في الفيديو أعلاه، والتي تساعد في إضفاء طابع شخصي على التفاعل من خلال:
- تسليط الضوء على السياق
- تقديم ملاحظات حول واجهة المستخدم بشأن "مدى اكتمال" القيمة في النطاق
- تقديم ملاحظات حول واجهة المستخدم تفيد بأنّ الحقل يقبل الإدخال
لتقديم ملاحظات عند التفاعل مع عنصر، تستخدم CSS الفئة الزائفة
:focus-within
لتغيير مظهر العناصر المختلفة، لنحلّل
.fieldset-item، إنّها مثيرة للاهتمام:
.fieldset-item {
...
&:focus-within {
background: var(--surface2);
& svg {
fill: white;
}
& picture {
clip-path: circle(50%);
background: var(--brand-bg-gradient) fixed;
}
}
}
عندما يكون التركيز على أحد العناصر الثانوية لهذا العنصر:
- يتم تخصيص لون سطح ذي تباين أعلى لخلفية
.fieldset-item. - يتم ملء
svgالمتداخل باللون الأبيض لزيادة التباين. - يتوسّع
<picture>clip-pathالمتداخل ليصبح دائرة كاملة، وتمتلئ الخلفية بالتدرج الثابت الساطع.
نطاق مخصّص
بالنظر إلى عنصر إدخال HTML التالي، سأوضح لك كيف قمت بتخصيص مظهره:
<input type="range">
هناك 3 أجزاء في هذا العنصر نحتاج إلى تخصيصها:
أنماط عناصر النطاق
input[type="range"] {
/* style setting variables */
--track-height: .5ex;
--track-fill: 0%;
--thumb-size: 3ex;
--thumb-offset: -1.25ex;
--thumb-highlight-size: 0px;
appearance: none; /* clear styles, make way for mine */
display: block;
inline-size: 100%; /* fill container */
margin: 1ex 0; /* ensure thumb isn't colliding with sibling content */
background: transparent; /* bg is in the track */
outline-offset: 5px; /* focus styles have space */
}
الأسطر القليلة الأولى من CSS هي الأجزاء المخصّصة من الأنماط، وآمل أن يساعد تصنيفها بوضوح. بقية الأنماط هي في الغالب أنماط إعادة ضبط، لتوفير أساس متسق لإنشاء الأجزاء الصعبة من المكوّن.
تتبُّع الأنماط
input[type="range"]::-webkit-slider-runnable-track {
appearance: none; /* clear styles, make way for mine */
block-size: var(--track-height);
border-radius: 5ex;
background:
/* hard stop gradient:
- half transparent (where colorful fill we be)
- half dark track fill
- 1st background image is on top
*/
linear-gradient(
to right,
transparent var(--track-fill),
var(--surface1) 0%
),
/* colorful fill effect, behind track surface fill */
var(--brand-bg-gradient) fixed;
}
يكمن السر في "إظهار" لون التعبئة النابض بالحياة. ويتم ذلك باستخدام تدرج التوقف الثابت في الأعلى. يكون التدرج شفافًا حتى نسبة التعبئة، وبعد ذلك يستخدم لون سطح المسار غير المعبأ. خلف هذا السطح غير الممتلئ، يوجد لون بعرض كامل، في انتظار الشفافية للكشف عنه.
نمط تعبئة المسار
يتطلّب تصميمي استخدام JavaScript للحفاظ على نمط التعبئة. هناك استراتيجيات CSS فقط ولكنها تتطلب أن يكون عنصر الإبهام بنفس ارتفاع المسار، ولم أتمكن من العثور على انسجام ضمن هذه الحدود.
/* grab sliders on page */
const sliders = document.querySelectorAll('input[type="range"]')
/* take a slider element, return a percentage string for use in CSS */
const rangeToPercent = slider => {
const max = slider.getAttribute('max') || 10;
const percent = slider.value / max * 100;
return `${parseInt(percent)}%`;
};
/* on page load, set the fill amount */
sliders.forEach(slider => {
slider.style.setProperty('--track-fill', rangeToPercent(slider));
/* when a slider changes, update the fill prop */
slider.addEventListener('input', e => {
e.target.style.setProperty('--track-fill', rangeToPercent(e.target));
})
})
أعتقد أنّ هذا التغيير يمثّل ترقية مرئية جيدة. يعمل شريط التمرير بشكل رائع بدون
JavaScript، ولا يلزم استخدام السمة --track-fill، ولن يكون له
نمط تعبئة إذا لم يكن موجودًا. إذا كان JavaScript متاحًا، يمكنك تعبئة الخاصية المخصّصة مع مراعاة أي تغييرات يجريها المستخدم، ومزامنة الخاصية المخصّصة مع القيمة.
إليك
منشور رائع على
CSS-Tricks من قِبل آنا
تيودور، يوضّح حلاً يعتمد على CSS فقط
لملء المسار. لقد وجدت أيضًا عنصر range هذا ملهمًا للغاية.
أنماط الصور المصغّرة
input[type="range"]::-webkit-slider-thumb {
appearance: none; /* clear styles, make way for mine */
cursor: ew-resize; /* cursor style to support drag direction */
border: 3px solid var(--surface3);
block-size: var(--thumb-size);
inline-size: var(--thumb-size);
margin-top: var(--thumb-offset);
border-radius: 50%;
background: var(--brand-bg-gradient) fixed;
}
معظم هذه الأنماط تهدف إلى إنشاء دائرة جميلة.
مرة أخرى، يمكنك رؤية تدرج الخلفية الثابت هناك الذي يوحد
الألوان الديناميكية للإبهام والمسارات وعناصر SVG المرتبطة.
لقد فصلتُ الأنماط الخاصة بالتفاعل للمساعدة في عزل تقنية box-shadow
المستخدَمة لتمييز العنصر عند تمرير مؤشر الماوس فوقه:
@custom-media --motionOK (prefers-reduced-motion: no-preference);
::-webkit-slider-thumb {
…
/* shadow spread is initally 0 */
box-shadow: 0 0 0 var(--thumb-highlight-size) var(--thumb-highlight-color);
/* if motion is OK, transition the box-shadow change */
@media (--motionOK) {
& {
transition: box-shadow .1s ease;
}
}
/* on hover/active state of parent, increase size prop */
@nest input[type="range"]:is(:hover,:active) & {
--thumb-highlight-size: 10px;
}
}
كان الهدف هو إنشاء ميزة مرئية متحركة وسهلة الإدارة لإبراز ملاحظات المستخدمين. باستخدام ظل المربع، يمكنني تجنُّب تفعيل التنسيق مع التأثير. أفعل ذلك عن طريق إنشاء ظل غير مموه ويتطابق مع الشكل الدائري لعنصر الإبهام. بعد ذلك، أغيّر حجم الانتشار عند تمرير مؤشر الماوس فوقه.
لو كان تأثير التمييز بهذه السهولة على مربعات الاختيار…
محدِّدات متوافقة مع متصفّحات متعددة
وجدتُ أنّني بحاجة إلى هذين المحدّدَين -webkit- و-moz- لتحقيق الاتساق بين المتصفحات:
input[type="range"] {
&::-webkit-slider-runnable-track {}
&::-moz-range-track {}
&::-webkit-slider-thumb {}
&::-moz-range-thumb {}
}
مربّع اختيار مخصّص
بالنظر إلى عنصر إدخال HTML التالي، سأوضح لك كيف قمت بتخصيص مظهره:
<input type="checkbox">
هناك 3 أجزاء في هذا العنصر نحتاج إلى تخصيصها:
عنصر مربّع الاختيار
input[type="checkbox"] {
inline-size: var(--space-sm); /* increase width */
block-size: var(--space-sm); /* increase height */
outline-offset: 5px; /* focus style enhancement */
accent-color: var(--brand); /* tint the input */
position: relative; /* prepare for an absolute pseudo element */
transform-style: preserve-3d; /* create a 3d z-space stacking context */
margin: 0;
cursor: pointer;
}
يُعدّ النمطان transform-style وposition للعنصر الزائف الذي سنقدّمه لاحقًا
لتصميم التمييز. بخلاف ذلك، فإنها في الغالب
أشياء ذات نمط رأي بسيط مني. أفضّل أن يكون المؤشر على شكل سهم، وأفضّل
إزاحات المخطط، ومربعات الاختيار التلقائية صغيرة جدًا، وإذا كان accent-color
متاحًا، أفضّل أن تكون مربعات الاختيار هذه
متوافقة مع نظام ألوان العلامة التجارية.
تصنيفات مربّعات الاختيار
من المهم توفير تصنيفات لمربّعات الاختيار لسببَين. الأول هو تمثيل الغرض من استخدام قيمة مربّع الاختيار، للإجابة عن السؤال "ما الذي يتم تفعيله أو إيقافه؟" ثانيًا، بالنسبة إلى تجربة المستخدم، اعتاد مستخدمو الويب على التفاعل مع مربّعات الاختيار من خلال التصنيفات المرتبطة بها.
<input type="checkbox" id="text-notifications" name="text-notifications" >
<label for="text-notifications"> <h3>Text Messages</h3> <small>Get notified about all text messages sent to your device</small> </label>
في التصنيف، أضِف سمة for تشير إلى مربّع اختيار حسب رقم التعريف: <label for="text-notifications">. في مربّع الاختيار، يجب تكرار كل من الاسم والمعرّف
لضمان العثور عليه باستخدام أدوات وتقنيات مختلفة، مثل الماوس أو قارئ الشاشة:
<input type="checkbox" id="text-notifications" name="text-notifications">.
تتوفّر ميزات :hover و:active وغيرها مجانًا مع عملية الربط، ما يزيد من
طرق التفاعل مع النموذج.
تمييز مربّع الاختيار
أريد الحفاظ على اتساق واجهاتي، ويحتوي عنصر شريط التمرير على تمييز مصغر لطيف أود استخدامه مع مربع الاختيار. تمكّنت الصورة المصغّرة من استخدام box-shadow وسمة spread لتكبير الظل وتصغيره. ومع ذلك، لا يعمل هذا التأثير هنا لأن مربعات الاختيار لدينا، ويجب أن تكون، مربعة.
تمكنت من تحقيق نفس التأثير البصري باستخدام عنصر زائف، وكمية مؤسفة من CSS الصعبة:
@custom-media --motionOK (prefers-reduced-motion: no-preference);
input[type="checkbox"]::before {
--thumb-scale: .01; /* initial scale of highlight */
--thumb-highlight-size: var(--space-xl);
content: "";
inline-size: var(--thumb-highlight-size);
block-size: var(--thumb-highlight-size);
clip-path: circle(50%); /* circle shape */
position: absolute; /* this is why position relative on parent */
top: 50%; /* pop and plop technique (https://web.dev/centering-in-css#5-pop-and-plop) */
left: 50%;
background: var(--thumb-highlight-color);
transform-origin: center center; /* goal is a centered scaling circle */
transform: /* order here matters!! */
translateX(-50%) /* counter balances left: 50% */
translateY(-50%) /* counter balances top: 50% */
translateZ(-1px) /* PUTS IT BEHIND THE CHECKBOX */
scale(var(--thumb-scale)) /* value we toggle for animation */
;
will-change: transform;
@media (--motionOK) { /* transition only if motion is OK */
& {
transition: transform .2s ease;
}
}
}
/* on hover, set scale custom property to "in" state */
input[type="checkbox"]:hover::before {
--thumb-scale: 1;
}
إنّ إنشاء عنصر زائف دائري هو عمل بسيط، ولكن وضعه خلف العنصر المرتبط به كان أكثر صعوبة. إليكم ما قبل وبعد أن أصلحتها:
إنّه بالتأكيد تفاعل دقيق، ولكن من المهم بالنسبة إليّ الحفاظ على الاتساق
المرئي. تقنية تغيير حجم الصور المتحركة هي نفسها التي استخدمناها في
أماكن أخرى. نضبط خاصية مخصّصة على قيمة جديدة ونسمح لـ CSS بنقلها
استنادًا إلى الإعدادات المفضّلة للحركة. الميزة الرئيسية هنا هي translateZ(-1px). أنشأ العنصر الرئيسي مساحة ثلاثية الأبعاد، واستفاد هذا العنصر الفرعي الزائف من ذلك من خلال وضع نفسه في الخلف قليلاً في المساحة z.
تسهيل الاستخدام
يقدم فيديو على YouTube عرضًا رائعًا لتفاعلات الماوس ولوحة المفاتيح وقارئ الشاشة لمكون الإعدادات هذا. سأذكر بعض التفاصيل هنا.
خيارات عناصر HTML
<form>
<header>
<fieldset>
<picture>
<label>
<input>
يحتوي كل منها على تلميحات ونصائح لأداة التصفّح الخاصة بالمستخدم. تقدّم بعض العناصر تلميحات حول التفاعل، وبعضها يربط بين التفاعلات، وبعضها يساعد في تشكيل شجرة تسهيل الاستخدام التي يتنقّل فيها قارئ الشاشة.
سمات HTML
يمكننا إخفاء العناصر التي لا تحتاجها برامج قراءة الشاشة، في هذه الحالة الرمز الموجود بجوار شريط التمرير:
<picture aria-hidden="true">
يعرض الفيديو أعلاه سير عمل قارئ الشاشة على نظام التشغيل Mac. لاحظ كيف ينتقل تركيز الإدخال مباشرة من شريط تمرير إلى آخر. ويرجع ذلك إلى أنّنا أخفينا الرمز الذي قد يكون محطة في الطريق إلى شريط التمرير التالي. بدون هذه السمة، سيحتاج المستخدم إلى التوقف والاستماع وتجاوز الصورة التي قد لا يتمكن من رؤيتها.
يتألف ملف SVG من مجموعة من العمليات الحسابية، لذا لنضِف عنصر <title> لإنشاء عنوان يظهر عند تمرير مؤشر الماوس فوقه وتعليق يمكن لشخص عادي قراءته حول ما تنشئه العمليات الحسابية:
<svg viewBox="0 0 24 24">
<title>A note icon</title>
<path d="M12 3v10.55c-.59-.34-1.27-.55-2-.55-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4V7h4V3h-6z"/>
</svg>
بخلاف ذلك، استخدمنا ما يكفي من ترميز HTML المميّز بوضوح، بحيث يتم اختبار النموذج بشكل جيد عبر الماوس ولوحة المفاتيح وأذرع التحكّم في ألعاب الفيديو وبرامج قراءة الشاشة.
JavaScript
لقد شرحتُ سابقًا كيفية إدارة لون تعبئة المسار من JavaScript،
لذا لنلقِ نظرة على رمز JavaScript المرتبط بـ <form> الآن:
const form = document.querySelector('form');
form.addEventListener('input', event => {
const formData = Object.fromEntries(new FormData(form));
console.table(formData);
})
في كل مرة يتم فيها التفاعل مع النموذج وتغييره، تسجل وحدة التحكم النموذج ككائن في جدول لسهولة المراجعة قبل الإرسال إلى الخادم.

الخاتمة
بعد أن عرفتم كيف فعلتُ ذلك، كيف ستفعلونه أنتم؟ وهذا يجعل بعض بنية المكونات ممتعة! مَن سيصنع الإصدار الأول مع فتحات في إطاره المفضل؟ 🙂
لنتعرّف على الطرق المختلفة لإنشاء المواقع الإلكترونية. يمكنك إنشاء نسخة تجريبية وإرسال الروابط إليّ عبر تغريدة، وسأضيفها إلى قسم الريمكسات التي أنشأها المنتدى أدناه.
ريمكسات من المنتدى
- @tomayac على أسلوبه في ما يتعلق بمنطقة التمرير لتصنيفات مربّعات الاختيار. لا يتضمّن هذا الإصدار فجوة عند تمرير مؤشر الماوس بين العناصر: عرض توضيحي والمصدر.