متحرک کردن به ارتفاع: خودکار. (و سایر کلمات کلیدی اندازه گیری ذاتی) در CSS

از ویژگی interpolate-size یا تابع calc-size() برای فعال کردن انتقال صاف و انیمیشن از طول به کلمات کلیدی اندازه ذاتی و برگشت استفاده کنید.

مقدمه

یکی از ویژگی های CSS که اغلب درخواست می شود، توانایی متحرک سازی به height: auto . یک تغییر جزئی از این درخواست، انتقال ویژگی width به جای height ، یا انتقال به هر یک از اندازه‌های ذاتی دیگر است که با کلمات کلیدی مانند min-content ، max-content و fit-content نشان داده شده است.

به عنوان مثال، در نسخه ی نمایشی زیر، خوب است که برچسب ها به راحتی به عرض طبیعی خود در هنگام نگه داشتن نمادها متحرک شوند.

CSS مورد استفاده به شرح زیر است:

nav a {
    width: 80px;
    overflow-x: clip;
    transition: width 0.35s ease; /* 👈 Transition the width */

    &:hover,
    &:focus-visible {
        width: max-content; /* 👈 Doesn't work with transitions */
    }
}

حتی اگر یک transition برای انتقال ویژگی width اعلام شود، و width: auto در :hover اعلان شده است، هیچ انتقال صافی اتفاق نمی‌افتد. در عوض، تغییر ناگهانی است.

متحرک سازی به و از کلمات کلیدی اندازه ذاتی با interpolate-size

پشتیبانی مرورگر

  • کروم: 129.
  • لبه: پشتیبانی نمی شود.
  • فایرفاکس: پشتیبانی نمی شود.
  • سافاری: پشتیبانی نمی شود.

ویژگی CSS interpolate-size به شما امکان می دهد تا روی اینکه آیا انیمیشن ها و انتقال کلمات کلیدی اندازه ذاتی CSS باید مجاز باشند یا نه، کنترل کنید.

مقدار پیش فرض آن numeric-only است که درون یابی را فعال نمی کند. هنگامی که ویژگی را روی allow-keywords تنظیم می‌کنید، در مواردی که مرورگر می‌تواند آن کلمات کلیدی را متحرک کند، از درون یابی از طول به کلمات کلیدی اندازه ذاتی CSS استفاده می‌کنید.

طبق مشخصات :

  • numeric-only : یک <intrinsic-size-keyword> را نمی توان درون یابی کرد.
  • allow-keywords : اگر یکی از آنها <intrinsic-size-keyword> و دیگری <length-percentage> باشد، می توان دو مقدار را درون یابی کرد. […]

از آنجا که ویژگی interpolate-size یکی از ویژگی‌هایی است که به ارث می‌رسد، می‌توانید آن را در :root اعلام کنید تا انتقال به و از کلمات کلیدی اندازه ذاتی برای کل سند فعال شود. این رویکرد توصیه شده است.

/* Opt-in the whole page to interpolate sizes to/from keywords */
:root {
    interpolate-size: allow-keywords; /* 👈 */
}

در دمو زیر این قانون به کد اضافه می شود. در نتیجه، انیمیشن ها به عرض و از width: auto به خوبی کار می کنند (در مرورگرهای دارای پشتیبانی):

با محدود کردن انتخابگر، دسترسی به انتخاب را محدود کنید

اگر می‌خواهید انتخاب کردن allow-keywords فقط به یک زیردرخت از سند خود محدود کنید، انتخابگر را از :root فقط به عنصری که می‌خواهید هدف قرار دهید تنظیم کنید. به عنوان مثال، در صورتی که <header> صفحه شما با این نوع انتقال ها سازگار نباشد، می توانید گزینه opt-in را فقط به عنصر <main> و فرزندان آن به صورت زیر محدود کنید:

main { /* 👈 Scope the opt-in to only <main> and its descendants */
    interpolate-size: allow-keywords;
}

چرا به صورت پیش‌فرض به انیمیشن‌ها اجازه نمی‌دهید تا کلمات کلیدی را اندازه‌گیری کنند؟

یک بازخورد رایج در مورد این مکانیسم انتخاب این است که مرورگرها باید به طور پیش‌فرض اجازه انتقال و انیمیشن‌ها را از اندازه ذاتی کلمات کلیدی به طول دهند.

