ฟังก์ชันคณิตศาสตร์ CSS: calc, min, max, clamp
เผยแพร่แล้ว: 2022-03-20- คำนวณ ()
- นาที()
- สูงสุด ()
- ที่หนีบ()
- การสร้างแถบด้านข้างที่ตอบสนองด้วย 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>
และนี่จะเป็นผลลัพธ์:
แต่ที่ 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>
และที่นี่คุณสามารถปรับขนาดผลลัพธ์เพื่อดูว่ามันทำงานอย่างไร:
เนื่องจากเราต้องการให้มีช่องว่าง 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>
ลองปรับขนาดนี้:
ในบริบทนี้ องค์ประกอบ 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>
ลองปรับขนาดนี้เป็นคอนเทนเนอร์ขนาดเล็กลงเพื่อดูว่าเกิดอะไรขึ้น:
อย่างที่คุณเห็น – คอนเทนเนอร์ยึดตาม 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);
และนี่คือสิ่งที่ดูเหมือน:

ในบริบทนี้ เรากำหนดรูปแบบส่วนหัว 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>
ลองใช้:
อีกครั้ง ตัวอย่างนี้จะทำงานได้ดีที่สุดเมื่อคุณปรับขนาดวิวพอร์ตของเบราว์เซอร์จริง
โดยการระบุ gap: clamp(5px, 1vw, 25px);
เรากำลังบอกให้เบราว์เซอร์ปรับช่องว่างระหว่างแต่ละคอลัมน์ตามขนาดวิวพอร์ต ดังนั้น หากหน้าต่างเกิน 1vw ช่องว่างจะเพิ่มขึ้นเป็น 25px ในขณะที่วิวพอร์ตขนาดเล็กจะลดลงเหลือ 5px (เช่นบนมือถือ เป็นต้น)
อย่างไรก็ตาม คุณอาจสังเกตเห็นว่าฉันใช้คุณสมบัติที่น่าสนใจเพื่อจัดวางกล่องคอนเทนเนอร์ไว้ตรงกลาง มันคือ place-content: center;
. นี่เป็นคุณสมบัติชวเลขที่รองรับการวางตำแหน่งเนื้อหาในทิศทางต่างๆ คุณสามารถอ่านเพิ่มเติมเกี่ยวกับเรื่องนี้ได้ใน MDN
ฉันใช้ได้ไหม: การสนับสนุนอยู่ที่นั่น

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