Syntactically Awesome Style Sheets NOT SASS

Sass چی داره که Less نداره؟

امیدوارم از مطلب قبل تا الان با Sass کار کرده باشید، چطور بود؟ به مشکلی بر نخوردید؟ اگر چیزی بوده توی کامنت‌ها بگید تا در موردش بحث کنیم.

Sass ابزار‌های قدرتمندی در اختیار میذاره که هیجان کار و سر و کله زدن با آن ها را بالا می‌بره:

 

Mixin Directives

Mixinها یکی از قدرت‌ترین ویژگی‌هایی است که از تکرار کد جلوگیری کرده و باعث تمیز شدن کد می‌شود. در واقع کد را یکبار نوشته و چندجا استفاده می‌کنید. مثال زیر را ببینید:

@mixin txtHide {
text-indent: -9999px;
overflow: hidden;
display: block;
font: 0/0;
}
#logo {
@include txtHide;
}

خروجی:

#logo {
text-indent: -9999px;
overflow: hidden;
display: block;
font: 0/0;
}

میکسین‌ها را باید با استفاده از @mixin تعریف کنید و می‌توانند وردی بگیرند و برای ورودی‌ها مقدار پیش‌فرض تعریف کرد تا اگر مقادیر ورودی وارد نشده بود مشکلی بوجود نیاید. برای استفاده از میکسین‌ها باید آن‌ها را @include کنید.

در Sass برخلاف Less، میکسین‌ها به عنوان یک کلاس جدا چاپ نمی‌شوند و باید حتما @include شوند.

// It strips the unit of measure and returns it
@function strip-unit($num) {
@return $num / ($num * 0 + 1);
}
@mixin single-transition($property:all, $speed:300, $delay:500, $ease:ease-out) {
$speed: strip-unit($speed) + ms;
$delay: strip-unit($delay) + ms;
-webkit-transition: $property $speed $ease $delay;
-moz-transition: $property $speed $ease $delay;
transition: $property $speed $ease $delay;
}
a {
color: red;
@include single-transition(color, 500, 1000ms);
&:hover {
color: black;
}
}

خروجی:

a {
color: red;
-webkit-transition: color 500ms ease-out;
-moz-transition: color 500ms ease-out;
transition: color 500ms ease-out;
}
a:hover {
color: black;
}

@extend

یکی از ویژگی‌های Sass قابلیت @extend است. برای وقتی که می‌خواهید یک کلاس شما تمام ویژگی‌های یک کلاس دیگر را بگیرد(غیر از چند مورد کوچک) استفاده می‌شود.

.error {
border: 1px #777;
background-color: #eee;
}
.seriousError {
@extend .error;
border-color: #f00;
}

خروجی:

.error, .seriousError {
border: 1px #777;
background-color: #eee;
}
.seriousError {
border-color: #f00;
}

تفاوت اصلی Mixin با @extend در خروجی css است که در واقع ویژگی‌های کلاس کپی نمی‌شود بلکه نام کلاس با کاما در کنار دیگر کلاس می‌آید. از این قابلیت می‌توان استفاده‌های پیچیده‌تری هم کرد که در این صفحه میتونید ببینید اما باید حواستون باشید که کدتون را به جای ساده کردن پیچیده و سنگین‌تر نکنید!

Control Directives

  • @if
  • @for
  • @each
  • @while

اگر با هر زبان برنامه‌نویسی آشنا باشید دستورات بالا(شرط و حلقه‌ها) را می‌شناسید و من فقط برای استفاده از @if دو مثال کاربردی میزنم و پشنهاد می‌کنم برای اطلاعات بیشتر در مورد دستورات ایجاد حلقه مستندات Sass و این مقاله را بخوانید.

@if

$color-body: #000;
body {
background: $color-body;
@if(lightness($color-body) > 50%) {
color: darken($color-body, 35%);
} @else {
color: lighten($color-body, 35%);
}
}

