คำนวณด้วยขนาดภายใน

ฟีเจอร์บนเว็บ: calc-size() interpolate-size

calc-size() เป็นฟังก์ชัน CSS สำหรับดำเนินการทางคณิตศาสตร์กับคีย์เวิร์ดการกำหนดขนาดภายใน เช่น auto, min-content และ fit-content บังคับ: ใช้ calc-size() เฉพาะเมื่อคุณต้องการแก้ไขขนาดที่แท้จริงด้วยการคำนวณหรือข้อจำกัด สำหรับภาพเคลื่อนไหวที่อิงตามคีย์เวิร์ดแบบง่าย (เช่น 0 ถึง auto) คุณต้องใช้ interpolate-size: allow-keywords

ขั้นตอนการติดตั้งใช้งาน

  1. ระบุพื้นฐานที่แท้จริง: พิจารณาว่าคีย์เวิร์ดที่แท้จริงใด (auto, min-content ฯลฯ) ควรเป็นพื้นฐานของการคำนวณ
  2. กำหนดข้อจำกัด: ใช้ฟังก์ชันทางคณิตศาสตร์ของ CSS เช่น clamp(), min() หรือ max() ภายในอาร์กิวเมนต์ที่ 2 เพื่อบังคับใช้ข้อจำกัดด้านการออกแบบกับขนาดที่แท้จริง
  3. บังคับ: ระบุทางเลือกสำรอง: ประกาศคีย์เวิร์ดหรือความยาวของการปรับขนาดมาตรฐานก่อนพร็อพเพอร์ตี้ที่ใช้ calc-size() เสมอ เพื่อให้เลย์เอาต์ยังคงทำงานได้ในเบราว์เซอร์ที่ไม่รองรับ
  4. ใช้พร็อพเพอร์ตี้เชิงตรรกะ: ค่าเริ่มต้นคือการใช้พร็อพเพอร์ตี้เชิงตรรกะ เช่น inline-size หรือ block-size เพื่อให้การคำนวณเป็นไปตามโหมดการเขียนของเอกสาร
  5. ไม่บังคับ: การเพิ่มประสิทธิภาพแบบต่อเนื่อง: รวมตรรกะเลย์เอาต์หรือภาพเคลื่อนไหวที่ซับซ้อนไว้ในบล็อก @supports (inline-size: calc-size(auto, size + 0px)) เพื่อแสดงฟีเจอร์ขั้นสูงเฉพาะในเบราว์เซอร์ที่รองรับเท่านั้น

ไวยากรณ์พื้นฐาน

/* calc-size(<calc-size-basis>, <calc-sum>) — mathematical operations on intrinsic sizing keywords */
.element {
  /* MANDATORY: Always provide a fallback for browsers that do not support calc-size() */
  inline-size: min-content;
  
  /* DO: Use calc-size to modify an intrinsic basis with a calculation or function */
  inline-size: calc-size(min-content, size + 2rem);
}

อาร์กิวเมนต์พื้นฐานที่ถูกต้อง (<calc-size-basis>)

อาร์กิวเมนต์แรกจะกำหนดขนาด "ฐาน" สำหรับการคำนวณ

คีย์เวิร์ดมาตรฐาน:

  • auto: ขนาดเริ่มต้นขององค์ประกอบ
  • min-content: ขนาดเล็กที่สุดที่องค์ประกอบสามารถใช้ได้โดยไม่ล้น
  • max-content: ขนาดที่องค์ประกอบใช้เพื่อให้พอดีกับเนื้อหาทั้งหมดในบรรทัดเดียว
  • fit-content: เทียบเท่ากับ clamp(min-content, auto, max-content)
  • content: ใช้ได้เฉพาะเมื่อใช้ calc-size() ภายในพร็อพเพอร์ตี้ flex-basis

