ویژگی shape-outside در سی اس اس

shape-outside

از ویژگی shape-outside برای تغییر هندسی محیط اطراف یک عنصر شناور (دارای ویژگی float) استفاده می شود.

تمام عناصر یک صفحه وب بصورت پیشفرض در یک جریانی از مستطیل ها در کنار هم قرار گرفته اند. این بدین معنی است که اگر حتی به عنوان مثال با استفاده از ویژگی border-radius ظاهر یکی از این عناصر را از حالت مستطیل به دایره تبدیل کنیم باز هم عناصری که اطراف این عنصر وجود دارند طوری چیده می شوند که عنصر همچنان حالت مستطیل دارد نه دایره.

با استفاده از ویژگی shape-outside می توانیم این رفتار را تغییر دهیم یعنی عناصر اطراف عنصر به شکل آن عنصر در اطراف آن جمع شوند. به عنوان مثال اگر عنصر حالت دایره دارد عناصر اطراف آن نیز به همان حالت دور آن جمع شوند.

در نتیجه می توان گفت ویژگی shape-outside جریان یا Flow عناصر را در کنار هم از حالت مستطیل شکل به حالت های مختلفی می تواند تغییر دهد.

تصویر زیر گویای این مطلب می باشد:

ویژگی shape-outside در css

مواد لازم

برای اینکه این ویژگی کار کند دو شرط باید برقرار باشد:

  1. عنصر باید حتما شناور باشد: یعنی باید مقدار ویژگی float آن چیزی غیر از none باشد.
  2. ابعاد عنصر باید مشخص شده باشد: از عرض و ارتفاع ثبت شده عنصر برای تعیین سیستم مختصات آن استفاده می شود.

دلیل نیاز به یک سیستم مختصات این است که توابع اشکال سی اس اس برای تعریف یک شکل نیاز به مختصات دارند.

Reference Box

چارچوب مرجع یا Reference Box به چارچوب مجازی گفته می شود که از آن استفاده می شود تا شکل روی عنصر بوجود آید و سیستم مختصات روی این چارچوب قرار می گیرد.

مقادیر چارچوب مرجع به عنوان یک کلمه کلیدی برای ویژگی shape-outside تعیین می شوند که این مقادیر شامل content-box، padding-box، border-box، margin-box می باشند. برای اطلاعات بیشتر در مورد این مقادیر می توانید به ویژگی box-sizing مراجعه کنید.

مقدار پیشفرض چارچوب مرجع margin-box می باشد که این بدین معنی است که اگر عنصری که قرار است شکل روی آن اعمال شود margin داشته باشد مختصات شکل تا لبه های Margin یا همان فاصله بیرونی عنصر نیز گسترده می شود.

یعنی مثلا اگر قرار است شکل اعمال شده بر روی عنصر دایره باشد این دایره تنها به بزرگی عنصر نخواهد بود بلکه به بزرگی عنصر و فاصله بیرونی آن خواهد بود.

برای بقیه مقادیر هم به همین صورت می توان این موضوع را اعمال کرد مثلا اگر چارچوب مرجع border-box باشد گسترده شکل دایره فقط تا لبه های حاشیه عنصر یا همان border آن خواهد بود.

به عنوان نمونه مثال های زیر معتبر می باشند:


shape-outside: circle(15em at 10% 40%); /* Default: margin-box */

shape-outside: circle(15em at 10% 40%) content-box;

shape-outside: circle(15em at 10% 40%) border-box;

shape-outside: circle(15em at 10% 40%) padding-box;

ساخت شکل بصورت دستی با استفاده از توابع شکل

برای اینکه شکل های مختلف را برای این ویژگی تعیین کنیم می توانیم از توابع شکل سی اس اس استفاده کنیم. که در ادامه مثال های آنها آورده شده اند. برای آشنایی کامل با این توابع به مطلب <basic-shape> مراجعه کنید.

inset


.element {
  width: 10em;
  height: 10em;
  float: left; 
  shape-outside: inset(30% 20% 20% 0);
}

circle


.element {
  width: 10em;
  height: 10em;
  float: left; 
  shape-outside: circle(farthest-side at 25% 25%);
}

ellipse


.element {
  width: 10em;
  height: 10em;
  float: left;
  shape-outside: ellipse(100px 50px at 30% 50%) content-box;
}

polygon


.element {
  width: 10em;
  height: 10em;
  float: left;
  shape-outside: polygon(50px 0px, 100px 100px, 0px 100px);
}