فرض کنید شما به کاربرتون این اجازه را داده‌اید که رنگ زمینه را خودش انتخاب کند و شما می‌خواهید بر اساس رنگ زمینه، رنگ متن را مشخص کنید. خب میتونید با استفاده از توابع مربوط به رنگ(+) از lighten برای روشن‌تر کردن و از darken برای تیره‌تر کردن(در مثال مقدار ۳۵٪) استفاده کنید. اما از کدام استفاده کنید؟ نمی‌دانید رنگی که کاربر انتخاب کرده روشن است یا تیره؟ پس با استفاده از دستور @if و یکی دیگر از توابع Sass بررسی میکنیم که رنگ روشن است یا تیره و اگر lightness کوچکتر از ۵۰٪ بود درواقع رنگ تیره است و برای متن باید از lighten برای روشن‌تر کردن رنگ استفاده کنیم و بلعکس. خروجی را ببنید:

body {
background: black;
color: #595959;
}

حالا اگر مقدار متغیر $color-body را یک رنگ روشن بدیم به عنوان مثال همان سفید(#fff) نتیجه استفاده از تابع darken و تیره‌تر شدن رنگ می‌شود:

body {
background: white;
color: #a6a6a6;
}

در مثال دوم می‌خواهیم کدی بنویسیم که کاربر بتواند انتخاب کند زبان سایت راست به چپ است یا چپ به راست بدون اینکه کدی را override کنیم.

در این مثال کاربر فقط متغیر $global-direction را برای انتخاب زبان لازم است تغییر دهد تا کل سایت بر اساس این متغیر تغییر کند، ببنید:

$global-direction: rtl; // rtl or ltr
$default-float: left !default;
$opposite-direction: right !default;
@if $global-direction == ltr {
$default-float: left;
$opposite-direction: right;
} @else {
$default-float: right;
$opposite-direction: left;
}
body {
direction: $global-direction;
text-align: $default-float;
}
#container {
float: $default-float;
}
#sidebar {
float: $opposite-direction;
margin-#{$default-float}: 50px;
}

با مقدار rtl خروجی را ببنید:

body {
direction: rtl;
text-align: right;
}
#container {
float: right;
}
#sidebar {
float: left;
margin-right: 50px;
}

حالا اگر مقدار متغیرمان را به ltr(یعنی سایت چپ به راست) تغییر بدهیم خروجی به این شکل می‌شود:

body {
direction: ltr;
text-align: left;
}
#container {
float: left;
}
#sidebar {
float: right;
margin-left: 50px;
}

خب، خیلی کار‌های دیگه‌ایی هم میشه برای کامل کردن این کد کرد، به عنوان مثال میتونید نوع و اندازه فونت را هم بر اساس راست به چپ بودن مشخص کنید تا فونت مناسب آن زبان( مثلا فارسی و انگلیسی) نمایش داده شود.

در مثال بالا کد‌هایی وجود دارد که تا حالا توضیحی در موردشون ندادم ولی ترجیح میدم این مطلب را طولانی نکنم، اگر مایل بودید بدونید، میتونید به مستندات Sass مراجعه یا در نظرات سوالتون را مطرح کنید.

و آخرین ویژگی منحصربفرد Sass که در این مطلب بررسی میکنیم، قابلیت ایجاد تابع است.

Function Directives

با این ویژگی شما محدود به تابع‌های از پیش تعریف شده Sass نیستید و میتونید تابع خودتون را بسازید. فرق توابع با میکسین‌ها در این است که میکسین‌ها یک تکه کد بر ‌میگردونند ولی توابع یک مقدار بر‌میگردونند مانند یک رنگ یا یک عدد.

در مثال زیر همان شرطی که برای تشخیص روشنی رنگ زمینه و انتخاب رنگ متن در بخش @if گفتم را به صورت یک تابع در می‌آورم تا همه‌جا قابل استفاده باشد:

