كيفية إنشاء label عائم ب CSS فقط لحقول الإدخال + كود Tailwind

كتب بواسطة idriss douiri profile picture إدريس الدويري

حدث بتاريخ

3 min read

تسمية عائمة باستخدام CSS فقط
مشاركة

تُستخدم التسميات العائمة في العديد من واجهات المستخدم، خاصة من قِبل Google. سيركز هذا المقال على كيفية إنشائها باستخدام CSS فقط، بالإضافة إلى نسخة باستخدام tailwind css.

ما هي التسمية العائمة؟

التسمية العائمة هي نمط تصميم في واجهة المستخدم يُستخدم في حقول النماذج حيث يتحرك نص العنصر النائب أو يطفو فوق حقل الإدخال عند تركيزه أو عند احتوائه على نص. تم تقديم هذا النمط كعنصر في مبادئ تصميم Material من Google، التي تهدف إلى إنشاء تجربة استخدام موحدة عبر المنصات.

جرب هذا المثال:

لماذا نستخدم التسميات العائمة؟

تقدم التسميات العائمة العديد من المزايا وتحل الكثير من مشاكل واجهة المستخدم، مثل:

  • سهولة الوصول: التأكد من أن التسمية مرئية دائمًا للمستخدم.
  • الوضوح: استخدام مساحة أقل وتصميم أنظف وأكثر حداثة.

إعداد الـ HTML

ستختلف بنية الHTML بناءً على الطريقة التي تختار بها تصميمها (مثلاً: باستخدام محدد :has()، أو الموضع المطلق، إلخ…). بالنسبة لي، سأستخدم هذا الهيكل حيث أضع الlabel بعد الإدخال حتى أتمكن من استهدافه في CSS باستخدام المحدد الأخوي (sibling sellector) مع استخدام السمة for للربط بينهما.

<div class="form-group">
  <input type="text" id="name" placeholder="الاسم">
  <label for="name">الاسم</label>
</div>

يمكن وضع التسمية قبل أو بعد حقل الإدخال، كما هو مذكور في مواصفات HTML4:

“يمكن وضع التسمية نفسها قبل أو بعد العنصر المرتبط بها” — مواصفات W3C HTML4.

إضافة أنماط CSS

نحتاج إلى تصغير التسمية وتحريكها للأعلى عند التركيز على الحقل أو ملئه، ولتحقيق ذلك نتبع الخطوات التالية:

الخطوة 1: إخفاء العنصر النائب (placeholder) لأننا سنستخدم التسمية بدلاً منه.

input::placeholder {
	opacity: 0;
}

الخطوة 2: وضع التسمية داخل حقل الإدخال.

يمكننا استخدام position: absolute لوضع التسمية داخل الحقل، ومن المهم تعطيل أحداث المؤشر لها حتى لا تتداخل مع الإدخال.

.form-group {
  --pad: .75rem;
  position: relative;
}
label {
  position: absolute;
  left: var(--pad);
  top: var(--pad);
  pointer-events: none;
}

الخطوة 3: إستشعار ما إذا كان الحقل مُركّزًا أو مملوءًا.

نستخدم :placeholder-shown للكشف إذا كان العنصر النائب ظاهرا (أي إذا كان الحقل فارغ)، و :focus للكشف إذا كان مُركّزًا. بعدها نستخدم المحدد الأخوي next-sibling combinator (+) للوصول إلى التسمية وتنسيقها.

input:focus + label,
input:not(:placeholder-shown) + label {
   /* تنسيق عند تركيز أو ملء الحقل */
}

الخطوة 4: إزاحة التسمية عند التركيز أو التعبئة.

يمكننا إزاحة التسمية للأعلى تعديل الtranslsateY إلى قيمة سلبية في خاصية transform. هذا ما وجدته مناسبًا لي:

input:focus + label,
input:not(:placeholder-shown) + label {
  transform: translateY(calc(-50% - var(--pad))) scale(.8);
  color: var(--accent);
}

النتيجة الكاملة

بتتبع الخطوات أعلاه، هذا هو الشكل النهائي الذي توصلنا إليه. لكنك غير مقيد بهذه الخيارات فقط:

شاهد المثال تسمية عائمة باستخدام CSS فقط بواسطة Driss (@driss-d) على CodePen.

نسخة Tailwind CSS

هذه النسخة تتبع نفس المنطق المغطى في الشرح أعلاه:

<!-- غيّر الألوان لتتناسب مع تصميمك -->
<div class="relative">
  <input
    class="w-full p-2 border border-gray-400 rounded-md outline-none peer placeholder:opacity-0 bg-white focus:border-blue-500"
    placeholder="الاسم"
    id="name"
  />
  <label
    for="name"
    class="absolute left-1 scale-75 peer-placeholder-shown:scale-100 peer-focus:scale-75 -top-[0.8rem] px-2 origin-left peer-placeholder-shown:top-2 peer-focus:-top-[0.8rem] peer-focus:text-blue-500 text-body transition-all pointer-events-none bg-white"
  >
  الاسم
  </label>
</div>