อาร์กิวเมนต์พิเศษ:

  • any: พื้นฐานทั่วไปที่ใช้เมื่อไม่ทราบประเภทที่แท้จริงที่เฉพาะเจาะจงหรือเมื่อซ้อนการคำนวณ
  • calc-size()ที่ซ้อนกัน: ช่วยให้สามารถคำนวณแบบหลายขั้นตอนหรือแบบมีเงื่อนไขได้
  • <calc-sum>: ความยาว เปอร์เซ็นต์ หรือนิพจน์ทางคณิตศาสตร์ที่เฉพาะเจาะจง (เช่น 100px หรือ 20%) เมื่อใช้ค่าคงที่เป็นฐาน คีย์เวิร์ด size จะยังคงใช้ได้ (แต่จะใช้ได้เฉพาะในอาร์กิวเมนต์ที่ 2) และแสดงค่าที่แปลงแล้วของฐานนั้น

บังคับ: คีย์เวิร์ด size ไม่ถูกต้องภายในอาร์กิวเมนต์แรก (<calc-size-basis>) เอง ซึ่งเป็นตัวแปรในเครื่องที่มีไว้เพื่ออ้างอิงกลับไปยังฐานจากภายในอาร์กิวเมนต์ที่ 2 (<calc-sum>) เท่านั้น

อาร์กิวเมนต์การคำนวณที่ถูกต้อง (<calc-sum>)

อาร์กิวเมนต์ที่ 2 คือนิพจน์ทางคณิตศาสตร์

  • โดยปกติแล้วจะใช้คีย์เวิร์ด size เพื่ออ้างอิงถึงค่าของฐาน
  • แม้ว่าคีย์เวิร์ด size จะไม่บังคับในทางเทคนิค แต่การละเว้นคีย์เวิร์ดนี้หมายความว่าการคำนวณจะแสดงผลเป็นค่าคงที่ โดยไม่สนใจฐานเลย
  • ซึ่งอาจรวมถึงโอเปอเรเตอร์ทางคณิตศาสตร์มาตรฐาน (+, -, *, /)
  • ซึ่งอาจรวมถึงฟังก์ชันทางคณิตศาสตร์ของ CSS เช่น clamp(), min(), max() และ round()
  • บังคับ: calc-size() อนุญาตให้ใช้ค่าขนาดที่แท้จริงค่าเดียว (ฐาน) ในการคำนวณแต่ละครั้ง คุณไม่สามารถผสมคีย์เวิร์ดการกำหนดขนาดภายในในการเรียก calc-size() เดียวกันได้

กรณีการใช้งาน

การสร้างภาพเคลื่อนไหวไปยังและจากขนาดภายใน

โดยค่าเริ่มต้น เบราว์เซอร์จะไม่สามารถประมาณค่าในช่วงระหว่างความยาว (เช่น 0px) กับคีย์เวิร์ดภายใน (เช่น auto) การรวมคีย์เวิร์ดไว้ใน calc-size() จะทำให้คีย์เวิร์ดเป็นค่าที่ประมาณค่าในช่วงได้

การเลือกเครื่องมือที่เหมาะสมสำหรับภาพเคลื่อนไหว

  • บังคับ: ใช้ interpolate-size: allow-keywords: สำหรับภาพเคลื่อนไหวแบบง่ายไปยังหรือจากขนาดที่แท้จริง (เช่น height: 0 ไปยัง height: auto) โดยไม่มีการแก้ไขทางคณิตศาสตร์ วิธีนี้เป็นวิธีที่จำเป็นสำหรับการแทรกคีย์เวิร์ดแบบง่าย และควรใช้ทั่วโลกผ่าน :root

    :root {
      /* Best practice: Enable keyword interpolation globally */
      interpolate-size: allow-keywords;
    }
    
    .item {
      height: 0;
      transition: height 0.3s ease;
    }
    
    .item.open {
      /* Simple interpolation from 0 to auto now works without calc-size() */
      height: auto;
    }
    
  • ใช้ calc-size(): เฉพาะเมื่อคุณต้องการทำการคำนวณทางคณิตศาสตร์กับขนาดที่แท้จริงในระหว่างการเปลี่ยน (เช่น การเพิ่มระยะห่างจากขอบหรือการจำกัดขนาด)

