menu

ابزار های توسعه دهنده ی مدرن وب

Less

چهارشنبه 24 شهریور 1395

در فصل قبل، به معرفی و کار با Sass پرداختیم. در ادامه میریم که با یکی دیگه از پیش پردازنده های CSS کار کنیم.

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

امیدوارم فصل قبل را خوب خونده باشید(!) چون که اگه به اون ها مسلط باشید، کارتون اینجا خیلی خیلی راحت تر میشه

ولی نگران هم نباشید، بدون اون هم اینجا کارتون راه می افته!

برای شروع، مثل همیشه ابتدا سری به سایت اصلی Less میزنیم

در اولین قدم، میریم که Less را نصب کنیم. برای نصب Less (بر خلاف Sass که از Gem استفاده کردیم) از npm استفاده میکنیم

npm install -g less

و بعد از این که نصب شد، میتونیم با استفاده از دستور lessc ، از less استفاده کنیم. مثلا برای شروع بد نیست ورژن Less خودمون را چک کنیم

lessc -v

برای شروع کد زدن، من یه پوشه میسازم به اسم less و یه فایل style.less توش ایجاد میکنم و توی Sublime بازش میکنم و یه کد ساده ی css توش مینویسم

p{
    color: red;
}

حالا برای این که خروجی css داشته باشیم، مثل Sass ، باید فایل less را کامپایل کنیم. برای اینکار کافیه کد زیر را توی ترمینال بزنیم

lessc style.less

با زدن کد بالا، خروجی کد کامپایل شده ی ما توی ترمینال نمایش داده میشه

ولی اگه بخواهیم که خروجی ما، توی یه فایل css ذخیره بشه، میتونیم کدمون را به شکل زیر تغییر بدیم

lessc style.less style.css

و خروجی ما یه فایل css با مقدار زیر خواهد بود

p {
  color: red;
}

در ادامه، همونطور که قبلا توی Sass دیدیم، ما میتونستیم توی Sass نوع خروجی را انتخاب کنیم که مثلا css هامون minified باشه یا معمولی. برای اینکار توی Less ، شما باید یه پلاگین به اسم less-plugin-clean را نصب کنید

برای نصبش کافیه بزنیم

npm install -g less-plugin-clean-css

و همینطور، موقعی که میخواهیم فایل less را کامپایل کنیم از آپشن زیر استفاده کنیم

lessc --clean-css style.less style.css

مطلب دیگه ای هم که میخوام اضافه کنم، یه پلاگین برای Sublime هست به اسم Less2Css. این پلاگین کاری که میکنه این هست که همزمان با Save شدن فایل less، خودکار برای شما فایل less را کامپایل میکنه و خروجی css را براتون توی یه فایل css ذخیره میکنه. اگه میخواهید که هردفعه کد bash مربوطه را اجرا نکنید، میتونید از اون استفاده کنید

برگردیم سراغ کد زدن توی sublime

روند کار با Less را مشابه با Sass میریم جلو

الف) نظرگذاری (Comment)

اینجا هم دقیقا مشابه با Sass با دو نوع کامنت مواجه هستیم

مدل اول

//comment

هست و مدل دوم هم

/*comment*/

هست. تفاوت این دوتا این هست که که بعد از کامپایل شدن، Comment از نوع اول توی فایل خروجی نشون داده نمیشه ولی کامنت نوع دوم توی خروجی نمایش داده میشه

ب) متغیر ها

دقیقا مشابه با Sass، اینجا ها متغیرها را میتونیم ازشون استفاده کنیم. مثلا فرض کنید که یه رنگ به عنوان رنگ غالب (غلط املایی نیست ها! منظورم از غالب دقیقا غالب هست نه قالب!) سایتتون انتخاب کنید و از این رنگ خیلی جاها استفاده کنید. در آینده ممکنه که این رنگ را بخواهید عوض کنید و اگه به طور معمولی css زده باشید، مجبور میشید صدها خط را ویرایش کنید. ولی با استفاده از یه متغیر، خیلی راحت میتونید با تغییر یه خط، کل اون رنگ ها را عوض کنید.

برای مثال کد css ما اینطوری هست

p{
	color: #444;
}
h1{
	color: #444;
}
a{
	color: #444;
}

ما میتونیم خیلی راحت مقدار #444 را توی یه متغیر ذخیره کنیم و از اون متغیر استفاده کنیم. برای استفاده از متغیر ها توی less از @ استفاده میکنیم (توی Sass از $ استفاده میکردیم). اینطوری

//Variables
@mainColor : #444;
p{
	color: @mainColor;
}
h1{
	color: @mainColor;
}
a{
	color: @mainColor;
}

و خروجی css ما اینجوری میشه

p {
  color: #444;
}
h1 {
  color: #444;
}
a {
  color: #444;
}

