اذهب إلى المحتوى

الأشكال Shapes في CSS


Bian Alabras

مستطيلات داخل مستطيلات هذا هو التصميم المعتمد عند الغالبية في بناء صفحات الويب الخاصة بنا، ولكننا نحاول الآن كسر هذه الصورة النمطية عن أشكال CSS من خلال استخدام أشكال هندسية جديدة، ولكن هذه الأشكال Shapes لا تتفاعل أبدًا مع محتوى الشكل أو مع العناصر الأخرى داخل الصفحة.
يتم الآن وضع تخصيصات جديدة للأشكال في CSS لتغيّر من هذا الجمود في الأشكال. ففي منتصف عام 2012 وضعت شركة Adobe هدفًا جديدًا أمامها ألا وهو تزويد مصممي الويب بطريقة جديدة تغير من الطريقة النمطية في انسياب المحتوى داخل وحول الأشكال المعقدة - وهو أمر جديد تمامًا لم نكن قادرين في تطبيقه حتى باستخدام JavaScript. على سبيل المثال، ستلاحظ في التصاميم الجديدة التي تعتمد على الأشكال المتعددة انسياب النص حول الصور الدائرية بشكل سلسل وجميل، ولكن بدون هذه الأشكال سيتوضع النص بشكل مستطيل من دون أي تأثيرات إضافية، وبالتالي نجد أن هذه الطريقة الجديدة في التعامل مع الأشكال ستأخد التصاميم إلى مستوى جديد من التطور.

01.jpg

دعم المتصفحات

