در مطلب قبل توضیح داده شد که این واحدهای نسبی چه هستند و چگونه عمل می کنند. حال در این مطلب به دنبال جواب دادن به این سوال هستیم که “از کدام یک از این واحدها باید استفاده کنیم؟“. آیا اصلا این سوال درست است؟
پای سفره ماژولاریان!
اینکه می گوییم می شود به ماژولار بودن یک کامپوننت با استفاده از این واحدها کمک کرد به این معنی است که یکی از نکاتی که باید در زمان ساخت یک کامپوننت دقت کرد, انسجام بین اندازه ها و فضاهای بین اجزا و اندازه فونت ها می باشد. همچنین ما به این دلیل ماژولار طراحی می کنیم که بتوانیم از کامپوننت هایی که می سازیم بارها و بارها در جاهای مختلف استفاده کنیم. احتمالا اندازه فونت ها و اندازه اجزای کامپوننت و فاصله بین اجزای موجود آن در جاهای مختلف که قرار است از کامپوننت استفاده کنیم, متفاوت خواهند بود. پس باید در زمان ساخت کامپوننت کمی بیشتر وسواس به خرج داد تا بتوان در آینده به راحتی از آن کامپوننت در موقعیت های مختلف استفاده کرد. یکی از موارد برای وسواس به خرج دادن همین واحدهای اندازه دهی می باشند.
به عنوان مثال دموی زیر را در نظر بگیرید:
See the Pen Circular Menu by Mojtaba Seyedi (@seyedi) on CodePen.
منوی بالا یه کامپوننت است (یا حداقل دوس داره که باشه :) ) که می تواند در پروژه های مختلف مورد استفاده قرار بگیرد. شاید اندازه این منو و آیتم هایش در نظر شما کوچک و یا بزرگ باشد و بخواهید اندازه آن را تغییر دهید در اینجا اگر واحدهای اندازه px
بودند شما با یک کار طاقت فرسا مواجه بودید به این دلیل که مکان تمام آیتم ها باید دوباره مشخص و اندازه گیری می شد. اما الان که واحدها em
هستند کافی است اندازه فونت عنصر اصلی را تغییر دهید تا تمام منو و جزییاتش به صورت یکنواخت کوچک یا بزرگ شود. پس در اینجا تنها با اعمال یک خط قادر به تغییر اندازه خواهید بود.
فرض کنید می خواهیم منو را کمی کوچک تر کنیم کافی است بنویسیم:
.circular-menu {
font-size: 13px;
}
ساخت این کامپوننت در این مطلب توضیح داده شده است.
حال متوجه قدرت واحدهای نسبی مثل em
و rem
می شویم.
کدام یک؟
بعضی از طراحان به هیچ عنوان از rem
استفاده نمی کنند, آنها به این باور هستند که استفاده از rem
باعث می شود تا کامپوننت هایشان کمتر ماژولار باشند به همین دلیل فقط از em
استفاده می کنند. اما گروهی دیگر به دلیل اینکه کار با em
کمی پیچیدگی محاسبه دارد, برای جلوگیری از این پیچیدگی فقط از rem
استفاده می کنند.
Zell Liew در بلاگ خود نوشته است: “دوره ای در کارم فقط از em
استفاده کردم و دوره ای فقط از rem
که em
به ماژولار نویسی خیلی کمک می کرد و rem
به سادگی کار”. جالب است بدانید که وی هردوی این موارد را دام می داند.
پس از مدتی استفاده از این واحدها همه ما به این نتیجه می توانیم برسیم که هر کدام نقاط قوت و ضعف مخصوص به خود را دارند.
وی در این پست با بررسی چند مثال به دنبال روشن کردن این موضوع است که باید با استفاده مناسب از هر کدام بنا به شرایط موجود, از قدرت هر دو بهره ببریم. و روش کاری خود را با دو قانون بیان می کند:
- اگر ویژگی با توجه به
font-size
باید کوچک و یا بزرگ شود ازem
استفاده کنید. - بقیه ویژگی ها را با
rem
بنویسید.
او در پست خود یک کامپوننت ساده را با هردوی این واحدها می نویسد و به بررسی اینکه چگونه و چرا باید از این دو قانون استفاده کنیم می پردازد.
فقط با استفاده از Rem
فرض کنید یک عنصر شبیه به تصویر زیر داریم:
اگر بخواهیم فقط از rem
استفاده کنیم, خواهیم داشت:
.header {
font-size: 1rem;
padding: 0.5rem 0.75rem;
background: #7F7CFF;
}
از آنجایی که در یک سایت عناصر شبیه به هم که فقط از لحاظ اندازه متفاوت هستند همیشه وجود دارند, احتمال اینکه همین عنصر را با اندازه بزرگتر نیز بخواهیم زیاد است. چون سعی داریم از تکرار در کد جلوگیری کنیم باید در حد امکان از استایل های کلاس قبلی برای این عنصر نیز استفاده کنیم (وراثت):
<a href="#" class="header header--large">header!</a>
(به نحوه نوشتن کلاس ها توجه کنید. از روش BEM استفاده شده است که در آینده حتما بصورت مفصل در موردش بحث خواهیم کرد. اما بطور خلاصه: اگر بخواهیم پروژه را طوری پیاده سازی کنیم تا بتواند به راحتی گسترش پیدا کند و هر چه پروژه بزرگتر می شود کد نویسی راحتر شود نه سخت تر (از آنجا که خیلی از اجزا تکراری خواهند شد) باید یک روش مناسب برای انتخاب کلاس هایمان داشته باشیم. BEM یکی از این روش ها برای انسجام دادن به نام گذاری کلاس ها می باشد که به ماژولار نویسی هم کمک می کند. )
در CSS خواهیم داشت:
.header {
font-size: 1rem;
padding: 0.5rem 0.75rem;
background: #7F7CFF;
}
.header--large {
font-size: 2rem;
}
متاسفانه همانطور که در تصویر زیر می بینیم خروجی برای عنصر header--large.
مناسب نشد. چرا که فاصله بین متن و لبه های عنصر خیلی کم شد:
اگر اصرار داشته باشیم که همچنان از rem
استفاده کنیم باید ویژگی padding
را هم برای عنصر جدید باز نویسی کنیم.
.header {
font-size: 1rem;
padding: 0.5rem 0.75rem;
background: #7F7CFF;
}
.header--large {
font-size: 2rem;
padding: 1rem 1.5rem;
}
بله به خروجی مناسب رسیدیم, اما به چه قیمتی؟
همانطور که ملاحظه می کنید مقادیر ویژگی های font-size
و padding
برای عنصر جدید دو برابر شدند. چه می شود اگر تعداد عناصر مشابه به این هدر که قرار است با اندازه متفاوت در پروژه ظاهر شوند بیشتر شود؟ بله, هر بار باید ویژگی های مختلف را برای هدر جدید دیگر باز نویسی کنیم.
پس واضح است که استفاده از rem
باعث تکرار کد می شود و قانون Don’t Repeat Yourself) DRY (خودتو تکرار نکن دیگه :) ) ) رعایت نخواهد شود. و همینطور پیچیدگی کد زیاد می شود.
اگر em
را وارد بازی کنیم به راحتی می توانیم بدون باز نویسی ویژگی padding
به خروجی مناسب برسیم:
.header {
font-size: 1rem;
padding: 0.5em 0.75em;
background: #7F7CFF;
}
.header--large {
font-size: 2rem;
}
(البته با توجه به خوندن این پست این مطلب رو می دونید ولی باز هم برای یادآوری میگم:)
زمانی که از em
استفاده می کنیم اندازه عناصر, وابسته به font-size
همان عنصر و اجداد آن می شود پس هر بار که font-size
عنصر تغییر کند ویژگی هایی که با em
نوشته شده اند به همان نسبت تغییر می کنند.
پس تا الان به مفید بود قانون اول (اگر ویژگی با توجه به font-size
باید کوچک و یا بزرگ شود از em
استفاده کنید) پی بردیم.
فقط با استفاده از Em
در این مورد پیاده سازی با آخرین کدی که دیدیم خیلی تفاوت ندارد جز اینکه باید rem
ها تبدیل به em
شوند:
.header {
font-size: 1em;
padding: 0.5em 0.75em;
background: #7F7CFF;
}
.header--large {
font-size: 2em;
}
در اینجا هر دو عنصر header.
و header--large.
کاملا شبیه به زمانی خواهند بود که از rem
استفاده کردیم.
همین دیگه, تموم شد؟
نه :)
خیلی کم پیش می آید که در یک پروژه فقط یک هدر داشته باشیم, پس باید عناصر را در کنار هم نیز بررسی کنیم.
الگویی که در تصویر زیر مشاهده می کنید در صفحات وب کاملا رایج است
<div class="header header--large">A Header Element</div>
<p>A paragraph of text</p>
<p>A paragraph of text</p>
<div class="header">A Header Element</div>
<p>A paragraph of text</p>
برای استایل نیاز داریم تا کمی margin
به سمت چپ و راست عنصر پاراگراف اضافه کنیم:
p {
margin-left: 0.75em;
margin-right: 0.75em;
}
خروجی بصورت زیر خواهد بود:
:(
متاسفانه padding
سمت چپ و راست برای عنصر header--large.
خیلی زیاد است و باعث شده است تا چیدمان زشت بنظر برسد, چراکه شروع خطوط در یک راستا نیستند.
اگر برای استفاده از em
پافشاری کنیم باید padding-left
و padding-right
را برای عنصر بزرگتر بصورت جداگانه بازنویسی کنیم:
.header {
font-size: 1em;
padding: 0.5em 0.75em;
}
.header--large {
font-size: 2em;
padding-left: 0.375em;
padding-right: 0.375em;
margin: 0.75em 0;
}
اما به دلیل نکاتی که در مورد بالا گفته شد این کار روش مناسبی نیست پس بهتر است به جای لجبازی از واحد عزیزی به نام rem
کمک بگیریم:
.header {
padding: 0.5em 0.75rem; /* Em Rem */
font-size: 1em;
background: #7F7CFF;
}
.header--large {
font-size: 2em;
}
همانطور که می دانید rem
وابسته به font-size
عنصر ریشه (html
) است پس با تغییر اندازه font-size
عنصر header--large.
خروجی برای padding
چپ و راست تغییر نخواهد
کرد.
تا اینجا با دو کارآمد زیر آشنا شدیم که چون قانون های تجربی هستند احتمال اینکه موارد نقض پیدا کنند وجود دارد که بهتر است اگر موردی پیش آمد باهم به اشترک بگذاریم.
- اگر ویژگی با توجه به
font-size
باید کوچک و یا بزرگ شود ازem
استفاده کنید. - بقیه ویژگی ها را با
rem
بنویسید.
در مطلب بعد به نتیجه گیری کامل در مورد این دو واحد می رسیم و پاسخ سوال کدام بهتر است را بیشتر بررسی می کنیم.
ایول
عالی توضیح دادین. مثال هاتون هم خیلی گویاست
خدا وکیلی ده تا مقاله راجع به EM و Rem خوندم اما تفاوتشونو نفهمیدم و اصلا نفهمیدم کجا از em استفاده کنم و کجا از rem اما با تشکر از شما و مثال های گویاتون الان متوجه شدم بابت اون کامپوننت هم ممنون خیلی به درد بخوره
سلام
خیلی ممنون از مطالب عالیتون. بسیار حرفه ای آموزشها رو ارايه کردید.
میخواستم اگر امکان داره یک راهنما برای کد نویسی ماژولار برای css مثل کاری که framework ها انجام میدن معرفی کنید. من قصد دارم فریم ورک css شخصی خودم رو ایجاد کنم تا بتونم با سرعت زیاد سایتهای نسبتا ساده ولی با کیفیت بصری بالا طراحی کنم.
پیشاپیش سپاسگذارم
سلام. ممنون از پیامتون
سوالتون خیلی کلی هستش. ولی چند تا نکته واسه اینکه بتونید طراحی سریعتری داشته باشید رو میگم. امیدوارم بتونه کمکتون کنه.
اول اینکه حتما باید grid مخصوص به خودتون رو داشته باشید. یک گرید ساده در عین حال جامع که بشه هر صفحه آرایی رو باهاش انجام داد.
دوم اینکه به مرور زمان که پروژه های مختلف رو انجام می دید کم کم متوجه میشین که ماژول هایی هستند که دایما تکرارشون می کنید و از اول هر بار می سازینشون. مثلا باکس جستجو و دکمه کنارش. باید اینها رو بصورت یک ماژول با یک تم پایه طراحی کنید و همینطور کاملا ایزوله نسبت به عناصر دیگه باشند.
منظورم از ایزوله اینکه استایل عناصر دیگه تاثیری نزاره روی این ماژول. کلاسش رو طوری بدید که تداخل با کلاس های دیگه پیدا نکنه.
فونت سایز حتما نسبی باشه که به راحتی قابل تغییر باشه
و نکاتی که خودتون به مرور متوجه می شین.
به مرور تعداد اینچنین ماژول هایی که ساختین زیاد میشن و سرعت طراحی سایت های متخلف واستون بیشتر میشه.
و در نهایت می تونید یک تم خوب واسشون طراحی کنید و حتی به عنوان یک فریمورک عمومی معرفی کنید تا بقیه استفاده کنند.
من همینقدر تجربه دارم. امیدوارم کمکتون کنه. موفق باشید.
لطف کردید
این ابزار هم شاید به دردتون خورد
px-em.com
ابزار جالبی بود . تشکر
سلام وقت بخیر – توی طراحی طرح سایت توی فتوشاپ ابزاری هست که بهمون کمک کنه راحتتر واحد ها رو بر اساس EM یا REM استفاده کنیم ؟تشکر از مطلب خوبتون . موفق باشین
ممنون. ولی یه جا گفتید پس به em رو میاریم ولی دوباره rem توی css نوشته بودید. توی header-large. ولی عالی بود. ممنون.
مثل همیشه عالی