Kodokon kodokon.com

ตัวแปร CSS และฟังก์ชัน calc/clamp

เชี่ยวชาญ custom properties วิธีที่มันถูกแปลงค่าตอนรันไทม์ภายใน cascade และฟังก์ชัน calc() กับ clamp() สำหรับส่วนต่อประสานแบบลื่นไหล

10 นาที · 3 คำถาม

เปิดบทเรียนนี้ใน Kodokon

Custom properties ไม่ใช่ตัวแปรของ preprocessor ตัวแปร Sass จะถูกแทนที่ในตอนคอมไพล์ ส่วน property --brand จะถูกแปลงค่า ตอนรันไทม์ มีส่วนร่วมใน cascade สืบทอด (inherit) เหมือน property อื่น ๆ และสามารถเปลี่ยนได้โดย media query, คลาส หรือ JavaScript ผ่าน setProperty() นี่คือสิ่งที่ทำให้การทำ theme แบบไดนามิก, dark mode โดยไม่ต้องคอมไพล์ใหม่ และการสื่อสารระหว่าง CSS/JS โดยไม่ต้อง re-render เป็นไปได้

CSS
:root {
  --brand: #6c5ce7;
  --spacing: 8px;
}

.card {
  color: var(--brand);
  padding: calc(var(--spacing) * 2);
  border-color: var(--accent, currentColor);
}
การประกาศ การอ่าน และค่า fallback

อาร์กิวเมนต์ตัวที่สองของ var() คือค่า fallback ซึ่งจะถูกใช้เฉพาะเมื่อ property ไม่ได้ถูกกำหนด เท่านั้น กับดักคลาสสิก: ถ้า --accent มีค่าเป็น 12px แล้วคุณฉีดมันเข้าไปใน color ค่า fallback จะไม่ถูกใช้ การประกาศจะกลายเป็น invalid ในตอน computed-value time โดย property จะย้อนกลับไปใช้ค่าที่สืบทอดมาหรือค่าเริ่มต้น (initial) แทน ไม่ใช่การประกาศก่อนหน้าเหมือนที่ error ของ syntax ทั่วไปจะเป็น

กฎ @property แก้ข้อจำกัดสำคัญสองอย่าง: มันให้ ชนิดข้อมูล (type) แก่ตัวแปร (และจึงมีการตรวจสอบความถูกต้อง) และทำให้ตัวแปร เคลื่อนไหว (animate) ได้ เพราะตอนนี้เอนจินรู้วิธี interpolate ระหว่างค่าที่มี type สองค่าแทนที่จะมองตัวแปรเป็นสตริงทึบ ๆ

CSS
@property --progress {
  syntax: "<percentage>";
  inherits: false;
  initial-value: 0%;
}

.gauge {
  background: conic-gradient(
    var(--brand) var(--progress),
    #e5e7eb 0
  );
  transition: --progress 0.4s ease-out;
}

.gauge.is-full {
  --progress: 100%;
}
ตัวแปรที่มี type และ animate ได้ด้วย @property

ในด้านคณิตศาสตร์ calc() ให้คุณผสมหน่วยต่าง ๆ ได้ (calc(100% - 2rem)) ซึ่งเป็นไปไม่ได้กับ preprocessor เพราะการแปลงค่าขึ้นอยู่กับบริบทของการเรนเดอร์ ส่วน clamp(min, ideal, max) เป็นรูปแบบย่อของ max(min, min(ideal, max)) และเหนือกว่าการวาง breakpoint ซ้อน ๆ กันสำหรับ typography แบบลื่นไหล: ค่าอุดมคติ (ideal) ซึ่งมักแสดงในหน่วย vw หรือ cqi จะเลื่อนอย่างอิสระระหว่างขอบเขตทั้งสอง

CSS
:root {
  --fluid-title: clamp(
    1.5rem,
    1rem + 2.5vw,
    3rem
  );
}

h1 {
  font-size: var(--fluid-title);
  max-width: clamp(20ch, 60%, 65ch);
}
Typography แบบลื่นไหลโดยไม่ต้องใช้ media query

ทดสอบความรู้

ตรวจสอบว่าคุณจำประเด็นสำคัญของบทเรียนนี้ได้ครบถ้วน

  1. จะเกิดอะไรขึ้นถ้า color: var(--gap) ถูกประเมินขณะที่ --gap มีค่าเป็น 12px?
    • การประกาศจะถูกเพิกเฉยและกฎ color ก่อนหน้าจะถูกใช้
    • การประกาศจะกลายเป็น invalid ในตอน computed-value time และ color จะแปลงค่าเป็น unset
    • เบราว์เซอร์จะแปลง 12px ให้เป็นสีที่ใกล้เคียงกับสีดำ
    • จะมี error ถูกโยนขึ้นใน console และสไตล์ชีตจะถูกปฏิเสธ
  2. clamp(1rem, 2.5vw, 2rem) เทียบเท่ากับอะไรอย่างเคร่งครัด?
    • max(1rem, min(2.5vw, 2rem))
    • min(1rem, max(2.5vw, 2rem))
    • calc(1rem + 2.5vw + 2rem)
  3. ประโยชน์หลักของ @property เหนือ custom property ทั่วไปคืออะไร?
    • มันทำให้ตัวแปรเข้าถึงได้จาก JavaScript
    • มันอนุญาตให้ใช้ตัวแปรภายใน calc()
    • มันให้ type แก่ตัวแปร ซึ่งที่สำคัญคือทำให้ตัวแปร interpolate ได้ใน animation
    • มันบังคับให้ตัวแปรสืบทอดไปทั่วทั้งเอกสาร