.accordion-content {
  display: block;
  overflow: hidden;
  /* MANDATORY: Fallback value for closed state */
  block-size: 0;
  transition: block-size 0.3s ease-out;
}

.accordion-content.open {
  /* MANDATORY: Fallback value for open state */
  block-size: auto;

  /* 
    DO: Use calc-size(auto, ...) to enable animation from 0 to the element's 
    intrinsic size while doing a calculation (in this case, adding a space of 2rem).
  */
  block-size: calc-size(auto, size + 2rem);
}

บังคับ: การประมาณค่าในช่วงระหว่างคีย์เวิร์ดการปรับขนาดภายใน 2 รายการไม่สามารถทำได้โดยตรง ปลายด้านหนึ่งของทรานซิชันต้องเป็นความยาวหรือเปอร์เซ็นต์

การเคารพค่ากำหนดการเคลื่อนไหวของผู้ใช้

ภาพเคลื่อนไหวที่เปลี่ยนขนาดของพื้นที่เลย์เอาต์ขนาดใหญ่อาจสร้างความรบกวนอย่างมากสำหรับผู้ใช้ที่มีความผิดปกติของระบบการทรงตัว บังคับ: เคารพค่ากำหนดการเคลื่อนไหวของผู้ใช้เสมอโดยใช้คิวรี่สื่อ prefers-reduced-motion เพื่อลดความซับซ้อนหรือลดภาพเคลื่อนไหวที่ไม่จำเป็น กลยุทธ์ที่พบบ่อย ได้แก่ การปิดใช้การเคลื่อนไหวทั้งหมด การลดระยะเวลา หรือการแทนที่การเปลี่ยนเลย์เอาต์ด้วยการเปลี่ยนความทึบแสงเล็กน้อย

.accordion-content {
  opacity: 0;
  transition: block-size 0.3s ease, opacity 0.3s ease;
}

.accordion-content.open {
  opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
  .accordion-content {
    /* 
       EXAMPLE: Replacing disruptive layout animations with a subtle fade-in.
       Setting the block-size instantly and transitioning opacity 
       provides a clear state change without large-scale motion.
    */
    transition: opacity 1.5s ease;
  }

  .accordion-content.open {
    /* Jump the size instantly */
    block-size: auto;
  }
}

การใช้ข้อจำกัดกับขนาดภายใน

คุณสามารถใช้ calc-size() กับฟังก์ชันทางคณิตศาสตร์ CSS ใดก็ได้ เช่น min(), max(), clamp() หรือ round() เพื่อให้ขนาดที่แท้จริงขององค์ประกอบยังคงอยู่ภายในขอบเขตการออกแบบ

.dynamic-container {
  /* MANDATORY: Always provide a fallback for browsers that do not support calc-size() */
  inline-size: fit-content;

  /* 
    DO: Establish a dynamic size based on content, while:
    1. Enforcing boundaries using CSS math functions (min, clamp, etc.)
    2. Modifying the intrinsic size with fixed or relative offsets
  */
  inline-size: calc-size(fit-content, min(size + var(--extra-space), var(--max-allowed)));
}

