تایپوگرافی سیال بهتر با progress()
خلاصهٔ کاملتر
تایپوگرافی سیال چیز تازهای نیست و این روزها بیشتر آدمها سراغ clamp() با مقادیر از پیشمحاسبهشدهٔ ابزارهایی مثل Utopia یا Fluid Type Scale میرن. تو دو تا اندازه و دو تا breakpoint میدی و یه مقدار میگیری که بینشون سیال scale میشه. نویسنده میگه اما یه مشکل پنهون اینجاست.
این ابزارها معمولاً اندازهها رو به rem تبدیل میکنن که خوبه، ولی breakpointها رو هم بیسروصدا به rem تبدیل میکنن — و همینجاست که خراب میشه. اگه کاربری فونت پایهشو از ۱۶ به ۳۲ پیکسل ببره، تو همون عرض ۱۲۰۰ پیکسلی صفحه، فونتی که باید ۳۲ پیکسل میبود میشه ۲۴ پیکسل؛ یعنی با اینکه کاربر فونت رو بزرگتر خواسته، متن کوچیکتر شده. این دقیقاً برخلاف ترجیح و دسترسپذیری کاربره.
راهحل به گفتهٔ نویسنده اینه که محاسبه رو به خود CSS برگردونیم و واحدها رو ترکیب کنیم: دقتِ breakpointهای پیکسلی بهعلاوهٔ دسترسپذیریِ اندازههای rem. روش مناسب هم range mapping هست؛ یعنی موقعیت عرض فعلی صفحه رو تو بازهٔ ورودی حساب کنی و به بازهٔ خروجی نگاشت کنی. تابع جدید progress() دقیقاً همینه:
--min-size: 1rem;
--min-size-viewport: 400px;
--max-size: 1.5rem;
--max-size-viewport: 1200px;
--progress: progress(100vi, var(--min-size-viewport), var(--max-size-viewport));progress() یه ترکیب واحد (تا وقتی همنوع باشن) رو قبول میکنه، یه عدد بیواحد بین ۰ و ۱ برمیگردونه و چون همیشه بین صفر و یکه، خودش اندازه رو بین کف و سقف clamp میکنه.
نویسنده میگه این تکنیک الان کمی پرحرفه، ولی با custom propertyها قابلاستفادهٔ مجدده و CSSِ آینده خیلی مختصرترش میکنه: با @function میشه کل محاسبه رو تو یه تابع گذاشت (فعلاً فقط Chromium) و با calc-mix() بقیهٔ نگاشت بازه رو کامل کرد (که هنوز هیچ مرورگری پشتیبانی نمیکنه). محدودیت اصلی فعلی هم خود progress() هست که همهٔ مرورگرهای مدرن جز Firefox پشتیبانیش میکنن، پس هنوز آمادهٔ production نیست و بهتره با @supports یه fallback بذاری.
یه نکتهٔ مهم هم اینه که این روش مشکل جداگانهٔ zoom تا ۲۰۰٪ متن رو حل نمیکنه و اون هنوز به تست دستی نیاز داره.
نکات کلیدی:
- ابزارهای clamp() از پیشمحاسبهشده، breakpointها رو هم به rem تبدیل میکنن
- بزرگکردن فونت پیشفرض کاربر میتونه متن سیال رو برخلاف خواستش کوچیک کنه
- راهحل: برگردوندن محاسبه به CSS با range mapping و ترکیب px برای breakpoint و rem برای اندازه
- progress() یه عدد بیواحد ۰ تا ۱ میده و خودش اندازه رو clamp میکنه
- آیندهٔ CSS با @function و calc-mix() این کارو مختصرتر میکنه؛ فعلاً Firefox از progress() پشتیبانی نمیکنه