البته الان که از متغیر ها صحبت شد، بهتره از متغیرهای متغیر(Variable variables) هم حرف بزنم. فرض کنید یه متغیر داریم، که اون متغیر خودش هم متغیره! دقیقا عین همون مفهومی که توی PHP هست.

پ)توابع

خیلی شبیه به Sass که از mixin استفاده میکردیم، اینجا توی less هم میتونیم از توابع استفاده کنیم. برای مثال فرض کنید یه کد css شبیه به این داریم

.container{
	margin:0;
	padding: 0;
}
.row{
	margin:0;
	padding: 0;
}

اصلا بهینه نیست که هر دفعه که ما میخواهیم فاصله ها را تنظیم کنیم، بیایم از یه margin و padding استفاده کنیم و هر دفعه دو سه خط کد اضافه بنویسیم. و وظیفه ی less هم بهینه سازیه!

ما میتونیم از یه تابع استفاده کنیم و توی slector های خودمون اون تابع را فرابخونیم. اینجوری

//Functions
.space{
	margin:0;
	padding: 0;
}
.container{
	.space;
}
.row{
	.space;
}

برخلاف Sass هیچ کلید واژه ای (مثل Mixin) در کار نیست. یه Selector میسازیم و کدهامون را توش میزنیم و از اون Selector هرجا خواستیم استفاده میکنیم.

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

.space(@m:0, @p:0){
	margin:@m;
	padding: @p;
}
.container{
	.space;
}
.row{
	.space(2px,10px);
}

و به این شکل، ما آرگومان هامون را تعریف کردیم (با مقدار پیشفرض) و توی containter از مقدار های پیشفرض استفاده کردم و توی row بهش آرگومان دادم

خروجیش به شکل زیر میشه

.container {
  margin: 0;
  padding: 0;
}
.row {
  margin: 2px;
  padding: 10px;
}

یه نکته ی کوچیک که توی استفاده از mixin ها اضافه کنم، استفاده از یه حالت هست به اسم Pattern. به نظرم من این حالت خیلی شبیه به استفاده از Switch ها و شرط ها توی زبان های برنامه نویسی دیگه است. بیاید با یه مثال بیشتر توضیح بدم

فرض کنید کد Less زیر را داریم

//Paterns
.mixin(typeA; @m){
	margin: @m /2;
}
.mixin(typeB; @m){
	margin: @m * 2;
}
.mixin(@_;@m){
	color:black;
}
.box{
	.mixin(typeA,100px);
}

با کامپایل کردن اون خروجی CSS ما اینجوری میشه

.box {
  margin: 50px;
  color: black;
}

ولی دقیقا چه اتفاقی افتاد؟ ما یه تابع را (mixin) سه دفعه تعریف کردیم. در حالت اول که تعریف کردیم، داخل پرانتز، اولین مقدار را TypeA گذاشتم و برخلاف آرگومان ها که با , از هم جدا میشن، با استفاده از ; از مقدار بعدیش جدا کردم. این همون Switch ما هست مثل اکثر زبان های برنامه نویسی. یعنی موقعی که ما تابع را فرامیخونیم، اگه اولین مقدار ورودی تابع TypeA بود، تابع شماره اول که اولین مقدار اون هم TypeA هست فراخونده میشه و اگه مقدار ورودی تابع موقع فراخونده شدن TypeB بود، تابع دوم فراخونده میشه.

به تابع سوم نگاه کنید. مقدار ورودیش @_ هست. این مقدار باعث میشه که این تابع، Default Pattern ما باشه. یعنی چه TypeA چه TypeB هر کدوم فراخونده بشن، این تابع هم فراخونی میشه. 

باحال بود، مگه نه؟!

ت) انتخابگر های تودر تو(Nested Selectors)

دقیقا عین اونچه که توی Sass داشتیم

فرض کنید یه کد CSS مثل کد زیر داشته باشیم

.header{
    color: black;
}
.header p{
    font-size: 12px;
}
.header p a{
    color: grey;
}
.header p a.warning{
	color: red;
}
.header p a:hover{
    color:blue;
}

اینجا ما به اینجای اینکه هر کدوم از کدهامون را یه جا زده باشیم، چون هر کدوم از اون ها Parent یکی دیگه است، میتونیم به صورت تو در تو اون ها را بنویسیم (دقیقا عین اونچه که توی Sass بود)

.header{
	color: black;
	p{
		font-size: 12px;
		a{
			color: grey;
			&.warning{
				color: red;
			}
			&:hover{
				color: blue;
			}
		}
	}
}

و خروجیش کد زیر میشه

.header {
  color: black;
}
.header p {
  font-size: 12px;
}
.header p a {
  color: grey;
}
.header p a.warning {
  color: red;
}
.header p a:hover {
  color: blue;
}

ولی یه کار باحال دیگه که میشه توی انتخاب گرهای تودر تو توی less انجام داد، عوض کردن جای پدر و فرزند هست!

یعنی چی؟

فرض کنید ما کد less زیر را داریم