ข้อควรพิจารณาที่สำคัญ

  • ข้อผิดพลาดเกี่ยวกับเปอร์เซ็นต์: เปอร์เซ็นต์ภายใน <calc-sum> จะได้รับการแก้ไขตามขนาดของคอนเทนเนอร์ ไม่ใช่คีย์เวิร์ด size เช่น calc-size(auto, size + 10%) จะเพิ่ม 10% ของความกว้างขององค์ประกอบหลักลงในความกว้าง auto ขององค์ประกอบ ซึ่งอาจทำให้เกิดผลลัพธ์ที่ไม่คาดคิดหรือการล้น
  • ข้อกำหนดด้านการคำนวณ: บังคับ: ใช้ interpolate-size: allow-keywords แทน calc-size() สำหรับภาพเคลื่อนไหวแบบง่าย (เช่น 0 ถึง auto) ควรใช้ calc-size() เฉพาะเมื่อเลย์เอาต์ต้องมีการปรับเปลี่ยนทางคณิตศาสตร์แบบไดนามิกกับฐานที่แท้จริง
  • หมายเหตุเกี่ยวกับประสิทธิภาพ: การสร้างภาพเคลื่อนไหวให้กับพร็อพเพอร์ตี้โมเดลกล่อง เช่น inline-size หรือ block-size จะทริกเกอร์การคำนวณเลย์เอาต์ใหม่ ซึ่งอาจใช้ทรัพยากรมาก ใช้ภาพเคลื่อนไหว calc-size() เป็นหลักสำหรับองค์ประกอบที่สำคัญต่อเลย์เอาต์ซึ่งทางเลือกที่ไม่ใช่เลย์เอาต์ไม่เพียงพอ

กลยุทธ์สำรอง

calc-size() และ interpolate-size เป็นการเพิ่มประสิทธิภาพแบบต่อเนื่อง ในเบราว์เซอร์ที่ไม่รองรับ พร็อพเพอร์ตี้จะถูกละเว้นและเลย์เอาต์จะยังคงทำงานได้ แม้ว่าภาพเคลื่อนไหวไปยังคีย์เวิร์ดที่แท้จริงจะข้ามไปแทนที่จะเปลี่ยนผ่าน ระบุคีย์เวิร์ดหรือความยาวมาตรฐานเป็นทางเลือกสำรองเสมอ

.element {
  /* Fallback for browsers that don't support calc-size() */
  inline-size: fit-content; 
  /* Modern browsers will override the fallback */
  inline-size: calc-size(fit-content, size + 2rem);
}

ภาพเคลื่อนไหวและทางเลือกสำรองสำหรับการเปลี่ยนภาพ

ในเบราว์เซอร์ที่ไม่รองรับ calc-size() หรือ interpolate-size การเปลี่ยนที่เกี่ยวข้องกับคีย์เวิร์ดการปรับขนาดภายในจะไม่สามารถประมาณค่าในช่วงได้

  • การลดลงอย่างค่อยเป็นค่อยไป: ตัวเลือกสำรองเริ่มต้นคือ "การข้ามทันที" ระหว่างสถานะ (เช่น จาก 0 เป็น auto) ซึ่งมักเป็นที่ยอมรับได้เนื่องจากเลย์เอาต์ยังคงทำงานได้
  • ประสบการณ์ที่ดียิ่งขึ้น: ใช้ @supports เพื่อใช้ตรรกะเลย์เอาต์ที่ซับซ้อนหรือการจัดรูปแบบเพิ่มเติมที่เหมาะสมก็ต่อเมื่อสามารถใช้ภาพเคลื่อนไหวภายในที่ราบรื่นได้เท่านั้น
  • หลีกเลี่ยงการวัดผลที่ใช้ JS: แม้ว่าคุณจะใช้ JavaScript เพื่อวัดองค์ประกอบและทำให้มิติข้อมูลเคลื่อนไหวด้วยตนเองได้ แต่วิธีนี้มักไม่จำเป็นและอาจทำให้เกิด Layout Thrashing การใช้ "การข้ามทันที" แบบเนทีฟเป็นทางเลือกสำรองที่แนะนำสำหรับเว็บแอปพลิเคชันสมัยใหม่

สำหรับภาพเคลื่อนไหว ประสบการณ์สำรองจะเป็นการข้ามไปยังขนาดสุดท้ายทันที วิธีตรวจหาการรองรับใน CSS หรือ JavaScript

/* CSS Feature Detection */
@supports (inline-size: calc-size(auto, size + 0px)) {
  .element {
    /* Apply advanced logic only when supported */
  }
}
/* JavaScript Feature Detection */
if (CSS.supports('inline-size', 'calc-size(auto, size + 0px)')) {
  // Apply advanced sizing or animations
}