// Variables
$color-body: #000;
// Functions
@function txtColor($bg, $amount: 40%) {
@if(lightness($bg) > 50%) {
@return darken($bg, $amount);
} @else {
@return lighten($bg, $amount);
}
}
// My Style
body {
background: $color-body;
color: txtColor($color-body, 35%);
}
#footer {
background: invert($color-body);
color: txtColor(invert($color-body));
}

خروجی با رنگ زمینه سیاه:

body {
background: black;
color: #595959;
}
#footer {
background: white;
color: #999999;
}

حالا رنگ‌ها را تغییر میدیم

// Variables
$color-body: #fff;

خروجی:

body {
background: white;
color: #a6a6a6;
}
#footer {
background: black;
color: #666666;
}

مثال بعدی که از فریم‌ورک Foundation براتون پیدا کردم بر اساس متغیر $em-base که تعریف می‌کنیم واحد پیکسل را به em تبدیل می‌کند که خیلی کاربردی است. در این مثال ترکیب توابع مختلف با هم و استفاده از @if در توابع را هم میتونید ببنید.

// Variables
$em-base: 16px;
//
// Functions
//
// It strips the unit of measure and returns it
@function strip-unit($num) {
@return $num / ($num * 0 + 1);
}
// New Syntax, allows to optionally calculate on a different base value to counter compounding effect of em's.
// Call with 1, 2, 3 or 4 parameters, 'px' is not required but supported
// em-calc(10 20 30px 40);
// Space delimited, if you want to delimit using comma's, wrap it in another pair of brackets
// em-calc((10, 20, 30, 40px));
// Optionally call with a different base (eg: 8px) to calculate em.
// em-calc(16px 32px 48px, 8px);
// If you require to comma separate your list
// em-calc((16px, 32px, 48), 8px);
@function convert-to-em($value, $base-value: $em-base)  {
$value: strip-unit($value) / strip-unit($base-value) * 1em;
@if ($value == 0em) { $value: 0; } // Turn 0em into 0
@return $value;
}
@function em-calc($values, $base-value: $em-base) {
$max: length($values);
@if $max == 1 { @return convert-to-em(nth($values, 1), $base-value); }
$emValues: ();
@for $i from 1 through $max {
$emValues: append($emValues, convert-to-em(nth($values, $i), $base-value));
}
@return $emValues;
}
@function emCalc($value, $base-value: $em-base) {
@return em-calc($value, $base-value: $em-base);
}
// My Style
p {
font-size: emCalc(16px);
margin: emCalc(20 25 10px 15px);
}

خروجی:

p {
font-size: 1em;
margin: 1.25em 1.5625em 0.625em 0.9375em;
}

جزییات زیادی در مورد Sass و قابلیت‌هاش وجود داره که می‌تونیم در موردش صحبت کنیم. پس شروع به کار کنید چون خیلی چیز‌های دیگه وجود داره که هنوز در موردش نخوندیم!

+ اگر سوالی داشتید خوشحال می‌شم در کامنت‌ها مطرح کنید.
+ مطالب گذشته در این مورد را هم با تگ Sass در وبلاگم میتونید پیدا کنید.
+ در مورد استفاده از em چون گفتم پیشنهاد میکنم این دو مطلب را بخونید: + و +

پرهام سال‌هاست در مورد تجربه‌ی کاربری تحقیق می‌کند و همیشه به دنبال راهی عملی برای استفاده از تجربه‌کاربری در طراحی محصولات بوده. او در حال حاضر مدیر ارشد محصول در شرکت صبا‌ایده(آپارات، فیلیمو، صباویژن) است.

