از ویژگی shape-outside
برای تغییر هندسی محیط اطراف یک عنصر شناور (دارای ویژگی float) استفاده می شود.
تمام عناصر یک صفحه وب بصورت پیشفرض در یک جریانی از مستطیل ها در کنار هم قرار گرفته اند. این بدین معنی است که اگر حتی به عنوان مثال با استفاده از ویژگی border-radius ظاهر یکی از این عناصر را از حالت مستطیل به دایره تبدیل کنیم باز هم عناصری که اطراف این عنصر وجود دارند طوری چیده می شوند که عنصر همچنان حالت مستطیل دارد نه دایره.
با استفاده از ویژگی shape-outside
می توانیم این رفتار را تغییر دهیم یعنی عناصر اطراف عنصر به شکل آن عنصر در اطراف آن جمع شوند. به عنوان مثال اگر عنصر حالت دایره دارد عناصر اطراف آن نیز به همان حالت دور آن جمع شوند.
در نتیجه می توان گفت ویژگی shape-outside
جریان یا Flow عناصر را در کنار هم از حالت مستطیل شکل به حالت های مختلفی می تواند تغییر دهد.
تصویر زیر گویای این مطلب می باشد:
مواد لازم
برای اینکه این ویژگی کار کند دو شرط باید برقرار باشد:
- عنصر باید حتما شناور باشد: یعنی باید مقدار ویژگی
float
آن چیزی غیر ازnone
باشد. - ابعاد عنصر باید مشخص شده باشد: از عرض و ارتفاع ثبت شده عنصر برای تعیین سیستم مختصات آن استفاده می شود.
دلیل نیاز به یک سیستم مختصات این است که توابع اشکال سی اس اس برای تعریف یک شکل نیاز به مختصات دارند.
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
شکل جریان محتوای اطراف عنصر شناور را مشخص می کند و هیچ تاثیری بر روی شکل عنصر شناور مورد نظر را نخواهد داشت.
تصویر متحرک زیر این موضوع را بهتر نمایش می دهد:
همانطور که مشاهده می کنید این ویژگی هیچ تاثیری روی ظاهر عنصر ندارد بلکه جریان عناصر و محتوای اطراف آن را کنترل می کند.
حال اگر بخواهیم ظاهر عنصر را نیز به همان شکل در بیاوریم چه؟
تغییر شکل خود عنصر
برای تغییر شکل خود عنصر می توانیم به هر روشی که می دانیم و با شرایط عنصر و کار ما سازگار است عمل کنیم. به عنوان نمونه شاید برای ما کافی باشد که از 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
استفاده کنیم و خروجی بصورت زیر می باشد:
ساخت شکل با استفاد از تصویر (غیر دستی و خودکار)
تا الان فرا گرفتیم که چگونه اشکال مختلف را بصورت دستی توسط توابع شکل بوجود آوریم. آنچه که در مورد این ویژگی بسیار جالب و حیرت انگیز است این است که می توان شکل مورد نظر را از درون یک تصویر بیرون کشید.
فرض کنید تصویری بصورت زیر داریم:
همانطور که مشاهده می کنید تصویر دارای کانال آلفا است و قسمت هایی از آن بصورت transparent یا شفاف می باشد.
حال اگر این عنصر تصویر را بصورت شناور در کنار مقداری محتوا قرار دهیم اتفاق زیر می افتد:
<img src="flower.png" alt="تصویر گل با کانال آلفا یا همون ترنسپرنت خودمون">
<p>یک سری محتوای خوب و دراز...</p>
img {
float: right;
}
توجه داشته باشید که تصویر بصورت ذاتی دارای عرض و ارتفاع است به همین دلیل در اینجا عرض و ارتفاع در سی اس اس مشخص نشده است.
خیلی زشته دیگه… :)
بسیار خوب برای اینکه از این حالت در بیاید ما تا الان یک راه می دانیم و آن استفاده از توابع شکل می باشد. در این مثال تابع polygon می تواند به ما کمک کند.
اما این روش دشوار است چرا که باید نقاط مختلف را بصورت دستی تعیین کنیم. این همان روش دستی است.
روش خودکار استفاده از تصویر برای انجام این کار است که کافی است بصورت زیر آدرس تصویر شفاف را به ویژگی shape-outside
بدهیم که مرورگر بصورت خودکار شکل را از تصویر استخراج می کند و ما خروجی زیر را خواهیم داشت:
img {
float: right;
shape-outside: url(flower.png);
}
واضح است که تصویر می تواند دارای چند شکل باشد و همچنان این ویژگی کار خود را انجام می دهد. در نمونه زیر محتوا با توجه به اشکال مختلف در اطرف عنصر جریان دارد:
برای این ویژگی باید تصویر دو ویژگی زیر را داشته باشد:
- باید تصویر دارای کانال آلفا باشد: برای ساخت این تصاویر می توانیم از فوتوشاپ استفاده کنیم و با فرمت PNG آنها را ذخیره کنیم.
- تصویر باید CORS compatible باشد. و اگر این قابلیت برای شما وجود ندارد تصویر مورد نظر باید بر روی سرور یکسان باشد.
اگر به هر دلیلی تصویر برای مرورگر قابل دسترس نباشد هیچ شکلی اعمال نخواهد شد.
نکته دیگر اینکه اگر شما مثال گل بالا را آزمایش کنید محتوا به گل می چسبد و ظاهر جالبی ندارد برای جلوگیری از این اتفاق می توان از ویژگی shape-margin استفاده کرد. همچنین زمانی که از روش تصویر برای بوجود آوردن شکل استفاده می کنیم ویژگی دیگری می توان این کار را کنترل کند که در مطالب بعدی با آن آشنا خواهیم شد نام این ویژگی shape-image-threshold می باشد.
قرار دادن محتوا بین دو شکل
فرض کنید بخواهیم تصویر زیر را با استفاده از HTML و CSS پیاده سازی کنیم:
ساختار 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);
}
این مثال را می توانید بصورت زنده در این آدرس مشاهده کنید.
متحرک سازی اشکال
تا الان می دانیم که دو روش برای استفاده از 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%);
}
همینطور می توان برای تابع چندضلعی عمل کرد اما توجه کنید چطور مجبور هستیم تا نقاط را با تعداد یکسانی تعریف کنیم هر چند که مثلا برای یک مثلث نیاز به چهار نقطه نداریم:
.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%);
}
در اینجا ما هدف آموزشی داریم ولی این متحرک سازی ها معمولا از نظر کاربر جالب نیستند پس قبل از استفاده از آن ها بخوبی شرایط را در نظر بگیریم.
ابزارهای کمکی برای تعریف شکل
ساخت اشکال مختلف بصورت دستی کار سختی است. ابزارهایی مثل Clippy وجود دارند که این کار را ساده تر می کنند:
سلام آقای سیدی
یه سؤال داشتم، اینکه اگر بخوایم یه عنصر(مثلا دایره) رو وسط قرار بدیم و نوشته ها اطرافش قرار بگیرن، باید به چه صورت این کار را بکنیم؟
سلام مجدد، اینکه نوشتید برای ساخت شکل با استفاده از تصویر، تصویر باید CORS compatible باشد، یعنی چی؟
منظور از CORS compatible چیه؟
سازگاری CORS
چیزی که هنگام ایجاد اشکال از یک تصویر به آن توجه خواهید کرد این است که تصویری که شما استفاده می کنید باید با CORS سازگار باشد. تصویری که در همان دامنه سایت شما کار می کند باید کار کند ، اما اگر تصاویر شما در یک دامنه متفاوت مانند CDN میزبانی می شوند ، باید اطمینان حاصل کنید که آنها هدر های صحیح را ارسال می کنند تا امکان استفاده از آنها برای شکل ها فراهم شود. به دلیل این نیاز برای تصاویر سازگار با CORS ، اگر در حال پیش نمایش پرونده خود به صورت محلی و بدون استفاده از یک سرور وب محلی باشید ، شکل شما کار نخواهد کرد.
DevTools می تواند به شما در شناسایی خطاهای CORS کمک کند. در Chrome کنسول به شما در مورد مشکلات CORS هشدار می دهد. در Firefox در صورت بازرسی از اموال ، از این واقعیت مطلع می شوید که نمی توان تصویر را بارگیری کرد. این باید شما را به این واقعیت هشدار دهد که به دلیل CORS نمی توان از تصویر شما به عنوان منبع شکل استفاده کرد.
سلام وقت بخیر
خیلی متشکرم بابت راهنماییتون.
در “قرار دادن محتوا بین دو شکل” استفاده از تابع url بسیار بهتر است از تابع polygon.
برای هر شکل url خودش را وارد میکنیم.