إن المتصفحات التي تدعم الأشكال CSS Shapes Module 1 بالنسبة لنسخة الحاسب حتى نهاية عام 2017 كانت Chrome، Firefox، Opera و (Safari(WebKit، بينما لايقدم متصفح Internet Explorer هذا الدعم. ويختلف الأمر بالنسبة لنسخة المتصفحات الخاصة بالموبايل حيث أن متصفح Safari هو فقط من يدعم خاصية الأشكال. ومع ذلك فقد وصلت تقنية الأشكال في CSS المرحلة الأولى منها إلى أن جميع المتصفحات تتعرف على طريقة كتابة تعريف الأشكال Syntax الخاصة بها وتخصيصها وبالتالي تعتبر برمجة الأشكال مستقرة جدًا ولن يكون الوقت طويلًا حتى يتم تنفيذها بشكل كامل على جميع المتصفحات.
إن المرحلة الأولى من تطوير الأشكال في CSS يركز على الخصائص التي تغير من طريقة انسياب المحتوى حول الشكل أي أنها تركز على خاصية shape-outside بالإضافة إلى الخصائص الأخرى المتعلقة بها. ومن المتوقع أن استخدام هذه الميزة الجديدة في الأشكال عند CSS ودمجها مع الميزات الأخرى المتطورة مثل الإخفاء والقص Clipping and Masking، طريقة معالجة العنصر قبل عرضه CSS Filters، و مزج وتركيب العناصر معًا Compositing and Blending سيسمح لنا ببناء الأشكال وتصميمها بشكل احترافي متطور من دون الحاجة إلى المحررات المستخدمة في التصميم كالفوتوشوب و InDesign.
سيركّز بناء الأشكال في CSS مستقبلًا على طريقة التفاف المحتوى داخل الشكل نفسه أيضًا. فعلى سبيل المثال، من السهل اليوم بناء المعين باستخدام CSS حيث يتوجب علينا فقط تدوير العنصر بزاوية 24 درجة ثم تدوير المحتوى داخله وبالتالي يعود المحتوى ليتوضع أفقيًا ضمن الصفحة. ولكن المعين لن يكون هو الأب الحاوي container للمحتوى، وبالتالي سيبقى المحتوى مستطيل الشكل. ولحل هذه المشكلة يمكن استخدام الخاصية shape-inside والتي تقوم بجعل المحتوى يأخذ شكل معين داخل التصميم أيضًا.

02.jpg

بناء شكل باستخدام CSS

يمكن تطبيق شكل على أي عنصر element من خلال استخدام خاصية الأشكال shape property. حيث نمرر خاصية الشكل كتابع shape function يمرر مجموعة من المعاملات parameters التي تعرف الشكل الذي نريد تطبيقه مثل نقطة المركز ونصف القطر إذا كان الشكل دائرة أو مجموعة من النقاط على المحيط إذا كان الشكل مضلعًا.

03.jpg

من الأشكال التي يمكن بناؤها باستخدام التوابع التالية

  • ()circle
  • ()ellipse
  • ()inset
  • ()polygon

حيث يعرف كل شكل من خلال مجموعة من النقاط. فبعض التوابع تمرر هذه النقاط كمعاملات، وبعضها الآخر يمرر نقطة واحدة ومقدار الإزاحات ولكن في النهاية جميعها ترسم الأشكال من خلال مجموعة من النقاط. حيث سنقوم بتعريف هذه المتحولات الممررة عند بنائنا للأشكال في المثال القادم من خلال هذه التوابع. كما يمكن تعريف الشكل من خلال استخراجه من صوة باستخدام قناة ألفا وذلك عند تمرير الصورة لخاصية الشكل حيث سيقوم المتصفح باستخراج الشكل بالاعتماد على shape-image-threshold. يُعرف أي شكل من خلال البكسلات التي تحوي قيمة ألفا أكبر من القيمة البدائية كما أن الصورة يجب أن تكون متوافقة مع شروط CORS وبالتالي في هذه الحالة إذا لم يتم إظهار الصورة في الصفحة لأي سبب (مثل أن تكون غير موجودة أو محذوفة) عندها ستيم إظهار شكل الإطار الخاص بها.
خصائص الشكل shape proprties التي تقبل أن تمرر التوابع التي ذُكرت في الأعلى كقيمة لها هي:

  • shape-outside: تقوم هذه الخاصية بتخصيص طريقة التفاف المحتوى حول الشكل من الخارج.
  • shape-inside: تقوم هذه الخاصية بتخصيص طريقة التفاف المحتوى داخل الشكل.

كما يمكن استخدام خاصية shape-outside بالتزامن مع استخدام خاصية shape-margin من أجل إضافة هامش حول الشكل الذي نخصص طريقة انسياب المحتوى حوله وبالتالي بناء فراغ صغير بين المحتوى والشكل. وبنفس الطريقة يمكن استخدام خاصية shape-padding مع خاصية shape-inside من أجل إضافة هامش داخلي بين المحتوى داخل الشكل وحدود الشكل. باستخدام خصائص الشكل وتوابعه يمكن تعريف الشكل كعنصر element من خلال إضافة سطر واحد من تعليمات CSS.

.element {
	shape-outside: circle(); /* content will flow around the circle defined on the element */
}

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

.element {
	shape-outside: url(path/to/image-with-shape.png);
}

ولكن عند تطبيق هذا السطر من تعليمات CSS على الشكل لن يظهر الشكل المطلوب إلا إذا تحقق الشرطين التاليين:

  1. يجب أن يكون العنصر element عائمًا floated حيث أنه من الممكن مستقبلًا أن نحدد الأشكال على العناصر غير العائمة ولكن ليس الآن.
  2. يجب أن يكون العنصر لديه أبعاد واضحة لأنه سيتم استخدام الارتفاع والعرض لبناء العنصر ضمن نظام الإحداثيات.

يتم تعريف الأشكال من خلال مجموعة من النقاط لأنها تملك إحداثيات ديكارتية حيث أن نظام الإحداثيات الديكارتية هو الذي يُعرف من خلاله مواقع العناصر ضمن المتصفح لذلك عند تعريف العنصر element في المثال في الأعلى يتوجب علينا إضافة الارتفاع والعرض بشكل محدد.

.element {
	float: left;
	height: 10em;
	width: 15em;
	shape-outside: circle();
}

مع العلم أن إضافة هذه الأبعاد لا تؤثر على طريقة استجابة الشكل نفسه. وبما أن كل شكل يتم تعريفه بواسطة مجموعة من النقاط التي يتم وضعها باستخدام زوج من الإحداثيات فإن تغيير إحداثيات نقطة ما سيؤثر بشكل مباشر على الشكل الذي تم إنشاؤه. فمثلًا يمكننا إنشاء مضلع مسدس الشكل من خلال استخدام تابع ()polygon حيث يتكون الشكل من ست نقاط ولكن عند تغيير إحداثيات إحدى النقاط الأفقية (النقطة الملونة باللون البرتقالي) عندها سيتغير الشكل الناتج إلى شكل آخر وبالتالي سيؤثر على طريقة تدفق المحتوى داخل الشكل وخارجه.

04.jpg

المربع المرجعي للأشكال

يتم تعريف وبناء أي شكل يُرسم باستخدام CSS داخل ما يسمى بالمربع المرجعي الذي يستعمل لرسم الشكل على العنصر. يمتلك أي عنصر ارتفاع وعرض بالإضافة إلى مربع هامش الذي يحدد المسافة بين العنصر وباقي العناصر في الصفحة margin-box، مربع المحتوى content-box، مربع الهامش الداخلي الذي يحدد المسافة بين المحتوى وحدود الشكل padding-box، مربع الحدود border-box.

05.jpg

حيث تُستخدم إحدى هذه المربعات كمرجع لرسم الشكل على العنصر. افتراضيًا يُستخدم مربع الهامش margin-box كنقطة البداية الأساسية لأي عنصر وبالتالي إذا أردنا تطبيق الشكل على العنصر سيتم أولًا إزاحة الشكل إلى الأسفل ثم تمديده من أسفل زاوية الهامش إلى باقي مربع الهامش margin-box. كما يمكن استخدام قيمة مربع أخرى كمرجع بالإضافة إلى مربع الهامش ويتم ذلك من خلال تمرير اسم المربع بجانب تابع الشكل ()circle إلى خاصية الشكل المُستخدمة shape-outside.

shape-outside: circle(250px at 50% 50%) padding-box;

الكلمة المفتاحية padding-box هي التي خصصت بأن الشكل سيتم تطبيقه على العنصر بالنسبة إلى منطقة الهامش الداخلية للعنصر، أما تابع ()circle فعرّف الشكل الدائري المراد رسمه من خلال ذكر حجمه ومكان توضعه.

تعريف الأشكال باستخدام التوابع

سنبدأ بمثال عن طريقة التفاف النص حول صورة شخصية لمستخدم دائرية الشكل مثل تلك الصور المستخدمة في الصفحات التعريفية عن الأشخاص

06.jpg

حيث ستكون التعليمات في ملف HTML لبناء الصورة وكتابة المحتوى

<img src="http://api.randomuser.me/0.3.2/portraits/men/7.jpg" alt="profile image" />

<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Harum itaque nam blanditiis eveniet enim eligendi quae adipisci?</p>

<p>Assumenda blanditiis voluptas tempore porro quibusdam beatae deleniti quod asperiores sapiente dolorem error! Quo nam quasi soluta reprehenderit laudantium optio ipsam ducimus consequatur enim fuga quibusdam mollitia nesciunt modi.</p>

أما ضمن ملف CSS فسنستخدم تابع ()circle من أجل تطبيق الشكل الدائري على الصورة الشخصية التي وضعناها في ملف HTML. سنستخدم من أجل تدوير الصورة الخاصية border-radius حيث لا تمتلك هذه الخاصية أي تأثير على طريقة انسياب المحتوى داخل أو حول الصورة التي نطبق عليها الشكل. وبمعنى آخر لا تمتلك هذه الخاصية التأثير على منطقة المحتوى content area المتواجدة داخل العنصر element الذي قمنا ببنائه ولا على المحتوى الخارجي حول العنصر، وإنما يكون تأثيرها فقط على شكل الحدود الخاصة بالعنصر وخلفيته إن وُجدت. أي سيبقى المحتوى داخل العنصر مستطيل الشكل والمحتوى الموجود خارج العنصر سينظر ويتعامل مع العنصر نفسه كما لوكان مستطيل الشكل. أي أننا نقوم باستخدام الخاصية border-radius من أجل جعل الصورة فقط دائرية الشكل.

img {
	float: left;
	width: 150px;
	height: 150px;
	border-radius: 50%;
	margin-right: 15px;
}

07.jpg

تبين الصورة السابقة الشكل الذي سيظهر به المحتوى حول الصور الدائرية في المتصفحات القديمة التي التدعم الأشكال في CSS، ولتغيير هذا الشكل المربع في الانسياب حول الصورة الدائرية سنقوم بتعديل التعليمات بما يتوافق مع الشكل الذي أضفناه من خلال استخدام خصائص الشكل

img {
	float: left;
	width: 150px;
	height: 150px;
	border-radius: 50%;

	shape-outside: circle();
	shape-margin: 15px;
}

حيث سنرى في صفحة الويب عند استخدام هذه التعليمات شكلًا دائريًا مُطبّقًا على الصورة وسيظهر المحتوى ملتفًا حول الدائرة كما في أول صورة شاهدناها في المثال.
الطريقة الأساسية في استخدام تابع الدائرة هي

circle() = circle( [<shape-radius>]? [at <position>]? )

إن علامة الاستفهام ? في التعليمة السابقة تشير إلى أن هذه المعاملات الممررة اختيارية ولكن في حال عدم تمريرها سيأخذ التابع القيمة الافتراضية الموجودة في المتصفح وهي رسم الشكل ابتدءًا من مركز العنصر الذي نطبق عليه الشكل. يتم تحديد طول نصف قطر الدائرة بأحد وحدات الطول (البكسل px، النقطة pt…) ويقوم المتصفح برسمه ابتداءً من نقطة المركز وصولًا إلى إحدى أضلاع المستطيل المرجع ويحدد ذلك الخاصية

  • خاصية closest-side: وهي الخاصية الافتراضية وتعني رسم نصف القطر وصولًا إلى أقرب ضلع من أضلاع المستطيل.
  • خاصية furthest-side: وتعني أن المتصفح سيرسم نصف القطر وصولًا إلى أبعد ضلع من أضلاع المستطيل

08.jpg

يمكن تحديد هذه الخاصية وتمريرها كمعامل لتابع رسم الدائرة عند خاصية shape-outside

shape-outside: circle(farthest-side at 25% 25%); /* defines a circle whose radius is half the length of the longest side, positioned at the point of coordinates 25% 25% on the element’s coordinate system*/

shape-inside: circle(250px at 500px 300px); /* defines a circle whose center is positioned at 500px horizontally and 300px vertically, with a radius of 250px */

يعمل تابع رسم الإهليلج (القطع الناقص) ()ellipse فهو يعمل بنفس الطريقة التي يعمل فيها تابع ()circle وبنفس القيم ماعدا أنه بدلًا من تمرير تابع واحد لنصف القطر يجب تمرير اثنين أحدهما من أجل طول نصف القطر على محور الإحداثيات X والآخر لنصف القطر على محور الإحداثيات Y

ellipse() = ellipse( [<shape-radius>{2}]? [at <position>]? )

في حيث أن تابع ()inset يُستخدم لرسم شكل مستطيل مدور الزوايا ويمكن أن نجعل المحتوى ينساب حول هذه الزوايا بشكل دائري أيضًا.

09.jpg

ونمرر لتابع ()inset:

  • أربع قيم إزاحة تحدد قيمة إزاحة الحواف بالنسبة لصندوق المرجع نحو داخل العنصر.
  • معامل اختياري وهو قيمة تدوير الزوايا round حيث يتم تحديد القيمة من خلال border-radius بنفس طريقة استخدامها في تدوير الدائرة التي شرحناها سابقًا، ولكن هنا يجب تمرير أربع قيم.
inset() = inset( offset{1,4} [round <border-radius>]? )

من خلال التعليمات التالية سنقوم برسم مستطيل دائري الزاويا على عنصر عائم floated element

.element {
	float: left;
	width: 250px;
	height: 150px;
	shape-outside: inset(0px round 100px) border-box;
}

تابع الأشكال الأخير الذي سنتحدث عنه هو ()polygon الذي يعرف مجموعة معقدة من الأشكال الهندسية من خلال تحديد عدد من النقاط المعرفة بإحداثياتها الديكارتية (point(x,y والتي من خلالها يتحدد موقع النقطة ديكارتيًا على المتصفح. في المثال التالي نشاهد صورة عائمة في يمين الصورة وتغطي ارتفاع كامل مساحة العرض المتاحة لها، ونريد أن نظهر النص الذي على يسارها بشكل انسيابي حول الساعة الرملية الموجودة داخل الصورة ولذلك سنستخدم تابع ()polygon من أجل تعريف هذا الشكل غير المنتظم على الصورة.

10.jpg

تعليمات CSS التي ستقوم بهذه العملية هي

img.right {
	float: right;
	height: 100vh;
	width: calc(100vh + 100vh/4);
	shape-outside: polygon(40% 0, 100% 0, 100% 100%, 40% 100%, 45% 60%, 45% 40%);
}

يمكن تعيين إحداثيات النقط التي تعرف الشكل من خلال وحدات الطول أو من خلال النسب المئوية التي استخدمتها. ستُنتج التعليمات السابقة الشكل الذي شاهدناه في الأعلى حيث أنها لا تؤثر على باقي أجزاء الصورة الموجودة خارج الشكل المرسوم كما نلاحظ، لأن تطبيق شكل العنصر فقط يؤثر على منطقة تدفق المحتوى من دون أن يغيّر أي شيء في الخلفيات والحدود.
ومن أجل إظهار شكل المضلع الذي رسمناه فإننا بحاجة إلى قص أجزاء من الصورة خارج الشكل وذلك من خلال استخدام خاصية clip-path الموجودة في نموذج الإخفاء CSS Masking Module. تقوم خاصية clip-path على أخذ نفس شكل التابع المستخدم والقيم الممررة له. وبالتالي إذا استخدامنا نفس الشكل المضلع الذي مررناه للخاصية shape-outside فإن هذه الخاصية ستعمل على قص كل أجزاء الصورة خارج الشكل المحدد

img.right {
	float: right;
	height: 100vh;
	width: calc(100vh + 100vh/4);
	shape-outside: polygon(40% 0, 100% 0, 100% 100%, 40% 100%, 45% 60%, 45% 40%);
	/* clip the image to the defined shape */
	clip-path: polygon(40% 0, 100% 0, 100% 100%, 40% 100%, 45% 60%, 45% 40%);
}

وستكون النتيجة النهائية لهذه التعليمات كما في صورة

11.jpg

في الوقت الحالي يتم دعم خاصية clip-path من خلال إضافة بادئة إليها أولًا، مثلًا ستعمل هذه الخاصية مع Chrome إذا أضفنا لها -webkit-. إن خاصية clip-path هي أفضل إضافة مع خصائص الأشكال الأخرى لأنها تساعد في إظهار الأشكال المُنشأة من خلال قص أي جز من العناصر خارج الشكل. تابع()polygon يأخذ أيضًا خيارًا آخر هو إما nonzero أو evenodd والتي تحدد كيفية التعامل مع المناطق داخل الشكل المضلع التي تتقاطع مع نفسها ولمعرفة المزيد عن هذه الخصائص يمكن الإطلاع على SVG fill-rule

تعريف شكل باستخدام صورة

لتعريف شكل باستخدام صورة نحتاج إلى صورة من نمط ألفا والتي يمكن للمتصفح أن يحللها. يُعرّف الشكل بأنه مجموعة من البكسلات التي تمتلك قيمة ألفا أكبر من القيمة الحدّية والتي هي افتراضيًا القيمة 0 (أي شفافة تمامًا) أو يمكن تحديد قيمتها صراحة من خلال الخاصية shape-image-threshold.وبالتالي سيتم استخدام أي بكسل ليس شفافًا كجزء من الشكل المُعرّف من قبل الصورة. في مراحل قادمة من تعريف أشكال CSS قد يتم استخدام بيانات الإضاءة من الصورة بدلًا من استخدام بيانات ألفا. وفي حال حدوث هذا فإن خاصية shape-imgae-threshold سيتم توسيعها لتستخدم مع الإضاءة أو ألفا. الآن سنقوم باستخدام الصورة التالية من أجل تعريف شكل على عنصر ومن ثم تحديد طريقة التفاف النص حول الشكل:

12.jpg

باستخدام الخاصية shape-outside قيمة()url التي تشير إلى الصورة نستطيع جعل المحتوى ينساب حول العنصر الذي يحمل شكل الورقة.

.leaf-shaped-element {
	float: left;
	width: 400px;
	height: 400px;
	shape-outside: url(leaf.png);
	shape-margin: 15px;
	shape-image-threshold: 0.5;
	background: #009966 url(path/to/background-image.jpg);
	mask-image: url(leaf.png);
}


وبالطبع في حال أردنا تطبيق الصورة كخلفية في العنصر فإنه يجب قص الصورة الموجودة خارج الشكل من خلال الخاصية mask-image حيث أنه لايمكن استخدام خاصية clip-path مع الصور صاحبة القيمة ألفا، والنتيجة ستكون بالشكل التالي

13.jpg

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

تفاعل الأشكال في CSS مع التصميم المُتجاوب

هل تستطيع الأشكال المبنية باستخدام CSS تتناسب مع التصميم المتجاوب؟ التخصيص الحالي لخاصية shape-outside تستطيع العمل مع التصميم المتجاوب وذلك لأنه يسمح بتحديد أبعاد العنصر من خلال النسب المئوية أو أحد وحدات الطول، ويمكن تحديد نقاط الشكل الممررة كمعاملات لتابع الشكل. وهذا يعني أن خاصية العنصر shape-outside ستكون متجاوبة responsive بشكل كامل ولكن خاصية shape-inside ليست متجاوبة responsive إلى الآن ولكن سيتم إدخالها في المرحلة الثانية حتى يتم حل بعض الحدود.

الأدوات المستخدمة لبناء أشكال CSS

إن بناء الأشكال المعقدة بالاعتماد على تابع Shape يعد مهمة شاقة خصوصًا عند بناء العديد من الأشكال المضلعة المعقدة من خلال تمرير الإحداثيات الديكارتية لعدة نقاط من الشكل باستخدام التابع ()polygon ولكن لحسن الحظ فإن Adobe وفرّت العديد من الأدوات التفاعلية التي تقوم بهذا العمل بشكل أسهل. هنا يوجد عدة أدوات تسمح لنا ببناء الأشكال المضلعة من خلال الرسم ثم تتولى الأداة توليد تابع الأشكال الخاص بها. ولكن يوجد بعض المحدوديات في هذه البرامج إذا أردنا رسم الشكل بالاعتماد على صورة محددة لأنه لايوجد طريقة لإدخال الصورة إلى الأدوات ومن ثم إنشاء الشكل من خلالها. الأداة الأكثر تطورًا في هذا المجال لرسم الأشكال التفاعلية المتطورة بناها فريق تطوير الويب التابع لمنصة Adobe وتم وضعها كإضافة لمحرر brackets المجاني الخاص بالشركة.

14.gif

مستقبل الحالات المبعدة من المعالجة في CSS

لبناء أي شكل في CSS يجب أن يكون خاضعًا لعدد من المواصفات المحددة، فمثلًا لا يمكن تعريف الخاصيتين shape-inside و shape-outside إلا لأشكال مخصصة ولكن الحالات المقصاة هذه سيتم تعريف خصائص تسمح بالتفاف المحتوى حول العناصر مهما كان شكلها حتى لو لم تكن عائمة في المرحلة التالية من تطوير الأشكال في CSS وسيصبح بالإمكان التفاف النص على كامل الشكل من اتجاهات مختلفة كما في المثال الموضح بالصورة

15.jpg

ترجمة –وبتصرّف- للمقال CSS Shapes 101 لصاحبته Sara soueidan


تفاعل الأعضاء

أفضل التعليقات



انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أضف تعليق

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • أضف...