ใช้พร็อพเพอร์ตี้ 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
พร็อพเพอร์ตี้ interpolate-size
ของ CSS ช่วยให้คุณควบคุมได้ว่าควรอนุญาตภาพเคลื่อนไหวและการเปลี่ยนรูปแบบของคีย์เวิร์ดการปรับขนาดตามค่าเริ่มต้นของ CSS หรือไม่
ค่าเริ่มต้นคือ numeric-only
ซึ่งจะไม่เปิดใช้การประมาณ เมื่อตั้งค่าพร็อพเพอร์ตี้เป็น allow-keywords
แสดงว่าคุณเลือกใช้การหาค่าเฉลี่ยจากความยาวเป็นคีย์เวิร์ดการปรับขนาดตามค่าเริ่มต้นของ CSS ในกรณีที่เบราว์เซอร์สามารถสร้างภาพเคลื่อนไหวของคีย์เวิร์ดเหล่านั้นได้
numeric-only
: ประมาณ<intrinsic-size-keyword>
ไม่ได้allow-keywords
: ระบบจะหาค่าประมาณของค่า 2 ค่าได้หากค่าใดค่าหนึ่งเป็น<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
ไปยัง 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()
อีกวิธีในการเปิดใช้การประมาณค่าจากและไปยังคีย์เวิร์ดการปรับขนาดตามข้อมูลที่มีอยู่คือการใช้ฟังก์ชัน calc-size()
ทำให้สามารถคำนวณทางคณิตศาสตร์กับขนาดที่แท้จริงด้วยวิธีที่ปลอดภัยและกำหนดได้ดี
ฟังก์ชันนี้รับอาร์กิวเมนต์ 2 รายการตามลําดับดังนี้
- เกณฑ์ขนาดการคำนวณ ซึ่งอาจเป็น
<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()
2 รายการได้เมื่อฐานขนาดการคํานวณของทั้ง 2 รายการเหมือนกัน การดำเนินการนี้ยังทำไม่ได้ใน 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>
เคลื่อนไหว
Use Case ทั่วไปที่คุณต้องการใช้การอินเตอร์โพเลชันประเภทนี้คือการสร้างภาพเคลื่อนไหววิดเจ็ตการเปิดเผยหรือกล่องแอคคอร์เดียนเฉพาะขณะเปิด ใน 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
ร่วมกัน คุณจะได้ภาพเคลื่อนไหวทั้ง 2 ทิศทาง ดังนี้