مفتاح التبديل
Switch / Togglerole="switch"
اسمه كمانسويتش، توجل، مفتاح تشغيل وإيقاف، مفتاح الإعدادات، زرّ التفعيل، مفتاح منزلق، toggle، toggle switch، on/off switch، settings toggle، switch control، slider toggle
مفتاح التبديل عنصر تحكّم له حالتان فقط: مُفعّل أو مُعطّل. وهو ينفّذ التغيير في اللحظة التي يضغطه فيها المستخدم، بلا زرّ حفظ ولا خطوة تأكيد. مكانه الطبيعي شاشات الإعدادات وكل خيار يسري أثره فوراً: الوضع الداكن، الإشعارات، المزامنة في الخلفية. وهو ليس مربّع اختيار (checkbox)، فمربّع الاختيار قيمة تُجمَع مع بقية النموذج وتُرسَل عند الضغط على «حفظ»، ويظلّ أمام المستخدم متّسع للتراجع قبل الإرسال، أمّا المفتاح فلا تراجع فيه لأن الأثر وقع قبل أن يرفع إصبعه. وليس هو زرّ تبديل (toggle button)، فذاك زرّ يحمل aria-pressed ويصف حالة أداة داخل شريط أدوات، كزرّ «عريض» في المحرّر، بينما يحمل المفتاح role="switch" مع aria-checked ويصف إعداداً قائماً بذاته. ولا هو زوج أزرار راديو، فأزرار الراديو تعرض عدّة بدائل مسمّاة يُختار منها واحد، أمّا المفتاح فليس أمامه إلا الشيء ونقيضه. وفي المراجعة تكفي قاعدة واحدة لحسم النقاش: إذا احتاجت شاشتك زرّ «تطبيق» بجانب المفتاح فأنت لا تريد مفتاحاً أصلاً، بل مربّع اختيار داخل نموذج.
لو قلت عليه…
العيّنة الحيّة
تفاعل مع الديمو. كل الأجزاء حقيقية ومرقّمة.
الإعدادات
كل مفتاح يُطبَّق لحظة الضغط، ولا يوجد زرّ «حفظ» في هذه الشاشة.
تشريح العنصر: كل جزء واسمه
مرّر على أي سطر ليتحدّد مكانه في الديمو فوق.
برومبت البناء
سلوكه في الاتجاه من اليمين لليسار
الجزء ده حصري عندنا.
اتجاه سفر القرص
ينعكسالقرص يسافر دائماً نحو النهاية المنطقية للمسار، ومعنى ذلك أن حالة «مُفعّل» تجلس عند اليسار في العربية بعد أن كانت عند اليمين في الإنجليزية. والمشكلة أن transform خاصّية فيزيائية بحتة لا تعرف الاتجاه ولا يوجد لها مكافئ منطقي في CSS: translateX(22px) سيدفع القرص خارج المسار في RTL. الحلّ الصحيح translateX(calc(22px * var(--dir))) مع ضبط --dir: -1 داخل [dir="rtl"]. ويمكن الاستغناء عن الإزاحة أصلاً بجعل المسار flex وتبديل justify-content بين flex-start و flex-end، لأن المحور المضمّن ينعكس مع direction من تلقاء نفسه. غير أن هذا الشكل لا يقبل التحريك، فاختر متغيّر الاتجاه إن أردت انتقالاً ناعماً.
امتلاء المسار
ينعكسالمسار الذي يمتلئ باللون خلف القرص يجب أن ينمو من البداية المنطقية، أي من اليمين في العربية. نفّذه بعنصر داخلي مثبّت بـ inset-inline-start: 0 يتحرّك inline-size فيه من صفر إلى ١٠٠٪، فينعكس من تلقاء نفسه لأن الحافّة التي رُسِي عليها هي نفسها التي تبدّلت. أمّا transform: scaleX() فلا يصلح هنا، لأن transform-origin لا تقبل أي كلمة منطقية: ليس في محورها الأفقي إلا left و right و center أو طول أو نسبة مئوية، فتضطرّ إلى كتابة transform-origin: right بيدك داخل [dir="rtl"]. ونفس القاعدة على المسار ثنائيّ اللون المرسوم بـ linear-gradient(to right, …): لا كلمات منطقية في التدرّجات، فاقلبه إلى to left عند الانعكاس.
موضع التسمية في الصفّ
ينعكسفي صفّ الإعدادات تجلس التسمية عند البداية المنطقية والمفتاح عند النهاية، فينقلب الصفّ كاملاً في العربية: النصّ يميناً والمفتاح يساراً. استعمل صفّ flex مع justify-content: space-between أو margin-inline-start: auto على المفتاح، ولا تكتب float: right ولا margin-left: auto. ولا تضف flex-direction: row-reverse داخل [dir="rtl"] ظنّاً أنك تصحّح الاتجاه: المحور المضمّن انعكس مرّة بالفعل، والعكس الثاني يعيد المفتاح إلى الجهة الخطأ ويجعل الترتيب البصري مخالفاً لترتيب DOM وللتنقّل بـ Tab.
الرمزان داخل المسار
لا ينعكسموضعا الرمزين يتبادلان مع المسار تلقائياً لأنهما يتبعان حافّتيه المنطقيتين، لكن الرمزين نفسيهما لا ينقلبان: خاصّية Bidi_Mirrored للمحرف ✓ قيمتها No، ومعناه لا يتغيّر باختلاف اتجاه الصفحة. لذلك فالقاعدة الشاملة [dir="rtl"] svg { transform: scaleX(-1) } تكسر علامة الصح وتكسر معها مؤشّر التحميل الدوّار داخل القرص وتجعلهما يبدوان مرسومين بالمقلوب. اقصر القلب على صنف مخصّص تضعه على الأسهم وحدها.
السحب بالإصبع
ينعكسلو سمحت بتبديل المفتاح سحباً لا نقراً، فالسحب نحو اليسار في العربية هو ما يعني «شغّل». وأحداث المؤشّر تعطيك إزاحة فيزيائية بحتة: قيمة movementX (أو الفرق بين clientX الحالي وبداية السحب) موجبة دائماً عند التحرّك يميناً مهما كان اتجاه الصفحة، فمقارنة dx > threshold تعكس معنى الإيماءة كلها في العربية. اضرب الإزاحة في إشارة اتجاه تقرأها من getComputedStyle(el).direction === "rtl" ? -1 : 1 قبل المقارنة، وأضف touch-action: pan-y على المسار حتى لا يبتلع تمرير الصفحة الإيماءة.
أسماؤه في الكود
كل سطر هو كلمة مكتبة واحدة عن نفس الشيء. خد السطر اللي بيكلّم مشروعك.
شوف كمان
آخر تحديث · 2026-08-19