گزینه فعال کردن این رفتار در طول توسعه این ویژگی مورد بررسی قرار گرفت. گروه کاری متوجه شد که فعال کردن این مورد به طور پیش‌فرض سازگار با عقب نیست، زیرا بسیاری از شیوه نامه‌ها فرض می‌کنند که کلمات کلیدی اندازه ذاتی (مانند محتوای auto یا min-content ) را نمی‌توان متحرک کرد. می توانید جزئیات مربوط به موضوع CSS Working Group را در این نظر بیابید.

بنابراین ملک یک انتخاب است. به لطف ویژگی وراثتی آن، انتخاب یک سند کامل صرفاً یک تعریف interpolate-size: allow-sizes در :root همانطور که قبلاً توضیح داده شد است.

با calc-size() متحرک کردن کلمات کلیدی اندازه‌گیری درونی و از آن‌ها

پشتیبانی مرورگر

  • کروم: 129.
  • لبه: 129.
  • فایرفاکس: پشتیبانی نمی شود.
  • سافاری: پشتیبانی نمی شود.

راه دیگر برای فعال کردن درون یابی به و از کلمات کلیدی اندازه ذاتی، استفاده از تابع calc-size() است. این اجازه می دهد تا ریاضیات در اندازه های ذاتی به روشی ایمن و کاملاً تعریف شده انجام شود.

تابع به ترتیب دو آرگومان را می پذیرد:

  • یک پایه calc-size ، که می تواند یک <intrinsic-size-keyword> باشد، اما همچنین یک calc-size() تودرتو باشد.
  • یک محاسبه اندازه calc ، که به شما امکان می دهد محاسبات را با استفاده از مبنای اندازه calc انجام دهید. برای مراجعه به مبنای calc-size از کلمه کلیدی size استفاده کنید.

در اینجا چند نمونه آورده شده است:

width: calc-size(auto, size);        // = the auto width, unaltered
width: calc-size(min-content, size); // = the min-content width, unaltered

با اضافه کردن calc-size() به نسخه آزمایشی اصلی، کد به شکل زیر است:

nav a {
    width: 80px;
    overflow-x: clip;
    transition: width 0.35s ease;

    &:hover,
    &:focus-visible {
        width: calc-size(max-content, size); /* 👈 */
    }
}

از نظر بصری، نتیجه دقیقاً مشابه زمانی است که interpolate-size استفاده می‌کنیم. بنابراین در این مورد خاص باید از interpolate-size استفاده کنید.

جایی که calc-size() می درخشد توانایی آن برای انجام محاسبات است، چیزی که نمی توان با interpolate-size انجام داد:

width: calc-size(auto, size - 10px); // = The auto width minus 10 pixels
width: calc-size(min-content, size + 10px); // = The min-content width plus 10 pixels
width: calc-size(max-content, size * .5);   // = Half the max-content width
width: calc-size(fit-content, size - 10%);  // = 10% less than the fit-content width

برای مثال، اگر می‌خواهید همه پاراگراف‌های یک صفحه به نزدیک‌ترین مضرب 50px اندازه شوند، می‌توانید از موارد زیر استفاده کنید:

p {
    width: calc-size(fit-content, round(up, size, 50px));
    height: calc-size(auto, round(up, size, 50px));
}

کاری که calc-size() نیز به شما امکان می دهد بین دو calc-size() درون یابی کنید زمانی که هر دو پایه اندازه calc آنها یکسان هستند. این نیز چیزی است که نمی توان با interpolate-size به دست آورد.

#element {
    width: min-content; /* 👈 */
    transition: width 0.35s ease;

    &:hover {
        width: calc-size(min-content, size + 10px); /* 👈 */
    }
}

چرا <intrinsic-size-keyword> در calc() اجازه نمی دهید؟

سوالی که معمولا با calc-size() مطرح می شود این است که چرا گروه کاری CSS تابع calc() را برای پشتیبانی از کلمات کلیدی اندازه ذاتی تنظیم نکرده است.

یکی از دلایل این امر این است که شما مجاز به ترکیب و مطابقت کلمات کلیدی اندازه ذاتی در هنگام انجام محاسبات نیستید. برای مثال، ممکن است وسوسه شوید که calc(max-content - min-content) بنویسید که معتبر به نظر می رسد، اما در واقعیت اینطور نیست. calc-size() صحت را اعمال می کند زیرا برخلاف calc() تنها یک <intrinsic-size-keyword> را به عنوان اولین آرگومان می پذیرد.