a,b,c{
	.parent{
		color: black;
	}
}

بعد از کامپایل کد ما این شکلی میشه

a .parent,
b .parent,
c .parent {
  color: black;
}

یعنی در واقع انتخاب گر .parent زیر مجموعه ی هر کدوم از a و b و c میشه

حالا بیاید یکم کد less را تغییر بدیم. اینجوری

a,b,c{
	.parent & {
		color: black;
	}
}

این دفعه خروجیمون این شکلی میشه

.parent a,
.parent b,
.parent c {
  color: black;
}

Cool! با زدن یه & جای پدر و فرزند توی Nested Selector عوض شد!

ث) دسترسی های متغیر ها (Scopes)

مثل تموم زبان های برنامه نویسی دیگه، متغیر ها توی Less هم محدوده ی تاثیر و دسترسی های خاص خودشون را دارن. مثلا کد less زیر

@myColor: white;
.footer{
	@myColor: black;
	color: @myColor;
	a{
		@myColor : blue;
		color: @myColor;
	}
}
.main{
	color: @myColor;
}

این کد بعد از کامپایل خروجیش این میشه

.footer {
  color: black;
}
.footer a {
  color: blue;
}
.main {
  color: white;
}

نکته ی قابل توجه اینه که با اینکه ما مقدار متغیر myColor را توی footer تغییر دادیم، اما توی main همون مقدار قبلی هست. چرا؟

به خاطر دسترسی ها. چون ما داخل یه براکت {} مقدار یه متغیر را تغییر دادیم، این مقدار فقط برای همون براکت تغییر میکنه و مقدارش local میشه و مقدار Global اون همون مقدار قبلی باقی میمونه

ج) استفاده از فایل های دیگه ی less

دوباره مثل Sass توی Less هم میتونیم فایل های less دیگه را import کنیم. مثلا من یه فایل lib.less میسازم و کد زیر را داخلش میزنم

body{
	font-size: 16px;
}

حالا میخواهم از کدهای داخل این فایل، توی فایل style.less خودم استفاده کنم. (این امکان واسه ی ماژولار کردن سایت خیلی به درد میخوره) کافیه توی فایل style.less بزنم

@import "lib";

و خروجیش توی فایل style.css من میشه

body {
  font-size: 16px;
}

و البته شما میتونید کدهاتون را نه الزاما توی یه ویرایشگر، بلکه به صورت آنلاین به زبان less وارد کنید و خروجی Sass بگیرید. برای این کار هم میتونید به اینجا برید

تا به اینجای کار، درباره ی Syntax های Less صحبت کردیم

بهتره به عنوان مطلب آخر، درباره ی استفاده از Less توی سایت کمی حرف بزنم.

اوایل مطلب، درباره ی clean-css صحبت کردم، که باعث میشه کدهای شما به صورت minified کامپایل بشه و همینطور درباره ی بسته ی Less2Css هم برای Sublime صحبت کردم که باعث میشه موقع ذخیره کردن کدهاتون توی Sublime به شما خروجی css بده. اما تمام این مطالب پردازش Less به صورت Server side بود. یعنی تا به اینجای کار شما یه کد Less مینوشتید و کامپایلش میکردید و از فایل css خروجی توی سایت خودتون استفاده میکردید، ولی شما میتونید که از Less به صورت Client Side هم استفاده کنید

یعنی به جای اینکه فایل css را توی صفحه تون لود کنید، کاربر فایل less را لود میکنه و فایل less توی مرورگر به css تبدیل میشه و اعمال میشه

البته من خودم توصیه میکنم که از less به صورت server side استفاده کنید و کلاینت ساید استفاده نکنید، چون استفاده اون به صورت کلاینت ساید یه فشار پردازشی اضافه به کاربر اضافه میکنه و یا ممکنه برخی از کدهاتون اونجوری که شما میخواید پردازش نشه، ولی برای کامل شدن این فصل، این مطلب را هم توضیح میدم

برای شروع، یه فایل index.html با کد زیر میسازم

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Less</title>
</head>
<body>
	
</body>
</html>

(کد بالا را با استفاده از Emmet زدم. خیلی راحت ! را تایپ کردم و tab را زدم!)

حالا ما میخواهیم که کاربر به جای اینکه فایل css را لود کنه، فایل less را لود کنه. پس فایل less را به صفحه مون اضافه میکنم. توی head صفحه میزنم

<link rel="stylesheet" href="./style.less">

حالا برای اینکه این فایل less به صورت Client Side پردازش بشه، باید از یه کتابخونه به اسم less.js استفاده کنیم. میتونید درباره ی این کتابخونه اینجا بیشتر بخونید

من برای استفاده از این کتابخونه، سری به سایت cdnjs.com میزنم و کد زیر را توی head صفحه ام میزنم

<script src="https://cdnjs.cloudflare.com/ajax/libs/less.js/2.7.1/less.min.js"></script>

تموم شد!