15 دیدگاه برای «Sass چی داره که Less نداره؟»

  1. توی قسمت @mixin ها فک کنم اگه ms رو به خود متغیر اضافه کنیم دیگه نیازی نیست که توی قسمت اصلی +ms بزاریم یه پیشنهاد دیگه هم اینکه میتونیم از property :delay هم استفاده کنیم و با تغریف متغیر @delay زمان تاخیر در اجرای tranistion هم در کد قرار بدیم البته کاربردش کمه اما بعضی جاها جواب میده

    1. در قسمتی که ورودی‌های میکسین را تعریف می‌کنیم نمیشه ms را وارد کرد و فایده‌ایی هم نداره چون کاربر هر مقداری وارد کنه، مقدار ورودیش جایگزین کد ما میشه. بهترین راهش اینه که بعد از تعریف بیایم ببینیم که ms را وارد کرده یا نه و اگر تعریف نکرده به متغیرمون اضافه کنیم:
      $speed: $speed / ($speed * 0 + 1) + ms;

      $delay را هم اضافه کردم، میکسین را تغییر دادم ببینید.

    1. خب پس باید بیشتر دقت کنید پیشنهاد می‌کنم نگاهی به داکیومنت خود Sass بندازین:
      http://sass-lang.com/documentation/file.SASS_REFERENCE.html

      البته Less هم مثل قبل نیست و کم کم ویژگی‌هایی را آورده ولی خب توی بخش‌های Control Directive خیلی ضعیف عمل کرده یا مفهوم میکسین با کلاس یکی بود قبلا الان نمیدونم فرقی کرده یا نه…

      توی ورژن جدیدش extend را خوشبختانه اضافه کرده بهتره شده.

      در هر صورت ساختار Sass ساختار برنامه نویسی قوی‌تری داره و در پروژه‌های بزرگ امکانات زیادی را میشه پیاده سازی کرد، مثلا در مورد کار با لیست‌ها و آرایه‌ها خیلی کار‌های مختلفی میشه کرد.

      یکی از مهم‌ترین ویژگی‌هایی که less فکر نمی‌کنم هنوز داشته باشه تابع است. که خیلی کاربردی‌تر است.

      و یک نکته دیگه اینکه پروژه‌های جدید دارن حرکت می‌کنند به سمت استفاده از Sass، الان ساختار Less Bootstrap را با ساختار Sass Foundation مقایسه کنید متوجه تفاوت‌های استفاده از Less و Sass خواهید شد.

      1. در مورد mixin از اولین ورژن هایی که من کار کردم، تعریف مشخصی داشت، mixin کلاسی بود که پارامتر میگرفت و تا زمانی که ازش استفاده نمی کردی چاپ نمی شد، در مورد تابع و لیست موافقم تا حدودی.

        من تا الان هر چیزی که با sass نوشته شده رو تونستم تو less هم پیاده کنم، ولی موافقم sass به برنامه نویسی نزدیکتره، اما چیزی که باعث میشه از less دفاع کنم، اینه که اصالت CSS رو حفظ کرده و تمام سعیش رو کرده که از محیط CSS دور نشه، نمی دونم شاید یه روز کلاً CSS منقرض شد و SCSS جانشینش شد، اون روز یا من باید به راحتی برم سراغ sass یا اینکه less رو به sass کامپایل کنم(شوخی)

        ممنون به خاطر مطلب جالبت، موفق باشی

  2. من فعلا دو چیز کامل متوجه نشدم
    اینکه فایل scss چطور باز کنم و روش کار کنم؟
    اینکه چطور از کلاس های بوت استرپ داخل این کدها استفاده کنم؟
    ممنون از راهنمایی شما

    1. اینکه پروژه رو ایجاد کنیم رو توضیح دادین امااینکه چطوراونها رو ویرایش کنیم توضیح ندادین من از git استفاده نمی کنم سرچ که کردم دستور clone از مخزن گیت گفته من این نمی خام باز کردن فایلا از روی هارد می خام

  3. سلام
    ممنون از مطلب با ارزشتون
    من با sublimetext کار میکنم
    شما عرض کردید که پلاگین مخصوص sass داره
    من طبق راهنمایی که سایت خودش کرده برای ویندوز تو قسمت کنسول اون دستورات را کپی کردم و ظاهرا پکیج نصب شد اما درباره ی sass نتیجه ای نگرفتم!لطفا راهنمایی کنید
    شما با sublime،
    sass مینویسید چطوری به css کامپایل میکنید؟
    سپاسگزارم

پاسخ دهید

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