ارتفاعِ «درستودرمون» برای selectِ سفارشی
خلاصهٔ کاملتر
نویسنده (Jake Archibald) میگه بعد از یه سخنرانی دربارهٔ selectِ کاملاً قابلاستایل و حین ساختِ دموها، متوجه یه الگوی سایزدهی شد که تقریباً همیشه «همونیه که میخوای»، ولی خودش نتونست تو CSS پیادهاش کنه و آخر Ian Kilpatrick قابلیتی که جا افتاده بود رو نشونش داد. هدف اینه که pickerِ بازشوندهٔ select همیشه یه ارتفاعِ «درستودرمون» داشته باشه.
بخش اول ماجرا اینه که picker نباید از viewport بلندتر شه و باید یه حاشیه از لبه نگه داره. نویسنده برای این کار از max-block-size: stretch بههمراهِ یه margin-block-end استفاده میکنه و برای مرورگرهایی که stretch رو ندارن، یه fallback با calc(100% - var(--viewport-margin)) میذاره.
مشکلِ بعدی وقتیه که picker به بالای دکمه flip میشه. نویسنده بهجای مقادیر پیشفرضِ position-try، از position-try-fallbacks با مقادیرِ flip-block، flip-inline و ترکیبشون استفاده میکنه. این flipها یه «جادوی تاریک» دارن: موقع flip سعی میکنن بعضی استایلهای دیگه رو هم برعکس کنن، و خوشبختانه margin جزو همونهاست؛ برای همین وقتی picker به بالا flip میشه، margin-block-end مثل margin-block-start رفتار میکنه. نویسنده اشاره میکنه که CSS Working Group قرار گذاشته پیشفرضها رو به چیزی شبیه همین تغییر بده تا این override دیگه لازم نباشه.
بخش دومِ مسئله جلوگیری از خیلی کوچیک شدنِ pickeره. کروم یه min-block-size پیشفرضِ 1lh میذاره که picker رو موقع نزدیک شدن به لبهٔ viewport غیرقابلاستفاده کوچیک میکنه. اگه صرفاً این مقدار رو بزرگتر کنی، وقتی گزینهها کمن، picker بیخودی بزرگ و بدریخت میشه. چیزی که میخوای یهجور min(fit-content, 12em)ه، ولی min() سایزهای درونذاتی مثل fit-content رو قبول نمیکنه.
اینجاست که نویسنده به تابعِ calc-size() میرسه، همون تیکهای که Ian Kilpatrick براش باز کرد:
.custom-select::picker(select) {
min-block-size: calc-size(fit-content, min(size, 12em));
}نویسنده توضیح میده که calc-size() اجازه میده یه سایزِ درونذاتی رو تو آرگومان اول بذاری و تو آرگومان دوم روش محاسبه کنی، جایی که کلیدواژهٔ size نمایندهٔ همون سایزِ درونذاتیه. یهکم عجیبه ولی کار میکنه؛ البته فعلاً فقط تو کروم. چون Firefox و Safari هنوز calc-size() رو ندارن، نویسنده یه راهِ موقتیِ hackی هم با @supports میذاره که اگه پشتیبانی نبود، بر اساس تعداد گزینهها و optgroupها (مثلاً با :has(:where(option:nth-of-type(4)))) رفتار رو تنظیم کنه.
نکات کلیدی:
- هدف: ارتفاعِ pickerِ selectِ سفارشی نه بیشازحد بلند بشه، نه بیشازحد کوچیک
- سقفِ ارتفاع با max-block-size: stretch و یه margin از لبهٔ viewport کنترل میشه
- موقع flip شدنِ picker به بالا، margin هم برعکس میشه که اینجا دقیقاً بهدرد میخوره
- برای کفِ ارتفاع، calc-size(fit-content, min(size, 12em)) مشکل min() رو حل میکنه
- calc-size() فعلاً فقط تو کروم هست؛ برای Firefox و Safari یه fallback لازمه




