المنزلق
Slider<input type="range">
اسمه كمانسلايدر، الشريط المنزلق، شريط الانزلاق، منزلق المدى، مقبض القيمة، شريط تحديد القيمة، range input، range slider، volume slider، dual range slider، track and thumb، value slider
المنزلق عنصر إدخال يختار قيمة رقمية واحدة من مدى متّصل بين حدّ أدنى وحدّ أقصى، ويعبّر عن الاختيار بموضع مقبض على مسار. القيمة تتغيّر أثناء السحب لا بعده، وهذا ما يجعله مناسباً لكل شيء يُرى أثره في اللحظة: مستوى الصوت، حجم الخطّ، سطوع الشاشة، سقف السعر في فلتر البحث. وهو ليس شريط تقدّم (progress bar)، فشريط التقدّم مخرَج لا مدخَل، يبلّغ عن حالة عملية جارية ويحمل role="progressbar" ولا يستجيب لسحب أصلاً. وهو ليس شريط التمرير (scrollbar)، فشريط التمرير يحرّك نافذة عرض فوق محتوى أطول منها، وطول مقبضه نفسه معلومة تقول لك كم ترى من المحتوى، بينما مقبض المنزلق ثابت الحجم لأن موضعه وحده هو الذي يحمل المعنى. ولا هو الحقل الرقمي ذو الأسهم (stepper)، فالحقل الرقمي يقبل الكتابة ويصلح للقيم الدقيقة التي يعرفها المستخدم مسبقاً، أمّا المنزلق فيقايض الدقّة بالسرعة. والقاعدة العملية في المراجعة: إذا كان المستخدم يعرف الرقم قبل أن يمدّ يده فأعطه حقلاً، وإذا كان يبحث عنه بالتجريب فأعطه منزلقاً.
لو قلت عليه…
العيّنة الحيّة
تفاعل مع الديمو. كل الأجزاء حقيقية ومرقّمة.
تشريح العنصر: كل جزء واسمه
مرّر على أي سطر ليتحدّد مكانه في الديمو فوق.
برومبت البناء
سلوكه في الاتجاه من اليمين لليسار
الجزء ده حصري عندنا.
المحور كلّه ينعكس
ينعكسالمنزلق الأفقي محور مضمّن كامل، فينقلب بأكمله في العربية: الحدّ الأدنى يجلس عند اليمين، والحدّ الأقصى عند اليسار، والجزء الممتلئ ينمو نحو اليسار. و<input type="range"> يفعل هذا وحده لأنه يتبع قيمة direction المحسوبة على الحقل نفسه لا على الصفحة، ومن هنا تأتي المصيدة: أي غلاف يفرض dir="ltr" حول الحقل (وهي عادة شائعة مع الأرقام والحقول الرقمية) يترك منزلقاً بالاتجاه الإنجليزي داخل صفحة عربية. أمّا المنزلق المبنيّ يدوياً على left و width فلا يعرف الاتجاه أصلاً ويبقى بعد الانعكاس كما كان قبله.
تثبيت الامتلاء والمقبض
ينعكساستبدل left: 0; width: 40% بـ inset-inline-start: 0; inline-size: 40% فينعكس الامتلاء من تلقاء نفسه لأن الحافّة التي رُسي عليها هي التي تبدّلت. أمّا تحريكه بـ transform: scaleX() فلا يمنحك هذه الراحة، لأن كلمات transform-origin كلّها فيزيائية (left و right و top و bottom و center) إلى جانب الأطوال والنِسَب ولا يوجد فيها مقابل منطقي واحد، فلا مفرّ من transform-origin: right داخل [dir="rtl"] أو من متغيّر اتجاه. وتوسيط المقبض هو المصيدة الأخيرة: inset-inline-start: 40% تجعل حافّته اليمنى في RTL على بُعد ٤٠٪ من يمين المسار، فتدفعه إزاحة translateX(-50%) المعتادة إلى الجهة الخطأ بنصف عرضه، والصواب translateX(calc(-50% * var(--dir))) مع ضبط --dir: -1 داخل [dir="rtl"].
الأسهم تتبادل معناها
ينعكسالسهمان الأفقيان يتبادلان مع المحور، ففي العربية يزيد ArrowLeft القيمة ويُنقصها ArrowRight، والمنزلق الأصلي يفعل ذلك وحده لأنه يعكس الأسهم مع الرسم. وجدول لوحة المفاتيح في نمط المنزلق لدى WAI-ARIA APG مكتوب من زاوية اليسار إلى اليمين ولا يذكر هذا الانعكاس، ولهذا يظلّ الكود اليدوي من نوع switch (e.key) { case "ArrowRight": v + step } يُنسخ كما هو ويسلّم المستخدم العربي عكس ما ضغط عليه. وما عدا ذلك ثابت: ArrowUp يزيد و ArrowDown يُنقص في الاتجاهين، و Home و End يقفزان إلى الحدّ الأدنى والأقصى المنطقيين لا إلى يمين الشاشة ويسارها.
حساب السحب بالمؤشّر
ينعكسأحداث المؤشّر لا تعرف الاتجاه إطلاقاً: clientX إحداثي فيزيائي، و getBoundingClientRect() تعيد left و right بالمعنى الفيزيائي مهما كانت قيمة dir. لذلك تقيس المعادلة المعتادة (e.clientX - rect.left) / rect.width من الحافّة اليسرى، وهي في العربية طرف الحدّ الأقصى، فتخرج القيمة مقلوبة ويقفز المقبض إلى الطرف البعيد أول لمسة. قِس من الحافّة المنطقية بـ (rect.right - e.clientX) / rect.width حين تكون getComputedStyle(track).direction === "rtl"، وضع touch-action: none على المسار حتى لا يبتلع تمرير الصفحة السحب على الموبايل.
الرقم نفسه لا ينقلب
لا ينعكسالمحور ينعكس والرقم لا. الأرقام تجري من اليسار إلى اليمين داخل النصّ العربي بحكم خوارزمية bidi، فلا تعِد ترتيب محارفها ولا تقلبها بـ scaleX(-1). والمشكلة الحقيقية في الرموز الملاصقة لها: قيمة سالبة مثل -5 تُعرض «5-» داخل فقرة عربية لأن محرف الناقص يؤول إلى محايد فيأخذ اتجاه الفقرة، وتنزلق وحدة لاتينية مثل km إلى الجهة الخطأ من الرقم بالطريقة نفسها، فاعزل كل تسمية قيمة داخل <bdi> أو بـ unicode-bidi: isolate وولّد النصّ بـ Intl.NumberFormat حتى تأتي الفاصلة العشرية ورمز العملة بالشكل الذي تتوقّعه اللغة.
أسماؤه في الكود
كل سطر هو كلمة مكتبة واحدة عن نفس الشيء. خد السطر اللي بيكلّم مشروعك.
شوف كمان
آخر تحديث · 2026-08-19