ฟังก์ชันคณิตศาสตร์ CSS: calc, min, max, clamp

เผยแพร่แล้ว: 2022-03-20
บทนำ » ฟังก์ชันตรรกะ CSS calc() , clamp() , min() และ max() ได้รับการสนับสนุนโดยเว็บเบราว์เซอร์สมัยใหม่ทั้งหมด แต่ถึงแม้จะพร้อมใช้งาน – การค้นหา GitHub แบบง่ายๆ บอกเราว่าการใช้งานฟังก์ชันเหล่านี้ได้ช้า แล้วเราจะใช้มันเพื่อสร้างประสบการณ์เลย์เอาต์ที่ลื่นไหลและตอบสนองได้อย่างไร ลองหา

สารบัญ
  • คำนวณ ()
  • นาที()
  • สูงสุด ()
  • ที่หนีบ()
  • การสร้างแถบด้านข้างที่ตอบสนองด้วย Grid
  • การใช้ช่องว่างที่ตอบสนองสำหรับเลย์เอาต์ Flexbox
  • ฉันใช้ได้ไหม: การสนับสนุนอยู่ที่นั่น
  • บทสรุป

ฉันรู้ว่าคุณกำลังคิดอะไรอยู่ “คณิตศาสตร์! ยัค. ออกไปจากสายตาฉันซะ” . แต่ให้ถามตัวเองว่า คุณมีพลังใจที่จะต่อต้านความพึงพอใจของตู้คอนเทนเนอร์ที่เรียงซ้อนกันอย่างสมบูรณ์แบบหรือไม่?

คุณรู้ไหม หลังจากที่ฉันเขียนบทความของฉันเกี่ยวกับเทคนิค CSS ต่างๆ (มันถูกหยิบขึ้นมาโดยสื่อสิ่งพิมพ์สองสามฉบับ) ฉันเห็นการเข้าชมไซต์มาที่ไซต์เพื่อหาคำหลักเช่น "วิธีจัดองค์ประกอบ div ให้อยู่ตรงกลาง" ซึ่งตลกดีเพราะฉันไม่เคยพูดถึงมันเลย บทความโดยเฉพาะ แต่นั่นก็แสดงให้เห็นว่านักพัฒนาจำเป็นต้องเข้าถึงข้อมูลโค้ดด่วนที่สามารถนำกลับมาใช้ใหม่ได้อย่างง่ายดาย

ดังนั้น นี่จึงเป็นพื้นฐานสำหรับบทช่วยสอนนี้

 อัปเดต: ฉันได้เขียนบทช่วยสอนโดยละเอียดเกี่ยวกับการจัดองค์ประกอบให้อยู่ตรงกลางใน CSS แล้ว

ฉันจะเน้นที่หัวข้อของฟังก์ชันคณิตศาสตร์ CSS ในบริบทของการบรรลุผลลัพธ์ของเลย์เอาต์ต่างๆ เช่น วิธีสร้างคอนเทนเนอร์แบบตอบสนองด้วย CSS สองสามบรรทัด วิธีเพิ่มการเติมแบบปรับได้ และวิธีทำให้แถบด้านข้างนั้นทำงานเหมือนแถบด้านข้างจริง ๆ

มาดูกันเลย


คำนวณ ()

ฟังก์ชัน calc() รองรับการดำเนินการเลขคณิตสี่อย่าง: การบวก (+) การลบ (-) การคูณ (*) และการหาร (/) ฟังก์ชันนี้ใช้เป็นหลักในการคำนวณความกว้างและความสูงของไดนามิกของคอนเทนเนอร์เพื่อสร้างประสบการณ์เลย์เอาต์ที่ปรับเปลี่ยนได้

ตัวอย่างโค้ด

 .calc { background: #c8e6f5; padding: 10px 20px; width: calc(100% - 200px); } .no-calc { background: #c8e6f5; padding: 10px 20px; margin-top: 10px; } <div class="calc">100% – 200px</div> <div class="no-calc">Default container width</div>

และนี่จะเป็นผลลัพธ์:

100% – 200px
ความกว้างคอนเทนเนอร์เริ่มต้น

แต่ที่ calc() โดดเด่นที่สุดคือเมื่อมันถูกใช้เพื่อจัดเรียงองค์ประกอบโดยคำนึงถึงค่าเฉพาะ โดยทั่วไปแล้ว การออกแบบที่ตอบสนองได้นั้นทำได้โดยมองหาจุดสั่งหยุดที่เฉพาะเจาะจงแล้วเขียนตรรกะแยกกัน ด้วย calc() – เราสามารถสร้างเลย์เอาต์ที่ตอบสนองได้โดยใช้ข้อกำหนดเดียวเท่านั้น ซึ่งทำให้สามารถบำรุงรักษาได้มากขึ้น

ลองดูตัวอย่างที่เป็นรูปธรรมโดยใช้ display: flex; . เป้าหมายของเราคือการสร้างองค์ประกอบข้างเคียง 3 ชิ้นที่ผูกติดกับความกว้าง (100%) ของคอนเทนเนอร์ นอกจากนี้เรายังต้องการเพิ่มช่องว่าง 30px ระหว่างแต่ละองค์ประกอบ และแน่นอน เราต้องการให้ตอบสนอง!

ตัวอย่างโค้ด

 <style> .calc-container-flex { display: flex; justify-content: center; } .calc-container-style .item { background: #fff2ea; padding: 20px 0; width: calc((100% - 90px)/3); text-align: center; } .calc-container-style .item + .item { margin-left: 30px; } </style> <div class="calc-container-flex calc-container-style"> <div class="item">1</div> <div class="item">2</div> <div class="item">3</div> </div>

และที่นี่คุณสามารถปรับขนาดผลลัพธ์เพื่อดูว่ามันทำงานอย่างไร:

1
2
3

เนื่องจากเราต้องการให้มีช่องว่าง 30px ระหว่างแต่ละองค์ประกอบ เราลบ 90px จากความกว้างของคอนเทนเนอร์เริ่มต้น (100%) และหารด้วย 3 เพื่อระบุจำนวนองค์ประกอบที่เรามี

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


นาที()

ฟังก์ชัน min() ใช้เพื่อตั้งค่าที่เล็กที่สุดที่ยอมรับได้ ต้องใช้ 2 ข้อกำหนดที่แตกต่างกันโดยคั่นด้วยเครื่องหมายจุลภาคและสนับสนุนนิพจน์ทางคณิตศาสตร์

สมมติว่าคุณระบุ font-size: min(25px,1vw); – ในตัวอย่างนี้ ขนาดแบบอักษรจะไม่ใหญ่กว่า 25px และจะย่อเล็กลงเป็น 1vw ขึ้นอยู่กับขนาดวิวพอร์ต

นอกจากนี้เรายังสามารถใช้ min() เพื่อจัดการความกว้างขององค์ประกอบคอนเทนเนอร์

ตัวอย่างโค้ด

 .min-sample-box-container { width: 100%; max-width: 1000px; } .min-sample-box { background: #fff2ea; padding: 15px 30px; width: min(70%, 800px); } <div class="min-sample-box-container"> <div class="min-sample-box">min() example - 800px limit</div> </div>

ลองปรับขนาดนี้:

min() ตัวอย่าง – ขีด จำกัด 800px

ในบริบทนี้ องค์ประกอบ div ภายในคอนเทนเนอร์ของเราต้องมีความกว้างไม่เกิน 800px แม้ว่าคอนเทนเนอร์จะมีความกว้างสูงสุด 1000px


สูงสุด ()

ฟังก์ชัน max() ให้เราทำสิ่งที่ตรงกันข้าม จากสองค่านี้ เราระบุค่าภายใน max() – ค่าที่มากที่สุดจะถูกจัดลำดับความสำคัญ

ตัวอย่างโค้ด

 .max-sample-box-container { width: 100%; max-width: 1000px; } .max-sample-box { background: #fff2ea; padding: 15px 30px; width: max(70%, 200px); } <div class="max-sample-box-container"> <div class="max-sample-box">max() example - 200px limit</div> </div>

ลองปรับขนาดนี้เป็นคอนเทนเนอร์ขนาดเล็กลงเพื่อดูว่าเกิดอะไรขึ้น:

max() ตัวอย่าง – ขีด จำกัด 200px

อย่างที่คุณเห็น – คอนเทนเนอร์ยึดตาม width: 100%; แต่ไม่ต่ำกว่าเครื่องหมาย 200px ที่ระบุ เนื่องจากเป็นค่าที่ใหญ่ที่สุดสำหรับคอนเทนเนอร์

คุณลักษณะ max() มีประโยชน์อย่างยิ่งเมื่อใช้ระยะขอบที่ตอบสนอง โดยทั่วไป สิ่งที่เกิดขึ้นคือเมื่อคุณใช้องค์ประกอบขนาดเล็กจำนวนมากบนเลย์เอาต์ จะทำให้หน้าจออุดตันเมื่อปรับขนาดแล้ว ด้วย max() เราสามารถจัดลำดับความสำคัญของระยะขอบเฉพาะตามความกว้างของคอนเทนเนอร์

ตัวอย่างโค้ด

 .max-margin-container { display: flex; flex-wrap: wrap; width: 100%; } .max-margin-container li { background: #fff2ea; color: #fff; padding: 3px 25px; min-width: 60px; text-align: center; margin: 0 max(4px,1vw) max(4px,1vw) 0; } <ul class="max-margin-container"><li>calc()</li><li>min()</li><li>max()</li><li>clamp()</li> <li>sin()</li><li>cos()</li><li>tan()</li><li>acos()</li><li>asin()</li><li>atan()</li> <li>atan2()</li><li>hypot()</li><li>sqrt()</li><li>pow()</li></ul>

ลองปรับขนาดรายการเพื่อดูการทำงาน:

  • คำนวณ ()
  • นาที()
  • สูงสุด ()
  • ที่หนีบ()
  • บาป()
  • คอส()
  • ตาล()
  • acos()
  • อาซิน()
  • atan()
  • atan2()
  • จุด ()
  • sqrt()
  • แป้ง()

การเปลี่ยนวิวพอร์ตของเบราว์เซอร์เป็นตัวอย่างที่ดีกว่าของการสาธิตการใช้งานจริง และใช่ อันที่จริงแล้ว ฟังก์ชันเหล่านี้เป็นฟังก์ชันทางคณิตศาสตร์ทั้งหมดที่มีอยู่ใน CSS!

อย่างที่คุณเห็น แม้ว่าความกว้างของวิวพอร์ตจะเปลี่ยนไป แต่ปุ่มต่างๆ จะรักษาระยะขอบ 4px ไว้ตลอดเวลา


ที่หนีบ()

ฟังก์ชัน clamp() ใช้เพื่อกำหนดช่วงที่ยอมรับได้ของค่าต่างๆ สำหรับองค์ประกอบเลย์เอาต์: ต่ำสุด ที่ต้องการ และ สูงสุด โดยทั่วไป clamp() ใช้เพื่อกำหนดช่วงของค่าที่ยอมรับได้สำหรับการพิมพ์เพื่อสร้างเอฟเฟกต์ของ การพิมพ์แบบไหล

โดยพื้นฐานแล้วมันคือจุดสุดยอดของคุณสมบัติ min() และ max()

ตัวอย่าง:

font-size: clamp(1rem, 4vw + 1rem, 4rem);

และนี่คือสิ่งที่ดูเหมือน:

ตัวอย่างฟังก์ชันแคลมป์ CSS

ในบริบทนี้ เรากำหนดรูปแบบส่วนหัว h2 ด้วยค่าต่ำสุด 1rem สูงสุด 4rem และเราตั้งค่าขนาดที่ต้องการเป็น 4vw (หน่วยวิวพอร์ต) + 1rem ดังที่คุณเห็นจากการสาธิตด้านบน เนื่องจากวิวพอร์ตของเรามีการเปลี่ยนแปลงขนาดของขนาดแบบอักษรของส่วนหัวก็เปลี่ยนไปเช่นกัน

นอกจากนี้ยังเป็นการสรุปการแนะนำของเราเกี่ยวกับฟังก์ชันทางคณิตศาสตร์ที่ได้รับการสนับสนุนอย่างกว้างขวางที่สุดใน CSS

ส่วนถัดไปจะเน้นเฉพาะตัวอย่างและกรณีการใช้งานต่างๆ ที่สามารถใช้ฟังก์ชันเหล่านี้ได้ โดยรวมแล้ว เรามุ่งเน้นที่การสร้างองค์ประกอบการออกแบบที่ตอบสนอง ซึ่งมิฉะนั้นจะต้องเขียนผ่านการสืบค้นสื่อ

การสร้างแถบด้านข้างที่ตอบสนองด้วย Grid

คุณสามารถใช้แถบด้านข้างตอบสนองที่ทำงานได้อย่างสมบูรณ์ด้วย CSS เพียง 2 บรรทัดหรือไม่

อย่างแน่นอน.

สำหรับการสาธิตนี้ เราจะสร้างแถบด้านข้างที่ตอบสนองโดยใช้ display: grid; และปรับแต่งการตอบสนองด้วย grid-template-columns โดยเฉพาะอย่างยิ่ง เราจะใช้ฟังก์ชันของ fit-content และ minmax() เพื่อกำหนดข้อจำกัดของเรา

ตัวอย่างโค้ด

 .grid-sidebar-demo { display: grid; grid-template-columns: fit-content(25ch) minmax(min(55vw, 35ch), 1fr) }

นี่คือผลลัพธ์:

เนื้อหาแถบด้านข้าง เนื้อหา ในหน้าของคุณ

มาทำความเข้าใจกันว่าเกิดอะไรขึ้นที่นี่

ขั้นแรก เราใช้ fit-content เพื่อประกาศขนาดที่ต้องการของแถบด้านข้างของเรา ค่าที่เราระบุที่นี่จะผลักดันให้แถบด้านข้างขยาย (ตามขนาดวิวพอร์ต) หรือย่อขนาดในหน้าจอที่เล็กกว่า ในขณะที่พิจารณา ปริมาณ เนื้อหาที่คุณมีในแถบด้านข้าง

หลังจากนั้น เราใช้ minmax() เนื่องจากเราไม่ต้องการให้แถบด้านข้างทับซ้อนกับพื้นที่เนื้อหาในหน้า ในกรณีของเรา wet ตั้งค่า 55vw ซึ่งจะใช้สำหรับการแสดงผลบนมือถือ และ 35ch ซึ่งจะใช้สำหรับวิวพอร์ตที่ใหญ่ขึ้น และสุดท้าย เราใช้หน่วยเศษส่วนแบบเจาะจงตารางเพื่อเติมพื้นที่ว่างเมื่อวิวพอร์ตอนุญาต

การใช้ช่องว่างที่ตอบสนองสำหรับเลย์เอาต์ Flexbox

นี่เป็นตัวอย่างที่คล้ายกับการเติมแบบตอบสนองที่เราดูก่อนหน้านี้ แต่สำหรับการสาธิตนี้ เราใช้ flexbox และคุณสมบัติ gap ร่วมกับ clamp()

ตัวอย่างโค้ด

 .gap-boxes-container { display: flex; flex-wrap: wrap; gap: clamp(5px, 1vw, 25px); place-content: center; } .gap-box { display: inline-flex; width: 100px; height: 100px; background-color: #fff2ea; align-items: center; justify-content: center; } <div class="gap-boxes-container"> <div class="gap-box">1</div> <div class="gap-box">2</div> <div class="gap-box">3</div> <div class="gap-box">4</div> </div>

ลองใช้:

1
2
3
4

อีกครั้ง ตัวอย่างนี้จะทำงานได้ดีที่สุดเมื่อคุณปรับขนาดวิวพอร์ตของเบราว์เซอร์จริง

โดยการระบุ gap: clamp(5px, 1vw, 25px); เรากำลังบอกให้เบราว์เซอร์ปรับช่องว่างระหว่างแต่ละคอลัมน์ตามขนาดวิวพอร์ต ดังนั้น หากหน้าต่างเกิน 1vw ช่องว่างจะเพิ่มขึ้นเป็น 25px ในขณะที่วิวพอร์ตขนาดเล็กจะลดลงเหลือ 5px (เช่นบนมือถือ เป็นต้น)

อย่างไรก็ตาม คุณอาจสังเกตเห็นว่าฉันใช้คุณสมบัติที่น่าสนใจเพื่อจัดวางกล่องคอนเทนเนอร์ไว้ตรงกลาง มันคือ place-content: center; . นี่เป็นคุณสมบัติชวเลขที่รองรับการวางตำแหน่งเนื้อหาในทิศทางต่างๆ คุณสามารถอ่านเพิ่มเติมเกี่ยวกับเรื่องนี้ได้ใน MDN

ฉันใช้ได้ไหม: การสนับสนุนอยู่ที่นั่น

บทสรุป

คุณรู้สึกตื่นเต้นที่จะลองใช้แนวคิดเหล่านี้ในโครงการต่อไปของคุณหรือไม่?

ฉันต้องบอกว่า CSS มาไกลตั้งแต่ต้นปี 2010 อันที่จริง หากเราสามารถจัดสไตล์ที่ตอบสนองได้เกือบทั้งหมด โดยไม่ต้อง สอบถามจากสื่อ มันจะดึงดูดนักพัฒนาที่ต้องการเขียนโค้ดและไม่ต้องกังวลเรื่องความเข้ากันได้ระหว่างอุปกรณ์ต่างๆ

ขอบคุณสำหรับการอ่านและขอให้สนุก!