به عنوان مثال نمونه زیر را در نظر بگیرید که از تابع polygon بصورت دستی برای ساخت شکل کمک گرفته است:

 

See the Pen CSS Shapes by Mojtaba Seyedi (@seyedi) on CodePen.


 

shape-outside ظاهر عنصر را تغییر نمی دهد

shape-outside شکل جریان محتوای اطراف عنصر شناور را مشخص می کند و هیچ تاثیری بر روی شکل عنصر شناور مورد نظر را نخواهد داشت.

تصویر متحرک زیر این موضوع را بهتر نمایش می دهد:

 
reference-box در ویژگی shape-outside
 

همانطور که مشاهده می کنید این ویژگی هیچ تاثیری روی ظاهر عنصر ندارد بلکه جریان عناصر و محتوای اطراف آن را کنترل می کند.

حال اگر بخواهیم ظاهر عنصر را نیز به همان شکل در بیاوریم چه؟

تغییر شکل خود عنصر

برای تغییر شکل خود عنصر می توانیم به هر روشی که می دانیم و با شرایط عنصر و کار ما سازگار است عمل کنیم. به عنوان نمونه شاید برای ما کافی باشد که از border-radius استفاده کنیم چرا که ظاهر شکل ما فقط کافی است به حالت دایره در بیاید.

اگر دنبال اشکال پیچیده تری هستیم می توانیم از ویژگی clip-path برای عنصر مورد نظر استفاده کنیم.

مثال زیر را بررسی کنید:

 

See the Pen shape-outside and clip-path by Mojtaba Seyedi (@seyedi) on CodePen.


 

ساخت شکل با استفاد از چارچوب مرجع

فرض کنید عنصر ما بوسیله ویژگی border-radius دایره شکل شده باشد. همانطور که تا الان متوجه شدیم این موضوع باعث نمی شود که محتوای اطراف این عنصر شناور به شکل دایره به جریان بیافتند.

تا الان یاد گرفتیم که می توانیم با استفاده از تابع شکل circle برای ویژگی shape-outside این امر را تغییر دهیم. راه حل دیگری برای این موضوع نیز وجود دارد و حتما نیاز نیست که از تابع دایره استفاده کنیم.

می توانیم فقط با استفاده از تعیین چارچوب مرجع برای این ویژگی محتوای اطراف عنصر را بصورت دایره شکل اطراف عنصر جمع کنیم.


.element {
  width: 10em;
  height: 10em;
  float: left;
  background: #4CAF50;  
  
  border-radius: 50%;
  
  shape-outside: border-box;
}

البته در این مورد فقط محدود به border-box نیستیم و می توانیم از مقادیر دیگر نیز استفاده کنیم. فرض کنید عنصر دارای margin یا همان فاصله بیرونی باشد و میخواهیم شکل تا فضای فاصله بیرونی را بپوشاند می توانیم از margin-box استفاده کنیم و خروجی بصورت زیر می باشد:

 
استفاده از چارچوب مرجع برای اعمال شکل با استفاده از shape-outside
 

ساخت شکل با استفاد از تصویر (غیر دستی و خودکار)

تا الان فرا گرفتیم که چگونه اشکال مختلف را بصورت دستی توسط توابع شکل بوجود آوریم. آنچه که در مورد این ویژگی بسیار جالب و حیرت انگیز است این است که می توان شکل مورد نظر را از درون یک تصویر بیرون کشید.

فرض کنید تصویری بصورت زیر داریم:

 
تصویر گل با کانال آلفا
 

همانطور که مشاهده می کنید تصویر دارای کانال آلفا است و قسمت هایی از آن بصورت transparent یا شفاف می باشد.

حال اگر این عنصر تصویر را بصورت شناور در کنار مقداری محتوا قرار دهیم اتفاق زیر می افتد:


<img src="flower.png" alt="تصویر گل با کانال آلفا یا همون ترنسپرنت خودمون">
<p>یک سری محتوای خوب و دراز...</p>


img {
  float: right;
}

توجه داشته باشید که تصویر بصورت ذاتی دارای عرض و ارتفاع است به همین دلیل در اینجا عرض و ارتفاع در سی اس اس مشخص نشده است.

 
متن و گل بدون استفاده از ویژگی shape-outside
 

خیلی زشته دیگه… :)

