انیمیشن باز و بسته شدن details فقط با CSS
خلاصهٔ کاملتر
سؤال سادهای که نویسنده باهاش شروع میکنه اینه: میشه باز و بسته شدن عنصر رو فقط با CSS انیمیت کرد؟ جوابش مثبته، ولی به گفتهٔ خودش پیدا کردن یه راهحل درست حسابی بهطرز آزاردهندهای طول کشیده — بیشتر چیزهایی که پیدا کرده یا هکهای مشکلدار بودن، یا بیدلیل جاوااسکریپت میخواستن، یا فقط نصف کار رو انجام میدادن و موقع بسته شدن انیمیشنی در کار نبود.
قلب راهحل، شبهعنصر ::details-content ـه؛ یعنی همون محتوایی که باید باز و بسته بشه:
details::details-content {
block-size: 0;
overflow: hidden;
transition-property: block-size, content-visibility;
transition-duration: var(--transition-duration, 0.2s);
transition-behavior: allow-discrete;
}
details[open]::details-content {
block-size: calc-size(auto, size);
}خط کلیدی transition-behavior: allow-discrete ـه که اجازه میده خاصیتهای بهاصطلاح گسسته هم انیمیت بشن. به توضیح نویسنده، content-visibility باید کنار block-size انیمیت بشه چون زیر کاپوت یه Shadow DOM داره که نمایش محتوا رو کنترل میکنه؛ ما میخوایم تغییر content-visibility صبر کنه تا انیمیشن ارتفاع تموم بشه. overflow: hidden هم جلوی بیرونزدن محتوا حین حرکت از صفر به auto رو میگیره. برای مرورگرهایی که calc-size() رو نمیشناسن هم میشه یه block-size: auto بهعنوان جایگزین قبلش گذاشت.
نویسنده صادقانه میگه این روش موقع انتشار مقاله تو فایرفاکس کار نمیکنه و خودش هم کاربر فایرفاکسه، ولی مشکلی باهاش نداره: این یه نمونهٔ کلاسیک بهبود تدریجیه. کاربر مرورگر پشتیبانیکننده انیمیشن میبینه، بقیه همون رفتار پیشفرض باز و بسته شدن رو میگیرن و چیزی از کار نمیافته. مزیت دیگهاش اینه که از قابلیتهای خود مرورگر استفاده میکنه، پس لازم نیست بعداً یادت باشه کد هکی رو پاک کنی.
آخر مقاله یه بخش اضافه هم هست که نشون میده چطور میشه نشانگر پیشفرض ::marker رو برداشت و با یه کاراکتر دلخواه از طریق ::before جایگزینش کرد و موقع باز شدن چرخوندش. نویسنده منبع اصلی راهحل رو هم یه ویدیو از Zoran Jambor در CSS Weekly معرفی میکنه.
نکات کلیدی:
- انیمیت کردن هر دو حالت باز و بسته شدن بدون جاوااسکریپت
- شبهعنصر ::details-content هدف اصلی استایلدهیه
- transition-behavior: allow-discrete چیزیه که کل ماجرا رو ممکن میکنه
- content-visibility باید همراه block-size گذار کنه چون روی Shadow DOM سواره
- فایرفاکس فعلاً پشتیبانی نمیکنه؛ رفتار پیشفرض بهعنوان جایگزین باقی میمونه




