وقتی صحبت از واحدهای مقداردهی در CSS میشود، گزینههای زیاد و خوبی برای انتخاب داریم. در دنیای امروز برای طراحیهای responsive، واحدهای relative مانند em یا rem مسقیما سازگاری و انعطافپذیری را در اختیار ما میگذارند و این موضوع اجازه میدهد تا اندازهها بر اساس font-sizeهای تعریف شده تعیین شوند. در این مقاله قصد داریم تا در مورد تفاوت بین em و rem صحبت کنیم و بررسی کنیم که استفاده از کدام یک از آنها بهتر است.
پیکسل (px) سادهترین واحد مقداردهی است که مورد استفاده قرار میگیرد. همه میدانند که یک پیکسل چیست و اندازه آن چقدر است (اگرچه اندازه یک پیکسل همیشه یکسان نیست) و هنگام استفاده از آن احساس راحتی دارند. زیرا پیکسل به راحتی قابل ترجمه است و طراحان معمولاً برای کارهای خود از آن استفاده میکنند.
اما سوال این است که پیکسل چه مشکلی دارد؟
Accessibility یکی از مهمترین موضوعاتی است که حتما باید به آن توجه شود. اگر تمام اندازههای فونتها، المنتها و فاصلهها را بر حسب پیکسل تنظیم کنیم، کار حرفهای و درستی انجام ندادهایم.
در اکثر مرورگرها، کاربر میتواند اندازه فونت مرورگر پیشفرض(معمولاً ۱۶px) خود را با اندازههای متفاوتی تنظیم کند. اگر کاربر پیشفرض خود را روی ۲۰px تنظیم کند، همه font-sizeها باید بر اساس آن مقیاس تعیین شوند.
با این حال اگر در وبسایت خود اندازه فونتها را برحسب پیکسل تنظیم کنیم، مثلا اگر اندازه heading برابر با ۳۰px باشد مقدار آن همیشه ۳۰px خواهد بود. این موضوع شاید از نظر طراح بسیار خوب باشد اما ممکن است از دید کاربر این چنین نباشد.
em از دنیای تایپوگرافی الهام گرفته شده است و واحدی است که امکان تنظیم font-size یک المنت را نسبت به اندازه فونت المنت parent آن فراهم میکند.
این مثال ساده را در نظر بگیرید:
.parent { font-size: 18px; } .child { font-size: 1.5em; }
در مثال بالا font-size المنت child برابر ۲۷px (1.5*18px) خواهد بود.
اگر المنت parent مقداری را برای font-size مشخص نکند، مقدار دیگری در سطح بالاتر درخت DOM جستجو میشود. اما اگر هیچ font-sizeای تا المنت root (<html>) مشخص نشده باشد، از مقدار پیشفرض مرورگر ۱۶px استفاده میشود.
بطور خلاصه، em را میتوان تقریبا در هر جایی که نیاز به استفاده از واحد طول است به کار برد، مثلا:
هنگامی که واحدهای em در ویژگیهای دیگری غیر از font-size استفاده میشوند، مقدار نسبت به font-size خود المنت تنظیم میشود.
در ادامه مثال بالا:
.parent { font-size: 18px; } .child { font-size: 1.5em; padding: 2em 1em; }
padding بالا و پایین در المنت child برابر ۵۴px خواهد بود. این اندازه ۲ برابر font-size المنت فعلی ما است (۲ * ۲۷px)
padding چپ و راست نیز در المنت child برابر ۲۷px خواهد بود. این اندازه ۱ برابر font-size المنت مدنظر ما است.
یادآوری: وقتی از em در font-size استفاده میشود، اندازه نسبت به اندازه فونت المنت parent است. هنگامی که در ویژگیهای دیگر مورد استفاده میگیرد، نسبت به font-size خود المنت است.
تا اینجا همه چیز با استفاده از واحد em خوب پیش رفته است، اما یک مشکل میتواند ایجاد شود و آن این است که واحد میتواند از یک سطح به سطح دیگر ترکیب شود.
یک مثال دیگر مشابه مثال قبل داریم:
.parent { font-size: 15px; } .child { font-size: 2em; }
و از آن در فایل html خود به این شکل استفاده میکنیم:
<div class="parent"> I'm 15px <div class="child"> I'm 30px, as expected <div class="child"> I'm 60px, trouble starts! <div class="child"> I'm 120px, now we're really in trouble! </div> </div> </div> </div>
بنابراین، اثر واحدهای em زمانی که چندین المنت داخل یکدیگر قرار گیرند، میتواند باهم ترکیب شود. این موضوع یک مشکل به حساب میآید و باعث شده است تا واحد rem ایجاد شود.
واحد rem که مخفف root em است یک واحد relative است و همیشه بر اساس مقدار font-size المنت root که المنت <html> است، تنظیم میشود. اگر المنت <html> اندازه فونت مشخصی نداشته باشد، از مقدار پیشفرض مرورگر، یعنی ۱۶px استفاده میشود.
به این معنی که با استفاده از واحد rem، مقادیر المنتهای parent نادیده گرفته شده و تنها مقدار root در نظر گرفته میشود.
اکنون مثالی که قبلا داشتیم، این بار با rem بررسی میکنیم:
.html { font-size: 16px; } .parent { font-size: 15px; } .child-rem { font-size: 2rem; } <div class="parent"> I'm 15px <div class="child-rem"> I'm 32px, as expected <div class="child-rem"> I'm 32px, yep! <div class="child-rem"> I'm 32px, like clockwork! </div> </div> </div> </div>
در نتیجه، استفاده از واحدهای rem به ما این امکان را میدهد تا از اثر ترکیبی واحدهای em جلوگیری کنیم. با rem، همه چیز همیشه و به طور مداوم بر اساس font-size یا المنت ریشه است، بنابراین هیچ مشکلی پیش نمیآید.
همین امر در مورد مقادیر دیگری غیر از اندازه فونت مانند margin، padding و … نیز صدق میکند.
با توجه به این که با تفاوت بین em و rem آشنا شدیم اما واقعاً نمیتوانیم به طور صریح مشخص کنیم که کدام یک بهتر است، چون همه چیز به ترجیحات شخصی افراد بستگی دارد. برخی از طراحان دوست دارند برای همه ویژگیها از واحدهای rem استفاده کنند زیرا سازگاری بالایی دارند و قابل پیشبینی هستند، در حالی که برخی دیگر دوست دارند در بخشهایی که تاثیرگذاری المنت parent منطقیتر است از واحدهای em استفاده کنند.