مشخصات مقاله
-
978
-
0.0
-
3357
-
0
-
0
آموزش کار با دستور extend در Sass
آموزش Sass – کار با دستور @extend
گاهی به هنگام طراحی یک صفحه لازم می شود که یک کلاس علاوه بر style های (دستورات تنظیم ظاهر) خود، style های کلاس دیگری را نیز داشته باشد. معمول ترین روش برای مدیریت این سناریو، استفاده از هر دو کلاس کلی و جزئی در HTML می باشد. برای مثال فرض کنید می خواهید دو نوع خطا را برای کاربر نمایش دهید. علاوه بر خطای جدی، ویژه نمایش خطای عادی نیز یک ظاهر ویژه طراحی کرده اید و برای این منظور کد HTML یا Markup خود را به این صورت تنظیم کرده اید:
< div class="error seriousError" > Oh no! You've been hacked! < /div >
style های لازم را نیز به این صورت:
.error {
border: 1px #f00;
background-color: #fdd;
}
.seriousError {
border-width: 3px;
}
همان طور که مشاهده می کنید، متاسفانه بایستی همیشه از .error و .seriousError استفاده کنیم و این در آینده نگهداشت فایل را سخت می کند، سبب رخداد خطاهای پیچیده و نگرانی هایی در خصوص style ها و دستورات بی معنا (non-semantic) در کد HTML می شود.
با استفاده از دستور @extend می توان این معضل را به راحتی برطرف کرد. دستور ذکر شده به Sass اعلان می کند که یک selector می تواند style های selector دیگر را به ارث برده و علاوه بر style های اختصاصی خود از style های ارث برده شده در تنظیم ظاهر المان مورد انتخاب استفاده نماید. مثال:
.error {
border: 1px #f00;
background-color: #fdd;
}
.seriousError {
@extend .error;
border-width: 3px;
}
به قطعه کد زیر کامپایل می شود:
.error, .seriousError {
border: 1px #f00;
background-color: #fdd;
}
.seriousError {
border-width: 3px;
}
همان طور که مشاهده می کنید، تمامی style های تعریف شده برای .error به .seriousError نیز اعمال می شوند. به عبارت دیگر .seriousError علاوه بر style های اختصاصی خود، قادر خواهد بود از style های کلاس .error نیز استفاده کند.
سایر دستوراتی که در کلاس .error تعریف شده اند، در کلاس .seriousError نیز اعمال می شوند. برای مثال اگر ویژه ی خطاهایی که در صورت رخداد حملات هکرها صادر می شود، style های اختصاصی تعریف کرده باشید:
.error.intrusion {
background-image: url("/image/hacked.png");
}
آنگاه المان< div class="seriousError intrusion" > نیز فایل hacked.png را در پس زمینه ی خود نشان خواهد داد.
چگونگی عملکرد دستور @extend
دستور @extend انتخابگر ارث برنده ( کلاس .seriousError) را در هر جایی از فایل stylesheet مورد نظر که selector ارث بری شده (همان کلاس .error) در آن ظاهر می شود نیز درج می کند. بنابراین این مثال در زیر بدین صورت پیاده سازی می شود:
.error {
border: 1px #f00;
background-color: #fdd;
}
.error.intrusion {
background-image: url("/image/hacked.png");
}
.seriousError {
@extend .error;
border-width: 3px;
}
به کد زیر کامپایل می شود:
.error, .seriousError {
border: 1px #f00;
background-color: #fdd; }
.error.intrusion, .seriousError.intrusion {
background-image: url("/image/hacked.png"); }
.seriousError {
border-width: 3px; }
لازم به ذکر است زمانی که دو selector بایکدیگر ادغام می شوند، دستور @extend به قدری هوشمند است که از تکرار غیر ضروری کد خودداری می کند. به عبارت دیگر اسم کلاس را بدین صورت .seriousError.seriousError تکرار نمی کند و در عوض آن را به شکل مختصر .seriousError می نویسد. علاوه بر آن، selector هایی مانند #main#footer تولید نمی کند که با هیچ المانی منطبق نیستند.
ارث بری selector های تودرتو و پیچیده
در Sass این تنها selector های کلاس نیستند که قابل ارث بری و extend هستند. می توان هر selector ای که را که حتی فقط یک المان را دربرمی گیرد مانند .special.cool, a:hover یا a.user[href^="http://"] به ارث برد.مثال:
.hoverlink {
@extend a:hover;
}
بدیهی است که تمامی style هایی که برای المان a:hover تعریف شده اند، برای .hoverlink نیز اعمال می شوند. مثال:
.hoverlink {
@extend a:hover;
}
a:hover {
text-decoration: underline;
}
به کد زیر کامپایل می شود:
a:hover, .hoverlink {
text-decoration: underline;
}
مانند .error.intrusion در مثال بالا، تمامی rule یا دستوراتی که از المان a:hover استفاده می کنند، بر روی .hoverlink نیز اعمال می شوند، حتی اگر چندین selector داشته باشند. مثال:
.hoverlink {
@extend a:hover;
}
.comment a.user:hover {
font-weight: bold;
}
به کد زیر کامپایل می شود:
.comment a.user:hover, .comment .user.hoverlink {
font-weight: bold;
}
ارث بری از چندین selector
یک selector واحد می تواند از چند selector همزمان ارث بری داشته باشد. به عبارت دیگر، selector مورد نظر کلیه ی style های تعریف شده در selector هایی که از آن ها ارث بری کرده را در خود اعمال خواهد کرد. مثال:
.error {
border: 1px #f00;
background-color: #fdd;
}
.attention {
font-size: 3em;
background-color: #ff0;
}
.seriousError {
@extend .error;
@extend .attention;
border-width: 3px;
}
به کد زیر کامپایل می شود:
.error, .seriousError {
border: 1px #f00;
background-color: #fdd;
}
.attention, .seriousError {
font-size: 3em;
background-color: #ff0;
}
.seriousError {
border-width: 3px;
}
اگر بخواهیم دقیق توضیح دهیم، class selector ای که .seriousError نام دارد، تمامی style های تعریف شده در بدنه ی دو کلاس .error و .attention را به واسطه ی دستور @extend و قابلیت ارث بری Sass در خود اعمال می کند.
در مثال بالا، تمامی المان هایی که کلاس .seriousError به آن ها اعمال می شود، به واسطه ی دستور @extend از style های دو کلاس .error و .attention نیز برخوردار خواهد بود. لازم به ذکر است که style هایی که بعده ها در فایل تعریف می شوند، از اولویت بالاتری برخوردار هستند: مقدار background color از .seriousError بجای اینکه #fdd باشد، برابر #ff0 خواهد بود چرا که .attention پس از کلاس .error تعریف شده است.
می توان با جداسازی selector ها به وسیله ی ویرگول، از چندین کلاس ارث بری کرد. به عبارت دیگر می توان پس از درج دستور @extend، کلاس هایی که می خواهید style های تعریف شده در آن ها را به ارث ببرید، در یک لیست که با ویرگول از هم جدا شده اند ذکر کنید. بدین وسیله می توان همزمان از دو یا چند selector ارث بری کرد. برای مثال دو عبارت @extend .error, .attention و @extend .error; @extend .attention معادل هستند و هر دو در آن واحد چندین کلاس را به ارث می برند.
ارث بری به صورت پشت سرهم و زنجیره ای (Chaining Extends)
این امکان وجود دارد که یک selector از selector دیگر ارث بری داشته که آن باز خود از یک selector دیگر ارث بری می کند. برای مثال:
.error {
border: 1px #f00;
background-color: #fdd;
}
.seriousError {
@extend .error;
border-width: 3px;
}
.criticalError {
@extend .seriousError;
position: fixed;
top: 10%;
bottom: 10%;
left: 10%;
right: 10%;
}
همان طور که می بینید کلاس seriousError. خود از کلاس .error ارث بری داشته و کلاس سوم که .criticalError می باشد style های کلاس دوم (seriousError) را به ارث برده است.
در این حالت هر المانی که کلاس .seriousError را دارد، متعاقبا کلاس .error را نیز به ارث می برد و المانی هم که کلاس .criticalError به آن اعمال شود، طبیعتا style های کلاس .seriousError را خواهد داشت.
کد بالا به صورت زیر کامپایل می شود:
.error, .seriousError, .criticalError {
border: 1px #f00;
background-color: #fdd;
}
.seriousError, .criticalError {
border-width: 3px;
}
.criticalError {
position: fixed;
top: 10%;
bottom: 10%;
left: 10%;
right: 10%;
}
Selector Sequences (selector های متوالی)
در حال حاضر امکان ارث بردن از selector های متوالی مانند .foo .bar یا .foo + .bar وجود ندارد. اما selector هایی که به صورت تودرتو تعریف شده و nested هستند خود می توانند از دستور @extend استفاده کنند.
#fake-links .link {
@extend a;
}
a {
color: blue;
&:hover {
text-decoration: underline;
}
}
به قطعه کد زیر کامپایل می شود:
a, #fake-links .link {
color: blue;
}
a:hover, #fake-links .link:hover {
text-decoration: underline;
}
ادغام selector های متوالی (Merging Selector Sequences)
گاهی یک selector sequence از selector ای که در selector sequence دیگر ظاهر می شود، ارث بری می کند. در چنین شرایطی، دو sequence که حاوی چند selector می باشند بایستی بایکدیگر ادغام (merge) شوند. مثال:
#admin .tabbar a {
font-weight: bold;
}
#demo .overview .fakelink {
@extend a;
}
گرچه می توان تمامی selector های ممکن را تولید کرد که با هر دو sequence منطبق شوند، اما همان طور که انتظار می رود، این امر سبب بسیار بزرگ تر شدن فایل stylesheet می شود. مثال ساده ی بالا را در نظر بگیرید. این مثال به ده selector نیاز دارد. بجای انجام این کار Sass تنها selector هایی تولید می کند که لازم و کارا هستند.
زمانی که دو sequence که هیچ selector مشترکی بایکدیگر ندارند، ادغام می شوند، آنگاه دو selector کاملا جدید تولید می شود: 1. اولی متشکل است از sequence اول + sequence دوم 2. دومی مشتکل است از sequence دوم + sequence اول خواهد بود. مثال:
#admin .tabbar a {
font-weight: bold;
}
#demo .overview .fakelink {
@extend a;
}
به این کد کامپایل می شود:
#admin .tabbar a,
#admin .tabbar #demo .overview .fakelink,
#demo .overview #admin .tabbar .fakelink {
font-weight: bold;
}
چنانچه دو sequence (یک دنباله ای از selector ها) که قرار است باهم ادغام شوند، selector های مشترک داشته باشند، در آن صورت دو selector با یکدیگر ترکیب شده و چنانچه تفاوتی بین این دو وجود داشته باشد، به صورت تناوبی در sequence جدید قرار می گیرند. در مثال جاری، هر دو sequence دربردارنده ی انتخابگر #admin هستند، با توجه به آنچه گفته شد، selector مشترک #admin در sequence های جدید با یکدیگر ادغام و یکی می شود:
#admin .tabbar a {
font-weight: bold;
}
#admin .overview .fakelink {
@extend a;
}
به کد زیر کامپایل می شود:
#admin .tabbar a,
#admin .tabbar .overview .fakelink,
#admin .overview .tabbar .fakelink {
font-weight: bold;
}
Selector هایی که تنها برای ارث بری تعریف می شوند و انتخابگر اختصاصی Sass /@extend-Only Selectors #placeholders
گاهی توسعه دهنده style هایی در یک کلاس تعریف می کند که فقط قصد ارث بری از آن ها را داشته و شاید هیچگاه به طور مستقیم در HTML بکار نبرد. می توان به زمانی اشاره کرد که توسعه دهنده یک کتابخانه ی Sass دربردارنده ی یک سری style تعبیه می کند که کاربر ممکن است بر اساس نیاز از آن ارث بری /@extendکند یا اصلا هیچگاه استفاده ننماید.
اگر برای این منظور از کلاس های عادی استفاده کنید، در نتیجه مقدار زیادی کد بلااستفاده و غیرضروری CSS به هنگام تولید فایل stylesheet ایجاد می گردد. علاوه بر آن، این احتمال وجود دارد که با سایر کلاس های مورد استفاده در HTML تداخل به وجود آید. جهت رفع این مشکل زبان Sass، قابلیت یا ابزاری به نام انتخابگر های جایگزین/ placeholder selectorsرا تعبیه کرده است (برای مثال %foo).
این selector کاربردی مشابه انتخاب گر بر اساس id و کلاس (# یا .) دارد، با این تفاوت که بجای دو کاراکتر ذکر شده داخل پرانتز از % بهره می گیرد. selector مزبور را می توان بجای انتخابگر بر اساس id و class بکار برد.
لازم به ذکر است که % تنها همراه با دستور @extend قابل استفاده بوده و در غیر این صورت مانع از اجرا و تبدیل شده دستورات (ruleset ها) به CSS می شود. مثال:
// This ruleset won't be rendered on its own
//مجموعه دستور زیر به تنهایی و بدون حضور دستور مورد نیاز اجرا نشده و نمایش داده نمی شود
#context a%extreme {
color: blue;
font-weight: bold;
font-size: 2em;
}
placeholder selector که انتخابگر اختصاصی Sass هست، مانند Selector های عادی (id و class) قابل ارث بری و extend می باشد. باید توجه داشته باشید selector هایی که از آن ها ارث بری صورت گرفته، تولید می شود اما این امر در مورد selector پایه صادق نخواهد بود. مثال:
.notice {
@extend %extreme;
}
کد بالا پس از کامپایل به صورت زیر در می آید:
#context a.notice {
color: blue;
font-weight: bold;
font-size: 2em;
}
پارامتر اختیاری!optional
به طور معمول هنگامی که شما از یک selector ارث بری می کنید، دستور @extend بایستی وظیفه ی مورد انتظار خود را به درستی انجام دهد و در غیر این صورت حتما خطایی رخ داده است. به طور مثال اگر شما چنین دستوری را بنوسید: a.important {@extend .notice}، چنانچه این دستور selector ای که حاوی .notice است را نداشته باشد، خطا رخ می دهد. همچنین اگر تنها selector ای که کلاس .notice را شامل می شود، h1.notice باشد، باز هم خطا رخ می دهد چرا که a با h1 تداخل دارد و به همین جهت selector جدید ایجاد می شود.
گاهی شما نمی خواهید دستور @extendهبچ selector جدیدی تولید کند. برای این منظور، کافی است پارامتر !optional را پس از selector مورد نظر درج کنید. برای مثال:
a.important {
@extend .notice !optional;
}
استفاده از دستور @extend در بدنه ی Directive ها
در خصوص استفاده از دستور @extend داخل directive هایی نظیر @media محدودیت هایی وجود دارد. در واقع Sass این قابلیت را ندارد که دستورهای (rule) CSS موجود در خارج از بدنه ی @media را به selector های محصور (موجود) در آن اعمال کند چرا که در این صورت با تکرار و کپی غیرضروری style ها در بخش های مختلف فایل، باعث بزرگ و حجیم شدن فایل stylesheet می شود. به عبارت دیگر اگر از @extend داخل قطعه کد @media (یا سایر directive های CSS) استفاده نمایید، منحصرا می توانید selector هایی که داخل قطعه کد directive مربوطه (یکسان) ظاهر می شود را به ارث ببرید (extend).
برای مثال، کد زیر به درستی عمل می کند:
@media print {
.error {
border: 1px #f00;
background-color: #fdd;
}
.seriousError {
@extend .error;
border-width: 3px;
}
}
اما کد زیر خطا صادر می کند:
.error {
border: 1px #f00;
background-color: #fdd;
}
@media print {
.seriousError {
// INVALID EXTEND: .error is used outside of the "@media print" directive
@extend .error;
border-width: 3px;
}
}
مثال کاربردی
مثال زیر نحوه ی استفاده ی عملی از دستور @extend در فایل SCSS را نمایش می دهد:
extend.htm
< !doctype html >
< head >
< title >Extend Example< /title >
< link rel="stylesheet" href="extend.css" type="text/css" / >
< /head >
< body class="container" >
< h2 >Example using Extend< /h2 >
< p class="style" >Lorem Ipsum is simply dummy text of the printing and typesetting industry.< /p >
< /body >
< /html >
حال فایل extend.scss را ایجاد نمایید.
extend.scss
.style{
font-size: 30px;
font-style: italic;
}
h2{
color: #787878;
@extend .style
}
.container{
@extend h2
}
می توانید با اجرای دستور زیر به Sass فرمان دهید که بر روی محتوای فایل مورد نظر نظارت داشته و هرگاه تغییری در فایل SASS ایجاد شد، کد CSS متناظر را نیز بروز رسانی کند:
sass --watch C:\ruby\lib\sass\extend.scss:extend.css
با اجرای کد بالا، فایل extend.css با محتوای زیر ایجاد می شود.
extend.css
.style, h2, .container {
font-size: 30px;
font-style: italic;
}
h2, .container {
color: #787878;
}
خروجی
با طی کردن مراحل زیر از کد خروجی بگیرید:
- کد بالا را در extend.html ذخیره نمایید.
- فایل HTML را با مرورگر دلخواه باز کنید. خروجی به صورت زیر به نمایش در می آید: