نام Houdini گاهی طوری معرفی میشود که انگار یک قابلیت واحد است و تمام CSS را در همه مرورگرها قابل برنامهنویسی میکند. چنین برداشتی دقیق نیست. Houdini چتری برای چند API مرتبط با توسعهپذیری CSS است و وضعیت پشتیبانی هر بخش تفاوت دارد. ثبت Custom Property با @property را نباید با CSS Painting API یا APIهای دیگر همرده و همپشتیبانی دانست. برای استفاده در محصول، ابتدا قابلیت دقیق و نیاز آن را مشخص کنید و مسیر بدون پشتیبانی را نگه دارید. عنوان «آینده CSS» بهتنهایی دلیل انتخاب فناوری نیست.
چند API با هدفهای متفاوت
معرفی Houdini APIs در MDN مجموعهای از امکانات را توضیح میدهد. Properties and Values API به ثبت ویژگی سفارشی با نوع و قواعد مشخص مربوط است. Typed OM راههایی برای کار ساختیافتهتر با مقدارهای CSS مطرح میکند. Painting API امکان تولید نقاشی سفارشی برای کاربردهای مشخص دارد. این خانواده را یک کتابخانه واحد که نصب و فعال میشود ندانید. هر بخش قرارداد، محدودیت و جدول سازگاری خود را دارد.
برای تیم فرانتاند، سؤال مناسب این است: کدام مشکل را با کدام API حل میکنیم؟ اگر فقط رنگ و فاصله مشترک لازم دارید، Custom Property عادی شاید کافی باشد. اگر مقدار باید نوع مشخص داشته باشد یا در انیمیشن رفتار روشنتری بدهد، ثبت Property میتواند مطرح شود. اگر افکت با Gradient معمولی قابل اجراست، Paint Worklet شاید پیچیدگی بیدلیل بسازد. ابزار را از نیاز انتخاب کنید، نه از جذابیت نام مجموعه.
Custom Property عادی و ثبتشده
ویژگی سفارشی معمولی با نام آغازشده از دو خط تیره، دادهای را برای مصرف در CSS نگه میدارد. ثبت با @property میتواند syntax، مقدار اولیه و رفتار ارثبری را مشخص کند. این قرارداد به مرورگر میگوید انتظار چه نوع مقداری دارد. ثبت به معنی اعتبارسنجی داده تجاری یا امنیتی نیست؛ مربوط به رفتار CSS است. اگر ورودی کاربر دارید، همچنان باید قرارداد و محدوده آن را در لایه درست بررسی کنید.
برای مثال، زاویهای که برای چرخش یک Gradient استفاده میشود، میتواند بهعنوان angle ثبت شود. با نبود ثبت، بعضی رفتارهای انتقال ممکن است مانند مقدار تایپشده پیوسته نباشند. این تفاوت را برای همه نوعها و همه مرورگرها تعمیم ندهید. باید همان ویژگی و همان مصرف را بررسی کنید. نامگذاری نیز مهم است؛ Property عمومی و مبهم در پروژه بزرگ میتواند با بخشهای دیگر تداخل معنایی پیدا کند، حتی اگر از نظر فنی معتبر باشد.
نمونه کامل @property
این مثال یک پسزمینه تزئینی را با یک مقدار زاویه ثبتشده میچرخاند. همه HTML و CSS در یک فایل است و به JavaScript، کتابخانه یا تصویر خارجی نیاز ندارد. فایل را با نام index.html ذخیره و در مرورگر باز کنید. در محیط پشتیبان، زاویه به شکل پیوسته تغییر میکند. در محیط فاقد ثبت، ظاهر پایه و متن همچنان وجود دارند و نباید برای فهم محتوا به حرکت وابسته باشند. کاهش حرکت نیز در CSS لحاظ شده است.
<!doctype html>
<html lang="fa" dir="rtl"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>نمونه property ثبتشده</title>
<style>
@property --demo-angle {syntax:"<angle>";inherits:false;initial-value:0deg}
body {font-family:system-ui;background:#edf0f5;color:#172330;margin:0;padding:3rem 1rem}
.demo {--demo-angle:0deg;max-width:36rem;margin:auto;padding:1rem;border-radius:1rem;background:conic-gradient(from var(--demo-angle),#386ac5,#65c5b1,#386ac5);animation:turn 8s linear infinite}
.content {background:white;padding:2rem;border-radius:.6rem;line-height:1.9}
@keyframes turn {to {--demo-angle:360deg}}
@media(prefers-reduced-motion:reduce) {.demo {animation:none}}
</style></head><body><main class="demo"><section class="content"><h1>یک مقدار زاویه ثبتشده</h1><p>حرکت فقط تزئینی است؛ متن بدون حرکت هم کامل و خواناست.</p><p>این نمونه از CSS Painting API استفاده نمیکند.</p></section></main></body></html>
انتظار میرود کارت با متن خوانا روی زمینه روشن نمایش داده شود و پسزمینه در حالت عادی حرکت کند. بخش تزئینی محتوا یا وضعیت عملیاتی را نمایش نمیدهد. این مثال ادعای فعال بودن CSS Painting API ندارد؛ فقط یکی از بخشهای خانواده Houdini را نشان میدهد. دستور ذخیره و باز کردن برای اجرای مخاطب است و مقاله ادعای آزمون مرورگر در محیط انتشار ندارد. اگر ظاهر پایه هم دیده نمیشود، مسئله را از وابستگی پشتیبانی حرکت جدا بررسی کنید.
اجزای ثبت چه معنایی دارند؟
syntax نوع مورد انتظار را مشخص میکند و initial-value مقدار آغازین معتبر میدهد. inherits تعیین میکند مقدار چگونه به فرزندان مربوط شود. انتخاب این موارد باید با کاربرد سازگار باشد. اگر ویژگی برای یک Component محلی است، ارثبری ناخواسته میتواند نتیجه گیجکننده بسازد. اگر برای Theme مشترک طراحی شده، نیاز متفاوت است. قرارداد را در مستند Component بنویسید تا نفر بعدی بداند چرا این مقدار ثبت شده و کجا باید تغییر کند.
در نمونه، مقدار اولیه صفر درجه است و متغیر در یک Gradient مصرف میشود. لایه متنی با پسزمینه خوانا از تزئین جداست. این تفکیک کمک میکند نبود حرکت یا تغییر رنگ، معنی محتوا را از بین نبرد. برای استفاده در رابط واقعی، کنتراست و دامنه حرکت را با محتوا بسنجید. داشتن مقدار نوعدار، طراحی خوب را تضمین نمیکند. ممکن است انیمیشن از نظر فنی صحیح باشد ولی برای کاربر اضافی یا آزاردهنده باشد.
Painting API را جدا ارزیابی کنید
مرجع CSS Painting API در MDN آن را با وضعیت دسترسی محدود معرفی میکند. بنابراین نباید صرف وجود Houdini یا @property نتیجه گرفت Paint Worklet در تمام مرورگرهای مخاطب آماده است. Worklet، زمینه اجرا و بارگذاری خود را دارد و مانند یک تابع معمولی DOM با دسترسی نامحدود نیست. اگر از این مسیر استفاده میکنید، قرارداد دقیق و نیاز ارتباط امن را از مرجع همان API بخوانید.
برای محتوای ضروری، مسیر جایگزین لازم است. افکت تزئینی میتواند با رنگ یا Gradient معمولی جایگزین شود. لوگو، متن یا اطلاعات مهم را به موفق بودن بارگذاری Worklet وابسته نکنید. خطای بارگذاری و عدم پشتیبانی را با خطای داده اشتباه نگیرید. اگر نمونه آموزشی Painting ارائه میدهید، فایل Worklet، صفحه مصرفکننده و روش سرو کردن باید کامل باشند؛ یک تابع registerPaint جدا، مثال قابل اجرای کامل نیست. این مقاله برای جلوگیری از این ابهام، فقط نمونه مستقل @property دارد.
Typed OM و وعده عملکرد
کار با مقدار ساختیافته میتواند بعضی عملیات را روشنتر کند، اما از نام Typed OM نمیتوان نتیجه گرفت هر برنامه سریعتر میشود. هزینه واقعی به نوع کار، تعداد تغییرها و مرورگر وابسته است. تبدیل بیدلیل کد ساده به API کمتر آشنا ممکن است نگهداری را سخت کند. ابتدا مسئله را اندازهگیری و مشخص کنید و سپس روش را انتخاب کنید. ادعای درصد بهبود بدون محیط و روش قابل تکرار، اطلاعات قابل اتکا نیست.
بهخصوص درباره انیمیشن، همه Propertyها هزینه یکسان ندارند. تغییر مقدار Gradient یا نقاشی سفارشی میتواند نیاز به کار گرافیکی داشته باشد. استفاده از API جدید، آن را خودکار به عملیات ارزان Compositor تبدیل نمیکند. در بررسی کارایی صفحه، داده باید در زمینه دستگاه و تجربه واقعی خوانده شود. افکت باید ارزش بصری مشخصی داشته باشد تا هزینه پردازش و پیچیدگی آن توجیه شود.
پشتیبانی را قابلیتبهقابلیت ببینید
برای هر بخش، جدول سازگاری جاری و مرورگرهای هدف پروژه را بررسی کنید. عدد نسخهای که در یک مقاله قدیمی آمده، قرارداد امروز نیست. اگر به تشخیص قابلیت در JavaScript نیاز دارید، همان API را بررسی کنید و مسیر پایه را جدا نگه دارید. بررسی وجود یک ویژگی از خانواده، وجود تمام اعضا را ثابت نمیکند. برای CSS هم رفتار نبود پشتیبانی را از ابتدا طراحی کنید تا صفحه قابل استفاده بماند.
در View Transition API نیز Same-document و Cross-document را باید جدا دید. این عادت در فناوریهای جدید مفید است: نام خانواده را به ضمانت عمومی تبدیل نکنید. اگر یک ویژگی تنها تزئینی است، نبود آن نباید مانع انجام کار شود. اگر ضروری است، باید دلیل و پوشش مخاطب روشن باشد. انتخاب فناوری به سیاست پشتیبانی محصول وابسته است، نه فقط مرورگر دستگاه توسعهدهنده.
ارثبری، Cascade و Design Tokens
ثبت یک Property قواعد Cascade را حذف نمیکند. اگر چند قانون مقدار میدهند، منبع، اهمیت و ترتیب همچنان مطرحاند. در Cascade Layers، رابطه گروههای سبک جدا تنظیم میشود. همچنین نام Custom Property بهتنهایی آن را Design Token معتبر نمیکند. Token به معنی و قرارداد طراحی نیاز دارد؛ ثبت CSS بیشتر درباره رفتار مقدار در مرورگر است. این دو میتوانند کنار هم باشند ولی جای هم را نمیگیرند.
برای تیم، فهرست Propertyهای ثبتشده، نوع و کاربرد را نگه دارید. از نامهای مشترک بدون هماهنگی استفاده نکنید. اگر مقدار از Theme میآید، روشن کنید Component چه محدودهای را میپذیرد. تغییر نوع یا ارثبری ممکن است رفتار بخشهای دیگر را تغییر دهد و باید مانند تغییر قرارداد دیده شود. صرف اینکه نام در CSS است، به معنی بیاثر بودن تغییر برای API طراحی نیست. مستند کوتاه از اصلاحهای پراکنده جلوگیری میکند.
انتخاب محدود و قابل نگهداری
برای شروع، یک مسئله کوچک مانند انیمیشن مقدار نوعدار انتخاب کنید و رفتار پایه را حفظ کنید. اگر CSS معمولی همان نتیجه را سادهتر میدهد، لازم نیست Houdini اضافه شود. اگر نیاز خاصی دارید، همان API را با محدودیت و مرورگر هدف معرفی کنید. آینده CSS یک مسیر واحد و قطعی نیست و همه پیشنهادها به یک اندازه فراگیر نمیشوند. تصمیم امروز باید بر قابلیت موجود و نیاز واقعی تکیه کند، نه وعدهای کلی درباره جایگزینی همه روشهای قبلی.
هنوز دیدگاهی ثبت نشده
اولین نفری باشید که نظر میدهد!