الصور المتحركة لحدود CSS

الاطّلاع على عدة طرق لتحريك الحدود في CSS

ضبط الحدود

تتوفّر بضع طرق لضبط حدود لعنصر معيّن: border وoutline وbox-shadow. كما هو موضّح في مقالة The 3 CSS Methods for Adding Element Borders (طرق CSS الثلاث لإضافة حدود العناصر) بقلم "ستيفاني إيكلز"، لكل طريقة مزاياها وعيوبها، خاصةً عندما يتعلق الأمر بتحريك الحدود. السبب الرئيسي لعدم استخدام border CSS مناسب هو لأغراض الصور المتحركة.

Border Animations using outline-offset by Kevin J.‎ Powell

من المقالات التي لفتت انتباهي مؤخرًا مقالة Fantastic CSS border animation، حيث استكشف المؤلّف Coco المزيد من الخيارات. من خلال إدخال محتوى تم إنشاؤه باستخدام ::before و::after، يتم إنشاء حدود زائفة يتم تحريكها بعد ذلك.

أكثر ما يبرز بالنسبة لي هو الرسوم المتحركة الداعمة المستخدمة في المقالة. فهي تساعد حقًا في شرح ما يتم القيام به بالضبط لتحقيق التأثير المطلوب.

Border Animations using generated content by Coco

الطبقة البيضاء والخطوط الملوّنة هي محتوى من إنشاء الذكاء الاصطناعي. من خلال تلاشي الطبقة البيضاء للداخل والخارج، يتضح كيفية تكديسها وكيفية عمل الرسوم المتحركة.

الاحتفاظ بنموذج الصندوق

من عيوب استخدام "المحتوى الذي تم إنشاؤه" لتقليد الحدود هو أنّك ستحصل على نموذج مربّع معطّل: يمكن للمحتوى الآن حجب الحدود الزائفة لأنّ "الحدود" المذكورة يتم رسمها في الأسفل. للحدّ من هذه المشكلة، عليك تطبيق border-width المطلوب كـ padding.

To have a true border–and thus retain the workings of the box model–you can use multiple backgrounds which you then stretch out into the border area.

الأساسيات

لنبدأ بإنشاء حدود منقطة وإضافة الخلفيات المتعددة.

/* Size of the border */
--border-size: 0.5rem;

/* Create a dotted border */
border: var(--border-size) dotted lime;

/* Create two background layers:
   1. A white semi-transparent
   2. A layer with the colored boxes
 */
background-image:
  linear-gradient(to right, rgb(255 255 255 / 0.5), rgb(255 255 255 / 0.5)),

  conic-gradient(
    from 45deg,
    #d53e33 0deg 90deg,
    #fbb300 90deg 180deg,
    #377af5 180deg 270deg,
    #399953 270deg 360deg
  )
;

جارٍ ضبط حجم الخلفيات باستخدام background-origin

كما ترون، هناك مشكلة في الخلفيات هنا: تم رسمها في الحدود، ولكن يبدو أنّ conic-gradient غير صحيح على الإطلاق. هذا هو السلوك المقصود في الواقع: لا يتم رسم صور الخلفية تلقائيًا في الحدود لأنّ مصدرها هو padding-box للعنصر. لإنشاء حدّ بعد كل شيء، يتم تكرار صور الخلفية المحدّدة في الحدّ نفسه، ما يؤدي إلى تأثير مرئي غريب.

لحلّ هذه المشكلة، عليك تمديد الخلفية لتشغل أيضًا حجم الحدود. يمكنك إجراء ذلك يدويًا من خلال تمديد الخلفية وإعادة تحديد موضعها، ولكن من الأفضل استخدام السمة background-origin لتحديد حجم الخلفية مقارنةً بـ border-box.

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 4.
  • Safari: 3.

Source

الإجراءات غير المُوصى بها
/* Manually add or offset the size of the border where needed */
background-position: calc(var(--border-size) * -1) calc(var(--border-size) * -1);
background-size: calc(var(--border-size) * 2 + 100%) calc(var(--border-size) * 2 + 100%);
الإجراءات الموصى بها
background-origin: border-box;

هذه الإضافة الواحدة تجعل كل شيء يبدو أفضل بكثير:

تصغير طبقة الخلفية البيضاء باستخدام background-clip

بما أنّ الخلفيات تشغل الآن كل المساحة، يجب تقليص الطبقة شبه الشفافة مرة أخرى. بدلاً من تعديل background-size مرة أخرى، هناك طريقة أسهل لإجراء ذلك: استخدِم background-clip واضبطه على padding-box. بهذه الطريقة، لن يتم رسم الخلفية تحت منطقة الحدود.

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 4.
  • Safari: 5.

Source

background-clip:
  padding-box, /* Clip white semi-transparent to the padding-box */
  border-box /* Clip colored boxes to the border-box (default) */
;

أخيرًا، اجعل الحدود transparent للحصول على التأثير الكامل.

border: 0.3rem dotted transparent;

الصور المتحركة

لاستعادة حركة الحدود، يمكنك التلاعب بزاوية بدء conic-gradient.

--angle: 0deg;
conic-gradient(
  from var(--angle),
  #d53e33 0deg 90deg,
  #fbb300 90deg 180deg,
  #377af5 180deg 270deg,
  #399953 270deg 360deg
);

بفضل @property، أصبح ذلك سهلاً في المتصفّحات التي تتيح ذلك:

Browser Support

  • Chrome: 85.
  • Edge: 85.
  • Firefox: 128.
  • Safari: 16.4.

Source

@property --angle {
  syntax: "<angle>";
  initial-value: 0deg;
  inherits: false;
}

@keyframes rotate {
  to {
    --angle: 360deg;
  }
}

وعند دمج كل هذه العناصر، يصبح الرمز كالتالي:

المحتوى الإضافي: border-image

من الطرق التي تناولناها سابقًا لرسم حدود متدرّجة استخدام السمة border-image في CSS.

Browser Support

  • Chrome: 16.
  • Edge: 12.
  • Firefox: 15.
  • Safari: 6.

Source

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

/* Create a border */
border: 0.5rem solid transparent;

/* Paint an image in the border */
border-image:
  conic-gradient(
    from var(--angle),
    #d53e33 0deg 90deg,
    #fbb300 90deg 180deg,
    #377af5 180deg 270deg,
    #399953 270deg 360deg
  ) 1
;

ومع ذلك، ستلاحظ أنّ بعض الميزات لم تعُد تعمل مع هذا النهج:

  • لا يتّبع border-image شكل border-radius، بل يبقى دائمًا مستطيلاً.
  • عند ضبط border-image-slice على "تعبئة"، لا يتم رسم border-image أسفل background المحدّد، بل في الأعلى. قد يكون هذا مزعجًا إذا كنت تريد أن تكون الخلفية شبه شفافة.

في الختام

هناك العديد من الاحتمالات لتحريك الحدود في CSS. بناءً على حالة الاستخدام، قد تميل إلى أحدهما أو الآخر.