دلیل دیگر آگاهی از زمینه است. برخی از الگوریتم‌های چیدمان رفتار خاصی برای کلمات کلیدی با اندازه ذاتی خاص دارند. calc-size() به صراحت برای نشان دادن یک اندازه ذاتی تعریف شده است، نه یک <length> . به لطف این، آن الگوریتم‌ها می‌توانند calc-size(<intrinsic-size-keyword>, …) به عنوان <intrinsic-size-keyword> در نظر بگیرند و رفتار خاص خود را برای آن کلمه کلیدی حفظ کنند.

از کدام رویکرد استفاده کنیم؟

در بیشتر موارد، interpolate-size: allow-keywords در :root اعلان کنید. این ساده ترین راه برای فعال کردن انیمیشن به و از کلمات کلیدی اندازه ذاتی است زیرا اساساً یک خطی است.

/* Opt-in the whole page to animating to/from intrinsic sizing keywords */
:root {
    interpolate-size: allow-keywords; /* 👈 */
}

این قطعه کد یک بهبود پیشرونده خوب است، زیرا مرورگرهایی که از آن پشتیبانی نمی‌کنند، دوباره از هیچ انتقالی استفاده نمی‌کنند.

هنگامی که به کنترل دقیق تری بر روی چیزها نیاز دارید - مانند انجام محاسبات - یا می خواهید از رفتاری استفاده کنید که فقط calc-size() می تواند انجام دهد، می توانید از calc-size() استفاده کنید.

#specific-element {
    width: 50px;

    &:hover {
        width: calc-size(fit-content, size + 1em); /* 👈 Only calc-size() can do this */
    }
}

با این حال، استفاده از calc-size() در کد شما مستلزم آن است که برای مرورگرهایی که calc-size() پشتیبانی نمی‌کنند، نسخه‌های جایگزین اضافه کنید. برای مثال، افزودن اعلان‌های اندازه اضافی، یا بازگشت به تشخیص ویژگی با استفاده از @supports .

width: fit-content;
width: calc-size(fit-content, size + 1em);
       /* 👆 Browsers with no calc-size() support will ignore this second declaration,
             and therefore fall back to the one on the line before it. */

دموهای بیشتر

در اینجا چند نسخه نمایشی دیگر وجود دارد که interpolate-size: allow-keywords به نفع خود.

اطلاعیه ها

نسخه ی نمایشی زیر فورکی از این @starting-style demo است. کد به گونه ای تنظیم شد که مواردی با ارتفاع های مختلف اضافه شوند.

برای رسیدن به این هدف، کل صفحه از درون یابی کلمات کلیدی با اندازه استفاده می کند و height هر عنصر .item روی auto تنظیم می شود. در غیر این صورت کد دقیقاً مشابه قبل از فورکینگ است.

:root {
    interpolate-size: allow-keywords; /* 👈 */
}

.item {
    height: auto; /* 👈 */

    @starting-style {
        height: 0px;
    }
}

عنصر <details> را متحرک کنید

یک مورد معمولی که می‌خواهید از این نوع درون‌یابی استفاده کنید، متحرک کردن یک ویجت افشا یا یک آکاردئون انحصاری هنگام باز شدن است. در HTML از عنصر <details> برای این کار استفاده می کنید.

با interpolate-size: allow-keywords می توانید خیلی دورتر برسید:

@supports (interpolate-size: allow-keywords) {
    :root {
        interpolate-size: allow-keywords;
    }
    
    details {
        transition: height 0.5s ease;
        height: 2.5rem;
        
        &[open] {
            height: auto;
            overflow: clip; /* Clip off contents while animating */
        }
    }
}

همانطور که می بینید، انیمیشن تنها زمانی اجرا می شود که ویجت افشا در حال باز شدن است. برای تامین این موضوع، کروم در حال کار بر روی شبه ::details-content است که در اواخر امسال در کروم ارسال خواهد شد (و در پست بعدی پوشش داده خواهد شد). با ترکیب interpolate-size: allow-keywords و ::details-content ، می توانید یک انیمیشن در هر دو جهت دریافت کنید: