جایگزین تابع progress() در CSS برای همه مرورگرها
خلاصهٔ کاملتر
تابع progress(value, start, end) تو CSS حساب میکنه یه مقدار کجای بین یه کف و سقف نشسته و یه عدد بدون واحد بین 0 تا 1 میده. فرمولش سادهست: (مقدار فعلی منهای start) تقسیم بر (end منهای start). به این کار normalization میگن، یعنی آوردن یه عدد به بازه ۰ تا ۱. نویسنده میگه تا وقتی پشتیبانی مرورگرها کامل بشه، میشه همین فرمول رو دستی پیاده کرد.
اگه همه مقدارها بدون واحد باشن، کار راحته: فرمول رو مستقیم داخل calc() مینویسی و با clamp() بین ۰ و ۱ نگهش میداری تا دقیقاً مثل progress() رفتار کنه. ولی معمولاً با واحدهایی مثل px و rem و vw کار داریم و خروجی باید بدون واحد باشه. مرورگرهایی که typed arithmetic (یعنی تقسیم یه طول بر طول دیگه و گرفتن عدد خالص) رو بلدن این کارو میکنن، ولی به گفته نویسنده Firefox هنوز نه.
راهحل، ترفند tan(atan2()) ـه. تابع atan2(y, x) خودش دو مقدار رو بر هم تقسیم میکنه، پس offset (یعنی value منهای start) رو بهعنوان آرگومان اول و span (یعنی end منهای start) رو بهعنوان دومی میدی و tan عدد خالص رو برمیگردونه. اگه همه مقدارها یه واحد داشته باشن، مستقیم کار میکنه.
مشکل وقتی پیش میاد که واحدها قاطی باشن، مثلاً تو fluid typography (یعنی فونتی که با عرض صفحه بزرگ و کوچیک میشه) که 100vw رو با 320px و 1200px مقایسه میکنی. اینجا 100vw رو با @property بهعنوان ثبت میکنی تا مرورگر اونو به px تبدیل کنه:
@property --vw {
syntax: "<length>";
inherits: true;
initial-value: 100vw;
}
:root {
--progress: clamp(0, tan(atan2(var(--vw) - 320px, 1200px - 320px)), 1);
}اگه بخوای مرزها رو با rem بدی، دیگه نمیشه همهچیزو جدا ثبت کرد چون همیشه به px تبدیل میشه. نویسنده پیشنهاد میده فقط دو مقداری که به atan2() میرسن، یعنی --offset و --span، رو با @property ثبت کنی. اینطوری همون محاسبه progress() رو با پشتیبانی خیلی بهتر داری و اگه نسخه بدون clamp رو بخوای، کافیه clamp() رو برداری.
نکات کلیدی:
- فرمول progress برابره با (value - start) / (end - start) و خروجی بین ۰ تا ۱ هست.
- برای عددهای بدون واحد، calc() و clamp() کافیه.
- Firefox هنوز typed arithmetic رو پشتیبانی نمیکنه، برای همین ترفند tan(atan2()) لازمه.
- برای px بهعلاوه یه واحد دیگه، فقط مقدار غیر px رو بهعنوان ثبت کن.
- برای چند واحد غیر px، --offset و --span رو با @property ثبت کن.




