استخدام ميزة "الحركة إلى الارتفاع: تلقائي" (وكلمات المرور الأخرى ذات الصلة بالحجم الأساسي) في CSS

استخدِم السمة interpolate-size أو الدالة calc-size() لتفعيل الانتقالات والصور المتحركة السلسة من القيم إلى الكلمات الرئيسية ذات الحجم المطلق والعكس.

تاريخ النشر: 17 أيلول (سبتمبر) 2024

مقدمة

من ميزات 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

توافق المتصفّح

  • Chrome: ‏ 129
  • Edge: غير متوافق
  • Firefox: غير متوافق
  • Safari: غير متوافق

المصدر

تمنحك خاصية interpolate-size في CSS إمكانية التحكّم في ما إذا كان يجب السماح بالرسوم المتحرّكة والانتقالات للكلمات الرئيسية لتحديد الحجم في 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> صفحتك مع هذا النوع من عمليات النقل، يمكنك حصر الموافقة على عنصر <main> فقط وعناصره الفرعية على النحو التالي:

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

لماذا لا يُسمح بالتأثيرات المتحركة للانتقال من الكلمات الرئيسية التي تتضمّن معلومات الحجم والعكس تلقائيًا؟

من الملاحظات الشائعة حول آلية تفعيل هذه الميزة أنّ المتصفحات يجب أن تسمح فقط بالانتقالات والرسوم المتحرّكة من الكلمات الرئيسية ذات الحجم التلقائي إلى الطول تلقائيًا.

تم البحث في خيار تفعيل هذا السلوك أثناء تطوير الميزة. اكتشفت مجموعة العمل أنّ تفعيل هذه الميزة تلقائيًا غير متوافق مع الإصدارات القديمة لأنّ العديد من جداول الأنماط تفترض أنّه لا يمكن إضافة تأثيرات متحركة إلى الكلمات الرئيسية ذات الحجم التلقائي (مثل auto أو min-content). يمكنك الاطّلاع على التفاصيل في هذا التعليق على مشكلة مجموعة عمل CSS ذات الصلة.

وبالتالي، يكون الموقع متاحًا للجميع. بفضل سمة اكتساب السمات، فإنّ تفعيل مستند كامل هو مجرد بيان interpolate-size: allow-sizes عن :root كما هو موضّح سابقًا.

إضافة مؤثرات متحركة إلى الكلمات الرئيسية ذات الحجم التلقائي ومنها باستخدام calc-size()

توافق المتصفّح

  • Chrome: ‏ 129
  • ‫Edge: 129
  • Firefox: غير متوافق
  • Safari: غير متوافق

المصدر

هناك طريقة أخرى لتفعيل الاستقراء من الكلمات الرئيسية ذات الحجم المطلق وإليها، وهي استخدام دالة calc-size(). ويسمح هذا الإجراء بإجراء العمليات الحسابية على الأحجام الأساسية بطريقة آمنة ومحدّدة جيدًا.

تقبل الدالة وسيطتين على النحو التالي:

  • قاعدة حجم حسابي، والتي يمكن أن تكون <intrinsic-size-keyword> ولكن يمكن أن تكون أيضًا 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 + 1rem); // = The min-content width plus 1rem
width: calc-size(max-content, size * .5);   // = Half the max-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() عندما تكون قاعدتا الحجم المحسوبتان متطابقتَين. لا يمكن أيضًا تحقيق ذلك باستخدام 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() صحة القيمة لأنّها لا تقبل سوى دالة <intrinsic-size-keyword> واحدة كوسيطة أولى، على عكس دالة calc().

وهناك سبب آخر وهو الوعي بالسياق. تتّبع بعض خوارزميات التنسيق سلوكًا خاصًا لكلمات رئيسية معيّنة ذات حجم أساسي. تمّ تعريف 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 العرض التوضيحي. تم تعديل الرمز للسماح بإضافة عناصر ذات ارتفاعات مختلفة.

لتحقيق ذلك، يتم تفعيل الصفحة بأكملها لدمج حجم الكلمة الرئيسية ويتم ضبط 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 */
        }
    }
}

كما هو موضّح، لا يتم تشغيل الصورة المتحركة إلا عند فتح التطبيق المصغّر لبيان الإفصاح. لحلّ هذه المشكلة، يعمل فريق Chrome على تطوير العنصر النائب ::details-content الذي سيتم طرحه في Chrome في وقت لاحق من هذا العام (وسيتم تناوله في مشاركة مستقبلية). من خلال الجمع بين interpolate-size: allow-keywords و::details-content، يمكنك الحصول على صورة متحركة في كلا الاتجاهين: