الخطوات
-
1
إعادة تعيين مظهر المتصفح الافتراضي
appearance: noneيُزيل تنسيق الودجت الأصلي للمنصة (التدرج اللوني على حقول iOS Safari، والحواف المنحوتة على صناديق select في Firefox).border-radius: 0يمنع iOS من تدوير الزوايا التي لم تطلبها. اضبط هذه أولاً، ثم ابنِ التنسيق الذي تريده فعلاً فوقها.cssinput, select, textarea { appearance: none; -webkit-appearance: none; border-radius: 0; /* iOS Safari override */ box-sizing: border-box; font-family: inherit; /* browsers do NOT inherit this by default */ font-size: 1rem; } -
2
تعريف تنسيق أساسي متسق
بعد إعادة التعيين، طبّق نفس الأساس على جميع حقول الإدخال النصية. حد 1px، وpadding مريح، وline-height صريح يُنشئ خطاً أساسياً موثوقاً عبر Chrome وFirefox وSafari وEdge.
cssinput[type="text"], input[type="email"], input[type="password"], input[type="tel"], input[type="url"], input[type="search"], input[type="number"], textarea, select { width: 100%; padding: 0.625rem 0.875rem; line-height: 1.5; border: 1px solid #d1d5db; border-radius: 0.375rem; background: #fff; color: #111827; transition: border-color 0.15s ease, box-shadow 0.15s ease; } -
3
تنسيق :focus-visible — لا :focus
:focus-visibleلا يُفعَّل إلا حين يُقرر المتصفح أن مؤشر تركيز مرئياً ضروري (التنقل بالكيبورد، ليس النقر بالفأرة). هذا يمنحك حلقات تركيز دقيقة لمستخدمي الكيبورد دون ظهور الحلقة عند كل نقرة بالفأرة — وهو السبب الذي يجعل كثيراً من التصاميم تستخدمoutline: noneبشكل خاطئ. لا تُزيل المخطط التفصيلي كلياً أبداً.cssinput:focus-visible, textarea:focus-visible, select:focus-visible { outline: 2px solid #2563eb; outline-offset: 2px; border-color: #2563eb; } /* Remove the default (non-visible) focus ring from browsers that support :focus-visible */ input:focus:not(:focus-visible), textarea:focus:not(:focus-visible), select:focus:not(:focus-visible) { outline: none; } -
4
تمييز الحقول غير الصحيحة دون تحديد الفارغة
CSS
:invalidيطابق حقل الإدخال المطلوب الفارغ فور تحميل الصفحة — قبل أن يلمسه المستخدم. دمجه مع:not(:placeholder-shown)يُقيّد حالة الخطأ بالحقول التي تفاعل معها المستخدم وتركها غير صحيحة.css/* Only show error state after the user has typed something */ input:invalid:not(:placeholder-shown), textarea:invalid:not(:placeholder-shown) { border-color: #dc2626; background: #fef2f2; } /* Optional: paired error icon or message */ input:invalid:not(:placeholder-shown) + .field-error { display: block; } .field-error { display: none; font-size: 0.8125rem; color: #dc2626; margin-top: 0.25rem; } -
5
تنسيق مربعات الاختيار وأزرار الراديو بـ accent-color
الطريقة الحديثة لتنسيق مربعات الاختيار وأزرار الراديو دون استبدالها بعناصر مخصصة هي
accent-color. سطر واحد — يتولى المتصفح الباقي، مكيّفاً حالة التحديد وحالة indeterminate وحالة disabled تلقائياً. لأي شيء يتجاوز تغيير اللون، لا تزال تحتاج عناصر مخصصة.css/* Global tint for all native checkboxes and radios */ :root { accent-color: #2563eb; } /* Or scope to specific elements */ input[type="checkbox"], input[type="radio"] { accent-color: #2563eb; width: 1rem; height: 1rem; cursor: pointer; } -
6
تنسيق عنصر Select
بعد
appearance: none، يختفي سهم القائمة المنسدلة الأصلي. أضف سهم SVG مخصصاً عبرbackground-image. هذا أبسط بكثير من قائمة select مخصصة بالكامل ويغطي 95% من احتياجات التصميم. لقائمة منسدلة مخصصة بالكامل، تحتاج إلى مكتبة JavaScript أو العنصر الجديد التجريبي<selectlist>.cssselect { appearance: none; padding-right: 2.5rem; /* room for the arrow */ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='%236b7280' d='M4 6l4 4 4-4'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 0.75rem center; background-size: 1rem; cursor: pointer; } -
7
تغليف حقول الملفات للتنسيق المخصص
لا يمكن تنسيق زر إدخال الملف مباشرة. النمط المعياري هو إخفاء الحقل الحقيقي بصرياً وعرض label منسّق يُشغّله. سمة
forفي label تربطه بالحقل — النقر على label يفتح منتقي الملفات.html<label class="file-upload"> <input type="file" class="sr-only" id="avatar" accept="image/*"> <span class="file-upload__btn">Choose file</span> <span class="file-upload__name" id="file-name">No file chosen</span> </label> -
8
دعم الوضع الداكن بمتغيرات CSS
القيم السداسية المكتوبة مباشرة تنكسر في الوضع الداكن. استخدم خصائص CSS المخصصة لكل لون في تنسيقات النموذج، ثم تجاوز المتغيرات داخل
@media (prefers-color-scheme: dark). ستتحدث جميع حقول الإدخال تلقائياً.css:root { --input-bg: #ffffff; --input-border: #d1d5db; --input-text: #111827; --input-focus-ring: #2563eb; --input-error-border: #dc2626; --input-error-bg: #fef2f2; } @media (prefers-color-scheme: dark) { :root { --input-bg: #1f2937; --input-border: #374151; --input-text: #f9fafb; --input-focus-ring: #60a5fa; --input-error-border: #f87171; --input-error-bg: #450a0a; } } input, select, textarea { background: var(--input-bg); border-color: var(--input-border); color: var(--input-text); }
نصائح ومحاذير
- اضبط دائماً <code>font-family: inherit</code> و<code>font-size: 1rem</code> على عناصر النماذج — المتصفحات تستثنيها صراحةً من وراثة الخط، وهو ما نادراً ما تريده.
- يجب أن تصف سمة <code>placeholder</code> الشكل المتوقع (مثل "mm/dd/yyyy")، لا أن تكرر نص التسمية. يجب أن يكون نص التسمية في عنصر <code><label></code> دائماً — لا تعتمد على placeholder كبديل.
- لحقول الإدخال المعطّلة، أضف <code>cursor: not-allowed; opacity: 0.5</code> — المؤشر البصري يساعد المستخدمين على فهم أن الحقل غير نشط بشكل مقصود.
- يجب أن يكون ارتفاع حقل الإدخال 44px على الأقل لأهداف اللمس — الحد الأدنى لـ Apple HIG. استخدم <code>min-height: 2.75rem</code> بدلاً من ارتفاع ثابت حتى يتمكن المحتوى الطويل (مثل متعدد الأسطر) من التمدد.
خاتمة
الاتساق في تنسيق النماذج يتلخص في أربع خطوات: إعادة تعيين المظهر، وتعيين أساس مشترك، ومعالجة حالات التركيز والتحقق بشكل صحيح، واستخدام متغيرات CSS للوضع الداكن. الإضافات الحديثة — :focus-visible، وaccent-color، و:invalid:not(:placeholder-shown) — تُلغي فئات بأكملها من الحيل التي كانت تتطلب JavaScript. طبّقها وستحصل على نماذج تبدو احترافية، وتعمل عبر المتصفحات، وتبقى يسيرة الوصول دون جهد إضافي.