ในอดีต การสร้างภาพเคลื่อนไหวขององค์ประกอบให้มีขนาดแบบไดนามิก เช่น block-size: auto หรือ inline-size: max-content ต้องใช้ JavaScript หรือแฮ็ก "max-height" ที่ไม่เสถียร พร็อพเพอร์ตี้ interpolate-size และฟังก์ชัน calc-size() ช่วยให้เบราว์เซอร์สามารถประมาณค่าในช่วงระหว่างความยาวคงที่และคีย์เวิร์ดการปรับขนาดภายในได้โดยตรง
ขั้นตอนการติดตั้งใช้งาน
- เลือกใช้การประมาณค่าในช่วงคีย์เวิร์ด: ใช้
interpolate-size: allow-keywordsกับองค์ประกอบหลัก (โดยปกติคือ:root) เพื่อเปิดใช้การเปลี่ยนผ่านสำหรับพร็อพเพอร์ตี้ที่ใช้คีย์เวิร์ดภายใน - กำหนดการเปลี่ยน: ตั้งค่า
transitionสำหรับพร็อพเพอร์ตี้การปรับขนาด (เช่นblock-size,inline-size) ในองค์ประกอบเป้าหมาย - ใช้คีย์เวิร์ดภายใน: เปลี่ยนพร็อพเพอร์ตี้การปรับขนาดเป็นคีย์เวิร์ดภายในที่รองรับ (
auto,min-content,max-content,fit-contentหรือ (สำหรับ flex-basis)content) ระหว่างการโต้ตอบ (เช่น:hoverหรือคลาสสถานะ) - ทำการคำนวณ (ไม่บังคับ): ใช้
calc-size()หากต้องการคำนวณทางคณิตศาสตร์กับขนาดที่แท้จริง (เช่นauto + 2rem)calc-size()ยังรองรับคีย์เวิร์ดanyสำหรับการคำนวณที่ไม่ขึ้นอยู่กับพื้นฐานด้วย
ตัวอย่าง: รูปแบบการขยายทั่วไป
คุณสามารถใช้รูปแบบนี้กับคอนเทนเนอร์ใดก็ได้ (เช่น ส่วน "แสดงเพิ่มเติม" หรือเมนูการนำทาง) เพื่อเปลี่ยนระหว่างความสูงที่จำกัดกับขนาดปกติขององค์ประกอบ
/* Opt-in globally for all children */
:root {
/* MANDATORY: Transitions to intrinsic keywords are disabled by default for compatibility */
interpolate-size: allow-keywords;
}
.expandable-container {
/* 1. Define a fixed initial size (or 0) and hide overflow */
block-size: 100px;
overflow: hidden;
/* 2. Transition the sizing property */
transition: block-size 0.4s ease-out;
}
.expandable-container.is-expanded {
/* 3. Smoothly animate to the intrinsic natural height */
block-size: auto;
}
ตัวอย่าง: ขนาดในบรรทัดที่แท้จริงที่คำนวณแล้ว
.badge {
inline-size: 40px;
overflow: hidden;
white-space: nowrap;
transition: inline-size 0.3s ease;
}
.badge:hover {
/* calc-size(basis, calculation) */
/* 'size' refers to the evaluated basis (max-content in this case) */
inline-size: calc-size(max-content, size + 20px);
}
ตัวอย่าง: การเปลี่ยนจากขนาดที่แท้จริงเป็นขนาดคงที่
นอกจากนี้ คุณยังทำให้เคลื่อนไหวในทิศทางตรงกันข้ามได้ด้วย โดยเริ่มจากขนาดปกติและยุบเป็นความยาวที่เฉพาะเจาะจง ซึ่งมีประโยชน์สำหรับคอมโพเนนต์ที่ "ปิดได้"
.collapsible-alert {
/* 1. Start with the natural content height */
block-size: auto;
overflow: hidden;
transition: block-size 0.5s ease-in-out, opacity 0.5s ease;
}
.collapsible-alert.is-dismissed {
/* 2. Smoothly collapse to zero */
block-size: 0;
opacity: 0;
pointer-events: none;
}
/* MANDATORY Copy-Paste Safety: Disable sizing animations for sensitive users */
@media (prefers-reduced-motion: reduce) {
.expandable-container,
.badge,
.collapsible-alert {
transition: none !important;
}
}
// MANDATORY Accessibility Synchronization: Ensure elements collapsed to zero dimensions are removed from the assistive technology tree, and sync aria-expanded states on triggers.
const alertElement = document.querySelector('.collapsible-alert');
alertElement.addEventListener('transitionend', (e) => {
if (e.propertyName === 'block-size' && alertElement.classList.contains('is-dismissed')) {
alertElement.hidden = true;
}
});
// Example trigger syncer
const triggerBtn = document.querySelector('.accordion-trigger');
triggerBtn?.addEventListener('click', () => {
const isExpanded = triggerBtn.getAttribute('aria-expanded') === 'true';
triggerBtn.setAttribute('aria-expanded', !isExpanded);
});
ข้อจำกัดที่สำคัญ
- ข้อจำกัดคีย์เวิร์ดต่อคีย์เวิร์ด: คุณไม่สามารถสร้างภาพเคลื่อนไหวระหว่างคีย์เวิร์ด 2 คำที่แตกต่างกันโดยตรง (เช่น จาก
min-contentเป็นmax-content) ปลายด้านหนึ่งของการเปลี่ยนต้องมีความยาวหรือเปอร์เซ็นต์คงที่ (เช่น0เป็นauto) - ไวยากรณ์ calc-size: ภายใน
calc-size()คุณไม่สามารถผสมคีย์เวิร์ดภายในที่แตกต่างกันในนิพจน์เดียวกันได้ อาร์กิวเมนต์แรก (ฐาน) จะกำหนดว่าsizeแสดงถึงอะไร - ข้อกำหนดในการเลือกใช้: การเปลี่ยนไปใช้คีย์เวิร์ดภายในจะปิดอยู่โดยค่าเริ่มต้น (
numeric-only) เพื่อรักษาความเข้ากันได้แบบย้อนหลัง คุณต้องใช้interpolate-size: allow-keywordsกับองค์ประกอบหรือระดับบนสุดcalc-size()ทำหน้าที่เป็นการลบล้างต่อพร็อพเพอร์ตี้ โดยจะเปิดใช้การประมาณค่าในช่วงโดยอัตโนมัติเมื่อใดก็ตามที่มีการใช้งาน
กลยุทธ์สำรอง
interpolate-size และ calc-size() เป็นการเพิ่มประสิทธิภาพแบบต่อเนื่อง เบราว์เซอร์ที่ไม่รองรับจะข้ามไปยังขนาดเป้าหมายทันที
- การลดลงอย่างค่อยเป็นค่อยไป: สำหรับการเปลี่ยน
block-size: autoแบบง่ายๆ เบราว์เซอร์มาตรฐานจะสลับขนาดทันที ซึ่งใช้งานได้แต่ไม่ราบรื่นนัก - คีย์เวิร์ดสำรองที่กำหนดเอง: เมื่อใช้
calc-size()ให้ระบุคีย์เวิร์ดสำรองมาตรฐานสำหรับเบราว์เซอร์รุ่นเก่าเสมอ เนื่องจากเบราว์เซอร์เหล่านั้นจะทิ้งการประกาศcalc-size()ทั้งหมด
.card {
block-size: auto; /* Fallback for older browsers */
block-size: calc-size(auto, size); /* Modern browsers use this */
transition: block-size 0.3s ease;
}