بسیار خوب برای اینکه از این حالت در بیاید ما تا الان یک راه می دانیم و آن استفاده از توابع شکل می باشد. در این مثال تابع polygon می تواند به ما کمک کند.

اما این روش دشوار است چرا که باید نقاط مختلف را بصورت دستی تعیین کنیم. این همان روش دستی است.

روش خودکار استفاده از تصویر برای انجام این کار است که کافی است بصورت زیر آدرس تصویر شفاف را به ویژگی shape-outside بدهیم که مرورگر بصورت خودکار شکل را از تصویر استخراج می کند و ما خروجی زیر را خواهیم داشت:


img {
  float: right;  
  shape-outside: url(flower.png); 
}

 
استفاده از تصویر برای ویژگی shape-outside
 

واضح است که تصویر می تواند دارای چند شکل باشد و همچنان این ویژگی کار خود را انجام می دهد. در نمونه زیر محتوا با توجه به اشکال مختلف در اطرف عنصر جریان دارد:

 
استفاده از اشکال چندگانه برای ویژگی shape-outside
 

برای این ویژگی باید تصویر دو ویژگی زیر را داشته باشد:

  1. باید تصویر دارای کانال آلفا باشد: برای ساخت این تصاویر می توانیم از فوتوشاپ استفاده کنیم و با فرمت PNG آنها را ذخیره کنیم.
  2. تصویر باید CORS compatible باشد. و اگر این قابلیت برای شما وجود ندارد تصویر مورد نظر باید بر روی سرور یکسان باشد.

اگر به هر دلیلی تصویر برای مرورگر قابل دسترس نباشد هیچ شکلی اعمال نخواهد شد.

نکته دیگر اینکه اگر شما مثال گل بالا را آزمایش کنید محتوا به گل می چسبد و ظاهر جالبی ندارد برای جلوگیری از این اتفاق می توان از ویژگی shape-margin استفاده کرد. همچنین زمانی که از روش تصویر برای بوجود آوردن شکل استفاده می کنیم ویژگی دیگری می توان این کار را کنترل کند که در مطالب بعدی با آن آشنا خواهیم شد نام این ویژگی shape-image-threshold می باشد.

قرار دادن محتوا بین دو شکل

فرض کنید بخواهیم تصویر زیر را با استفاده از HTML و CSS پیاده سازی کنیم:

 
قرار دادن محتوا بین اشکال مختلف با استفاده از ویژگی shape-outside
 

ساختار HTML ما بصورت زیر خواهد بود:


<div>
  <div class="left-shape"></div>
  <div class="right-shape"></div>
  
  Lorem ipsum...
</div>

سپس دو عنصر مورد نظر را به اطراف شناور می کنیم:


.left-shape{
  float: left;
  width: 50%;
  height: 100%;
}

.right-shape{
  float: right;
  width: 50%;
  height: 100%;
}

حال کافی است که شکل مورد نظر را روی دو عنصر اعمال کنیم که از تابع polygon برای این موضوع استفاده می کنیم و خروجی مانند زیر خواهیم داشت:


.left-shape{
  float: left;
  width: 50%;
  height: 100%;
  /* اعمال شکل روی عنصر */
  shape-outside: polygon(0px 0px, 714px 0px, 705px 200px, 653px 262px, 651px 345px, 722px 381px, 693px 411px, 690px 455px, 776px 476px, 751px 516px, 751px 556px, 851px 559px, 846px 611px, 721px 650px, 710px 694px, 753px 728px, 782px 790px, 800px 839px, 761px 898px, 657px 923px, 625px 1024px, 598px 1199px, 0px 1200px);
}

.right-shape{
  float: right;
  width: 50%;
  height: 100%;

  /* اعمال شکل روی عنصر */
  shape-outside: polygon(94px 1007px, 82px 886px, -2px 840px, -2px 794px, 12px 756px, 15px 685px, 58px 618px, 139px 600px, 154px 532px, 89px 472px, 95px 414px, 143px 374px, 219px 285px, 146px 177px, 212px 1px, 960px 0px, 960px 1200px, 59px 1199px);
}

 
اعمال شکل رو عناصر با استفاده از تابع polygon
 

این مثال را می توانید بصورت زنده در این آدرس مشاهده کنید.

متحرک سازی اشکال

تا الان می دانیم که دو روش برای استفاده از shape-outside وجود دارد. روش خودکار یعنی استفاده از یک تصویر و روش دستی یعنی استفاده از توابع شکل.

⚠ زمانی که از روش خودکار یعنی از تصویر استفاده می کنیم نمی توانیم روی shape-outside ترنزیشن یا انیمیشن اعمال کنیم.

⚠ اما در روش دستی یعنی زمانی که از توابع شکل استفاده می کنیم می توانیم روی اشکال ترنزیشن یا انیمیشن اعمال کنیم.

در مطلب مربوط به clip-path در مورد متحرک سازی شکل های مختلف بحث کردیم که همان شرایط برای این ویژگی نیز صدق می کند. از مهمترین این شرایط باید به این اشاره کرد که فقط زمانی یک شکل قابل متحک سازی است که در حالت های مختلف شکل تعداد نقطه های آن برابر باشد.

و یا به عنوان نمونه در مورد تابع دایره، تغییری از circle(30%) به circle(50%) با ترنزیشن قابل انجام است اما تغییر circle(closest-side) به circle(farthest-side) با ترنزیشن قابل اجرا نیست و پرش خواهیم دید.


.element {
  shape-outside: circle(30%);
  transition: shape-outside 1s;
  float: left;
}

.element:hover {
  shape-outside: circle(50%);
}

 
متحرک سازی shape-outside در سی اس اس
 

همینطور می توان برای تابع چندضلعی عمل کرد اما توجه کنید چطور مجبور هستیم تا نقاط را با تعداد یکسانی تعریف کنیم هر چند که مثلا برای یک مثلث نیاز به چهار نقطه نداریم:


.element {
  shape-outside: polygon(0 0, 100% 0, 100% 100%, 0 100%);
  transition: shape-outside 1s;
}

.element:hover {
  /* مجبوریم یک نقطه اضافه تعریف کنیم که کاربردی در رسم شکل نداره */
  shape-outside: polygon(0 0, 100% 50%, 100% 50%, 0 100%);
}

 
ترنزیشن و انیمیشن اشکال در ویژگی shape-outside
 

در اینجا ما هدف آموزشی داریم ولی این متحرک سازی ها معمولا از نظر کاربر جالب نیستند پس قبل از استفاده از آن ها بخوبی شرایط را در نظر بگیریم.

ابزارهای کمکی برای تعریف شکل

ساخت اشکال مختلف بصورت دستی کار سختی است. ابزارهایی مثل Clippy وجود دارند که این کار را ساده تر می کنند:

پشتیبانی مرورگر ها

5 دیدگاه برای “shape-outside

  1. سلام آقای سیدی
    یه سؤال داشتم، اینکه اگر بخوایم یه عنصر(مثلا دایره) رو وسط قرار بدیم و نوشته ها اطرافش قرار بگیرن، باید به چه صورت این کار را بکنیم؟

  2. سلام مجدد، اینکه نوشتید برای ساخت شکل با استفاده از تصویر، تصویر باید CORS compatible باشد، یعنی چی؟
    منظور از CORS compatible چیه؟

    1. سازگاری CORS

      چیزی که هنگام ایجاد اشکال از یک تصویر به آن توجه خواهید کرد این است که تصویری که شما استفاده می کنید باید با CORS سازگار باشد. تصویری که در همان دامنه سایت شما کار می کند باید کار کند ، اما اگر تصاویر شما در یک دامنه متفاوت مانند CDN میزبانی می شوند ، باید اطمینان حاصل کنید که آنها هدر های صحیح را ارسال می کنند تا امکان استفاده از آنها برای شکل ها فراهم شود. به دلیل این نیاز برای تصاویر سازگار با CORS ، اگر در حال پیش نمایش پرونده خود به صورت محلی و بدون استفاده از یک سرور وب محلی باشید ، شکل شما کار نخواهد کرد.
      DevTools می تواند به شما در شناسایی خطاهای CORS کمک کند. در Chrome کنسول به شما در مورد مشکلات CORS هشدار می دهد. در Firefox در صورت بازرسی از اموال ، از این واقعیت مطلع می شوید که نمی توان تصویر را بارگیری کرد. این باید شما را به این واقعیت هشدار دهد که به دلیل CORS نمی توان از تصویر شما به عنوان منبع شکل استفاده کرد.

  3. در “قرار دادن محتوا بین دو شکل” استفاده از تابع url بسیار بهتر است از تابع polygon.
    برای هر شکل url خودش را وارد می‌کنیم.

سوال داری؟ برو به پنل پرسش و پاسخ

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *