ปลดล็อกศักยภาพของ CSS Flexbox ด้วยการทำความเข้าใจอัลกอริทึมการกำหนดขนาดภายในตัว คู่มือฉบับสมบูรณ์นี้จะอธิบายการกำหนดขนาดตามเนื้อหา, flex-basis, grow, shrink และปัญหาเลย์เอาต์ที่พบบ่อยสำหรับนักพัฒนาทั่วโลก
ไขปริศนาอัลกอริทึมการกำหนดขนาดของ Flexbox: เจาะลึกเลย์เอาต์ตามเนื้อหา
คุณเคยใช้ flex: 1
กับชุดไอเท็มโดยคาดหวังว่าจะได้คอลัมน์ที่เท่ากันเป๊ะ แต่กลับพบว่าขนาดของมันยังคงแตกต่างกันหรือไม่? หรือคุณเคยต้องต่อสู้กับ flex item ที่ดื้อดึงไม่ยอมหดตัว ทำให้เกิด overflow ที่ไม่สวยงามจนทำลายดีไซน์ของคุณ? ปัญหาที่พบบ่อยเหล่านี้มักจะนำนักพัฒนาไปสู่วงจรของการเดาสุ่มและเปลี่ยน property ไปเรื่อยๆ อย่างไรก็ตาม วิธีแก้ปัญหานั้นไม่ใช่เวทมนตร์ แต่เป็นตรรกะ
คำตอบของปริศนาเหล่านี้ซ่อนอยู่ลึกๆ ในข้อกำหนดของ CSS ในกระบวนการที่เรียกว่า Flexbox Intrinsic Sizing Algorithm มันคือเอนจิ้นที่ทรงพลังและรับรู้ถึงเนื้อหาซึ่งเป็นตัวขับเคลื่อน Flexbox แต่ตรรกะภายในของมันมักจะให้ความรู้สึกเหมือนกล่องดำที่ทึบแสง การทำความเข้าใจอัลกอริทึมนี้คือกุญแจสำคัญสู่การเป็นผู้เชี่ยวชาญ Flexbox และสร้าง User Interface ที่คาดเดาได้และยืดหยุ่นอย่างแท้จริง
คู่มือนี้สำหรับนักพัฒนาทั่วโลกที่ต้องการก้าวจากการ "ลองผิดลองถูก" ไปสู่การ "ออกแบบอย่างตั้งใจ" ด้วย Flexbox เราจะมาแจกแจงอัลกอริทึมอันทรงพลังนี้ทีละขั้นตอน เปลี่ยนความสับสนให้เป็นความชัดเจน และช่วยให้คุณสามารถสร้างเลย์เอาต์ที่แข็งแกร่งและรองรับการใช้งานทั่วโลก ซึ่งทำงานได้กับทุกเนื้อหาในทุกภาษา
ก้าวข้ามพิกเซลที่ตายตัว: ทำความเข้าใจ Intrinsic และ Extrinsic Sizing
ก่อนที่จะลงลึกในตัวอัลกอริทึม สิ่งสำคัญคือต้องเข้าใจแนวคิดพื้นฐานในการจัดเลย์เอาต์ของ CSS นั่นคือความแตกต่างระหว่าง intrinsic และ extrinsic sizing
- Extrinsic Sizing: นี่คือเมื่อคุณซึ่งเป็นนักพัฒนา กำหนดขนาดของ element อย่างชัดเจน property เช่น
width: 500px
,height: 50%
, หรือwidth: 30rem
เป็นตัวอย่างของ extrinsic sizing ขนาดจะถูกกำหนดโดยปัจจัยภายนอกเนื้อหาของ element - Intrinsic Sizing: นี่คือเมื่อเบราว์เซอร์คำนวณขนาดของ element โดยอิงจากเนื้อหาที่อยู่ภายใน ปุ่มที่ขยายความกว้างออกไปตามธรรมชาติเพื่อรองรับข้อความที่ยาวขึ้นคือการใช้ intrinsic sizing ขนาดจะถูกกำหนดโดยปัจจัยภายในตัว element เอง
Flexbox เป็นเจ้าแห่งการกำหนดขนาดตามเนื้อหาแบบ intrinsic ในขณะที่คุณเป็นผู้กำหนดกฎ (property ของ flex) เบราว์เซอร์จะเป็นผู้ทำการตัดสินใจเรื่องขนาดสุดท้ายโดยอิงจากเนื้อหาของ flex item และพื้นที่ว่างที่มีอยู่ใน container นี่คือสิ่งที่ทำให้มันทรงพลังมากสำหรับการสร้างดีไซน์ที่ลื่นไหลและตอบสนองได้ดี
สามเสาหลักแห่งความยืดหยุ่น: ทบทวน flex-basis
, flex-grow
, และ flex-shrink
การตัดสินใจของอัลกอริทึม Flexbox ส่วนใหญ่จะถูกชี้นำโดย property สามตัว ซึ่งมักจะถูกกำหนดพร้อมกันโดยใช้ shorthand flex
การทำความเข้าใจสิ่งเหล่านี้อย่างถ่องแท้เป็นสิ่งที่ขาดไม่ได้สำหรับการทำความเข้าใจขั้นตอนต่อไป
1. flex-basis
: จุดเริ่มต้น
ให้คิดว่า flex-basis
คือขนาดเริ่มต้นในอุดมคติหรือ "ตามสมมติฐาน" ของ flex item ตามแนวแกนหลัก ก่อนที่จะมีการขยายหรือหดตัวใดๆ เกิดขึ้น มันคือเส้นฐานที่ใช้ในการคำนวณอื่นๆ ทั้งหมด
- สามารถเป็นค่าความยาว (เช่น
100px
,10rem
) หรือเปอร์เซ็นต์ (25%
) - ค่าเริ่มต้นคือ
auto
เมื่อตั้งค่าเป็นauto
เบราว์เซอร์จะดูที่ property ขนาดหลักของ item ก่อน (width
สำหรับ flex container แนวนอน,height
สำหรับแนวตั้ง) - นี่คือจุดเชื่อมโยงที่สำคัญ: ถ้า property ขนาดหลักเป็น
auto
ด้วยเช่นกันflex-basis
จะถูกแปลงเป็นขนาดตามเนื้อหาภายใน (intrinsic) ของ item นี่คือวิธีที่ตัวเนื้อหาเองได้มีส่วนร่วมในกระบวนการกำหนดขนาดตั้งแต่แรก - ค่า
content
ก็มีให้ใช้เช่นกัน ซึ่งจะบอกเบราว์เซอร์อย่างชัดเจนให้ใช้ขนาด intrinsic
2. flex-grow
: การครอบครองพื้นที่บวก
property flex-grow
เป็นตัวเลขที่ไม่มีหน่วยซึ่งกำหนดว่า item ควรจะดูดซับพื้นที่ว่างที่เป็นบวกใน flex container มากน้อยเพียงใด เมื่อเทียบกับ item อื่นๆ ที่อยู่ข้างเคียง พื้นที่ว่างที่เป็นบวกจะเกิดขึ้นเมื่อ flex container มีขนาดใหญ่กว่าผลรวมของค่า `flex-basis` ของ item ทั้งหมด
- ค่าเริ่มต้นคือ
0
หมายความว่าโดยปกติแล้ว item จะไม่ขยายขนาด - ถ้าทุก item มี
flex-grow: 1
พื้นที่ที่เหลือจะถูกแบ่งเท่าๆ กันระหว่าง item ทั้งหมด - ถ้า item หนึ่งมี
flex-grow: 2
และ item อื่นๆ มีflex-grow: 1
item แรกจะได้รับพื้นที่ว่างเป็นสองเท่าของ item อื่นๆ
3. flex-shrink
: การสละพื้นที่ลบ
property flex-shrink
เป็นส่วนกลับของ flex-grow
มันเป็นตัวเลขที่ไม่มีหน่วยซึ่งควบคุมว่า item จะสละพื้นที่อย่างไรเมื่อ container มีขนาดเล็กเกินไปที่จะรองรับ `flex-basis` ของ item ทั้งหมด นี่มักจะเป็นส่วนที่ถูกเข้าใจผิดมากที่สุดในสามตัวนี้
- ค่าเริ่มต้นคือ
1
หมายความว่าโดยปกติแล้ว item จะได้รับอนุญาตให้หดตัวได้หากจำเป็น - ความเข้าใจผิดที่พบบ่อยคือ
flex-shrink: 2
ทำให้ item หดตัว "เร็วเป็นสองเท่า" ในความหมายง่ายๆ แต่มันซับซ้อนกว่านั้น: ปริมาณที่ item จะหดลงเป็นสัดส่วนกับ ปัจจัย `flex-shrink` คูณด้วย `flex-basis` ของมัน เราจะสำรวจรายละเอียดที่สำคัญนี้พร้อมตัวอย่างที่เป็นรูปธรรมในภายหลัง
อัลกอริทึมการกำหนดขนาดของ Flexbox: การแจกแจงทีละขั้นตอน
ตอนนี้ เรามาเปิดม่านและดูขั้นตอนความคิดของเบราว์เซอร์กัน แม้ว่าข้อกำหนดอย่างเป็นทางการของ W3C จะมีความเป็นเทคนิคและแม่นยำสูง เราสามารถทำให้ตรรกะหลักง่ายลงในรูปแบบลำดับที่ย่อยง่ายขึ้นสำหรับ flex line เดียว
ขั้นตอนที่ 1: กำหนด Flex Base Size และขนาดหลักตามสมมติฐาน
ขั้นแรก เบราว์เซอร์ต้องการจุดเริ่มต้นสำหรับแต่ละ item มันจะคำนวณ flex base size สำหรับทุก item ใน container ซึ่งส่วนใหญ่จะถูกกำหนดโดยค่าที่แปลงแล้วของ property flex-basis
flex base size นี้จะกลายเป็น "ขนาดหลักตามสมมติฐาน" ของ item สำหรับขั้นตอนต่อไป มันคือขนาดที่ item *ต้องการ* จะเป็น ก่อนที่จะมีการต่อรองใดๆ กับ item ข้างเคียง
ขั้นตอนที่ 2: กำหนดขนาดหลักของ Flex Container
ต่อไป เบราว์เซอร์จะคำนวณขนาดของ flex container เองตามแนวแกนหลัก ซึ่งอาจเป็นความกว้างที่กำหนดไว้จาก CSS ของคุณ, เป็นเปอร์เซ็นต์ของ parent ของมัน, หรืออาจถูกกำหนดขนาดโดยเนื้อหาของมันเอง ขนาดสุดท้ายที่แน่นอนนี้คือ "งบประมาณ" ของพื้นที่ที่ flex item ต้องทำงานด้วย
ขั้นตอนที่ 3: รวบรวม Flex Item เป็น Flex Line
จากนั้นเบราว์เซอร์จะกำหนดวิธีการจัดกลุ่ม item ถ้าตั้งค่า flex-wrap: nowrap
(ค่าเริ่มต้น) ไว้ item ทั้งหมดจะถือว่าเป็นส่วนหนึ่งของบรรทัดเดียว ถ้า flex-wrap: wrap
หรือ wrap-reverse
ทำงานอยู่ เบราว์เซอร์จะกระจาย item ไปยังหนึ่งหรือหลายบรรทัด ส่วนที่เหลือของอัลกอริทึมจะถูกนำไปใช้กับแต่ละบรรทัดของ item อย่างอิสระ
ขั้นตอนที่ 4: แก้ปัญหาความยาวที่ยืดหยุ่น (ตรรกะหลัก)
นี่คือหัวใจของอัลกอริทึม ที่ซึ่งการกำหนดขนาดและการกระจายที่แท้จริงเกิดขึ้น มันเป็นกระบวนการสองส่วน
ส่วนที่ 4a: คำนวณพื้นที่ว่าง
เบราว์เซอร์จะคำนวณพื้นที่ว่างทั้งหมดที่มีอยู่ใน flex line โดยการลบผลรวมของ flex base size ของ item ทั้งหมด (จากขั้นตอนที่ 1) ออกจากขนาดหลักของ container (จากขั้นตอนที่ 2)
พื้นที่ว่าง = ขนาดแกนหลักของ Container - ผลรวมของ Flex Base Size ของทุก Item
ผลลัพธ์นี้สามารถเป็น:
- บวก: Container มีพื้นที่มากกว่าที่ item ต้องการ พื้นที่ส่วนเกินนี้จะถูกกระจายโดยใช้
flex-grow
- ลบ: Item ทั้งหมดรวมกันมีขนาดใหญ่กว่า container การขาดดุลของพื้นที่นี้ (overflow) หมายความว่า item ต้องหดตัวตามค่า
flex-shrink
ของมัน - ศูนย์: Item พอดีกันอย่างสมบูรณ์ ไม่จำเป็นต้องมีการขยายหรือหดตัว
ส่วนที่ 4b: กระจายพื้นที่ว่าง
ตอนนี้ เบราว์เซอร์จะกระจายพื้นที่ว่างที่คำนวณได้ นี่เป็นกระบวนการที่ทำซ้ำ แต่เราสามารถสรุปตรรกะได้ดังนี้:
- ถ้าพื้นที่ว่างเป็นบวก (การขยาย):
- เบราว์เซอร์จะรวมปัจจัย
flex-grow
ทั้งหมดของ item ในบรรทัด - จากนั้นจะกระจายพื้นที่ว่างที่เป็นบวกไปยังแต่ละ item ตามสัดส่วน ปริมาณพื้นที่ที่ item ได้รับคือ:
(flex-grow ของ Item / ผลรวมของปัจจัย flex-grow ทั้งหมด) * พื้นที่ว่างที่เป็นบวก
- ขนาดสุดท้ายของ item คือ
flex-basis
ของมันบวกกับส่วนแบ่งของพื้นที่ที่กระจายไป การขยายนี้จะถูกจำกัดโดย propertymax-width
หรือmax-height
ของ item
- เบราว์เซอร์จะรวมปัจจัย
- ถ้าพื้นที่ว่างเป็นลบ (การหด):
- นี่เป็นส่วนที่ซับซ้อนกว่า สำหรับแต่ละ item เบราว์เซอร์จะคำนวณ weighted shrink factor โดยการคูณ flex base size ของมันด้วยค่า
flex-shrink
:Weighted Shrink Factor = Flex Base Size * flex-shrink
- จากนั้นจะรวม weighted shrink factor ทั้งหมดนี้เข้าด้วยกัน
- พื้นที่ติดลบ (ปริมาณของ overflow) จะถูกกระจายไปยังแต่ละ item ตามสัดส่วนโดยอิงจากปัจจัยถ่วงน้ำหนักนี้ ปริมาณที่ item จะหดลงคือ:
(Weighted Shrink Factor ของ Item / ผลรวมของ Weighted Shrink Factor ทั้งหมด) * พื้นที่ว่างติดลบ
- ขนาดสุดท้ายของ item คือ
flex-basis
ของมันลบด้วยส่วนแบ่งของพื้นที่ติดลบที่กระจายไป การหดตัวนี้จะถูกจำกัดโดย propertymin-width
หรือmin-height
ของ item ซึ่งที่สำคัญคือมีค่าเริ่มต้นเป็นauto
- นี่เป็นส่วนที่ซับซ้อนกว่า สำหรับแต่ละ item เบราว์เซอร์จะคำนวณ weighted shrink factor โดยการคูณ flex base size ของมันด้วยค่า
ขั้นตอนที่ 5: การจัดแนวแกนหลัก
เมื่อขนาดสุดท้ายของ item ทั้งหมดถูกกำหนดแล้ว เบราว์เซอร์จะใช้ property justify-content
เพื่อจัดแนว item ตามแกนหลักภายใน container สิ่งนี้เกิดขึ้น *หลังจาก* การคำนวณขนาดทั้งหมดเสร็จสิ้น
สถานการณ์จริง: จากทฤษฎีสู่ความเป็นจริง
การเข้าใจทฤษฎีเป็นเรื่องหนึ่ง การได้เห็นมันทำงานจริงจะช่วยตอกย้ำความรู้ให้แน่นขึ้น เรามาดูสถานการณ์ทั่วไปที่ตอนนี้สามารถอธิบายได้ง่ายด้วยความเข้าใจในอัลกอริทึมของเรา
สถานการณ์ที่ 1: คอลัมน์ที่เท่ากันอย่างแท้จริงและ Shorthand `flex: 1`
ปัญหา: คุณใช้ flex-grow: 1
กับทุก item แต่มันกลับไม่ได้มีความกว้างเท่ากัน
คำอธิบาย: สิ่งนี้เกิดขึ้นเมื่อคุณใช้ shorthand เช่น flex: auto
(ซึ่งขยายเป็น flex: 1 1 auto
) หรือเพียงแค่ตั้งค่า flex-grow: 1
โดยปล่อยให้ flex-basis
เป็นค่าเริ่มต้นคือ auto
ตามอัลกอริทึม flex-basis: auto
จะถูกแปลงเป็นขนาดเนื้อหาของ item ดังนั้น item ที่มีเนื้อหามากกว่าจึงเริ่มต้นด้วย flex base size ที่ใหญ่กว่า แม้ว่าพื้นที่ว่างที่เหลือจะถูกกระจายอย่างเท่าเทียมกัน ขนาดสุดท้ายของ item จะแตกต่างกันเพราะจุดเริ่มต้นของพวกมันแตกต่างกัน
วิธีแก้: ใช้ shorthand flex: 1
ซึ่งจะขยายเป็น flex: 1 1 0%
กุญแจสำคัญคือ flex-basis: 0%
สิ่งนี้บังคับให้ทุก item เริ่มต้นด้วยขนาดฐานตามสมมติฐานเป็น 0 ความกว้างทั้งหมดของ container จะกลายเป็น "พื้นที่ว่างที่เป็นบวก" เนื่องจากทุก item มี flex-grow: 1
พื้นที่ทั้งหมดนี้จึงถูกกระจายอย่างเท่าเทียมกันระหว่าง item ทั้งหมด ส่งผลให้ได้คอลัมน์ที่มีความกว้างเท่ากันอย่างแท้จริงโดยไม่คำนึงถึงเนื้อหา
สถานการณ์ที่ 2: ปริศนาสัดส่วนของ `flex-shrink`
ปัญหา: คุณมี item สองชิ้น ทั้งคู่มี flex-shrink: 1
แต่เมื่อ container หดตัว item หนึ่งกลับสูญเสียความกว้างไปมากกว่าอีกชิ้นหนึ่งมาก
คำอธิบาย: นี่คือตัวอย่างที่สมบูรณ์แบบของขั้นตอนที่ 4b สำหรับพื้นที่ว่างติดลบ การหดตัวไม่ได้ขึ้นอยู่กับปัจจัย flex-shrink
เพียงอย่างเดียว แต่จะถูกถ่วงน้ำหนักด้วย flex-basis
ของ item item ที่ใหญ่กว่ามีส่วนที่จะ "สละ" ได้มากกว่า
พิจารณา container ขนาด 500px ที่มี item สองชิ้น:
- Item A:
flex: 0 1 400px;
(ขนาดฐาน 400px) - Item B:
flex: 0 1 200px;
(ขนาดฐาน 200px)
ขนาดฐานทั้งหมดคือ 600px ซึ่งใหญ่กว่า container อยู่ 100px (พื้นที่ว่างติดลบ 100px)
- Weighted shrink factor ของ Item A:
400px * 1 = 400
- Weighted shrink factor ของ Item B:
200px * 1 = 200
- ผลรวมของปัจจัยถ่วงน้ำหนัก:
400 + 200 = 600
ตอนนี้ กระจายพื้นที่ว่างติดลบ 100px:
- Item A หดลง:
(400 / 600) * 100px = ~66.67px
- Item B หดลง:
(200 / 600) * 100px = ~33.33px
แม้ว่าทั้งคู่จะมี flex-shrink: 1
แต่ item ที่ใหญ่กว่ากลับสูญเสียความกว้างไปเป็นสองเท่าเพราะขนาดฐานของมันใหญ่เป็นสองเท่า อัลกอริทึมทำงานตรงตามที่ออกแบบไว้ทุกประการ
สถานการณ์ที่ 3: ไอเท็มที่ไม่ยอมหดและวิธีแก้ด้วย `min-width: 0`
ปัญหา: คุณมี item ที่มีข้อความยาวๆ (เช่น URL) หรือรูปภาพขนาดใหญ่ และมันไม่ยอมหดตัวลงต่ำกว่าขนาดที่กำหนด ทำให้มันล้นออกจาก container
คำอธิบาย: จำไว้ว่ากระบวนการหดตัวถูกจำกัดด้วยขนาดต่ำสุดของ item โดยค่าเริ่มต้น flex item จะมี min-width: auto
สำหรับ element ที่มีข้อความหรือรูปภาพ ค่า auto
นี้จะถูกแปลงเป็นขนาดต่ำสุดภายในตัวของมัน สำหรับข้อความ นี่มักจะเป็นความกว้างของคำหรือสตริงที่ยาวที่สุดที่ไม่สามารถตัดได้ อัลกอริทึม flex จะหด item แต่จะหยุดเมื่อถึงความกว้างต่ำสุดที่คำนวณได้นี้ ซึ่งจะนำไปสู่การ overflow หากยังไม่มีพื้นที่เพียงพอ
วิธีแก้: เพื่อให้ item สามารถหดตัวได้เล็กกว่าขนาดเนื้อหาภายในของมัน คุณต้องลบล้างพฤติกรรมเริ่มต้นนี้ วิธีแก้ไขที่พบบ่อยที่สุดคือการใช้ min-width: 0
กับ flex item สิ่งนี้จะบอกเบราว์เซอร์ว่า "ฉันอนุญาตให้คุณหด item นี้ลงไปจนถึงความกว้างศูนย์ได้ถ้าจำเป็น" ซึ่งจะช่วยป้องกันการ overflow
หัวใจของการกำหนดขนาดภายใน: `min-content` และ `max-content`
เพื่อให้เข้าใจการกำหนดขนาดตามเนื้อหาอย่างถ่องแท้ เราต้องนิยามคีย์เวิร์ดที่เกี่ยวข้องสองคำอย่างรวดเร็ว:
max-content
: ความกว้างที่ต้องการโดยธรรมชาติของ element สำหรับข้อความ มันคือความกว้างที่ข้อความจะใช้หากมีพื้นที่ไม่สิ้นสุดและไม่ต้องตัดคำเลยmin-content
: ความกว้างต่ำสุดโดยธรรมชาติของ element สำหรับข้อความ มันคือความกว้างของสตริงที่ยาวที่สุดที่ไม่สามารถตัดได้ (เช่น คำยาวๆ คำเดียว) นี่คือขนาดที่เล็กที่สุดที่มันสามารถเป็นได้โดยที่เนื้อหาของมันเองไม่ล้นออกมา
เมื่อ flex-basis
เป็น auto
และ width
ของ item ก็เป็น auto
ด้วย เบราว์เซอร์จะใช้ขนาด max-content
เป็น flex base size เริ่มต้นของ item นี่คือเหตุผลที่ item ที่มีเนื้อหามากกว่าจะเริ่มต้นด้วยขนาดที่ใหญ่กว่า ก่อนที่อัลกอริทึม flex จะเริ่มกระจายพื้นที่ว่างเสียอีก
ผลกระทบในระดับโลกและประสิทธิภาพ
แนวทางที่ขับเคลื่อนด้วยเนื้อหานี้มีข้อควรพิจารณาที่สำคัญสำหรับผู้ชมทั่วโลกและสำหรับแอปพลิเคชันที่ต้องการประสิทธิภาพสูง
เรื่องของ Internationalization (i18n)
การกำหนดขนาดตามเนื้อหาเป็นดาบสองคมสำหรับเว็บไซต์นานาชาติ ในแง่หนึ่ง มันยอดเยี่ยมสำหรับการปรับเลย์เอาต์ให้เข้ากับภาษาต่างๆ ซึ่งป้ายกำกับบนปุ่มและหัวข้ออาจมีความยาวแตกต่างกันอย่างมาก ในทางกลับกัน มันอาจทำให้เกิดการแตกของเลย์เอาต์ที่ไม่คาดคิดได้
ลองพิจารณาภาษาเยอรมัน ซึ่งมีชื่อเสียงในเรื่องคำประสมที่ยาวเหยียด คำอย่าง "Donaudampfschifffahrtsgesellschaftskapitän" จะเพิ่มขนาด min-content
ของ element อย่างมีนัยสำคัญ หาก element นั้นเป็น flex item มันอาจจะต่อต้านการหดตัวในแบบที่คุณไม่ได้คาดคิดไว้เมื่อออกแบบเลย์เอาต์ด้วยข้อความภาษาอังกฤษที่สั้นกว่า ในทำนองเดียวกัน บางภาษาเช่นญี่ปุ่นหรือจีนอาจไม่มีการเว้นวรรคระหว่างคำ ซึ่งส่งผลต่อการคำนวณการตัดคำและการกำหนดขนาด นี่เป็นตัวอย่างที่สมบูรณ์แบบว่าทำไมการทำความเข้าใจอัลกอริทึมภายในจึงสำคัญอย่างยิ่งต่อการสร้างเลย์เอาต์ที่แข็งแกร่งพอที่จะทำงานได้สำหรับทุกคน ทุกที่
ข้อสังเกตด้านประสิทธิภาพ
เนื่องจากเบราว์เซอร์ต้องวัดเนื้อหาของ flex item เพื่อคำนวณขนาดภายในของมัน จึงมีต้นทุนในการคำนวณ สำหรับเว็บไซต์และแอปพลิเคชันส่วนใหญ่ ต้นทุนนี้เล็กน้อยและไม่น่ากังวล อย่างไรก็ตาม ใน UI ที่ซับซ้อนและซ้อนกันลึกๆ ซึ่งมี element หลายพันชิ้น การคำนวณเลย์เอาต์เหล่านี้อาจกลายเป็นคอขวดด้านประสิทธิภาพได้ ในกรณีขั้นสูงเช่นนี้ นักพัฒนาอาจสำรวจ property ของ CSS เช่น contain: layout
หรือ content-visibility
เพื่อเพิ่มประสิทธิภาพการเรนเดอร์ แต่นั่นเป็นหัวข้อสำหรับวันอื่น
ข้อมูลเชิงปฏิบัติ: สูตรโกงการกำหนดขนาด Flexbox ของคุณ
โดยสรุป นี่คือประเด็นสำคัญที่คุณสามารถนำไปใช้ได้ทันที:
- สำหรับคอลัมน์ที่มีความกว้างเท่ากันอย่างแท้จริง: ให้ใช้
flex: 1
เสมอ (ซึ่งเป็นรูปย่อของflex: 1 1 0%
)flex-basis
ที่เป็นศูนย์คือกุญแจสำคัญ - ถ้า item ไม่ยอมหด: ตัวการที่น่าจะเป็นไปได้มากที่สุดคือ
min-width: auto
ที่ซ่อนอยู่ ให้ใช้min-width: 0
กับ flex item เพื่อให้มันสามารถหดตัวได้เล็กกว่าขนาดเนื้อหาของมัน - จำไว้ว่า `flex-shrink` มีการถ่วงน้ำหนัก: Item ที่มี
flex-basis
ใหญ่กว่าจะหดตัวในแง่ของค่าสัมบูรณ์มากกว่า item ที่เล็กกว่าซึ่งมีปัจจัยflex-shrink
เท่ากัน - `flex-basis` คือราชา: มันเป็นตัวกำหนดจุดเริ่มต้นสำหรับการคำนวณขนาดทั้งหมด ควบคุม
flex-basis
เพื่อให้มีอิทธิพลมากที่สุดต่อเลย์เอาต์สุดท้าย การใช้auto
จะอ้างอิงตามขนาดของเนื้อหา การใช้ค่าที่ระบุจะให้คุณควบคุมได้อย่างชัดเจน - คิดเหมือนเบราว์เซอร์: นึกภาพตามขั้นตอน ขั้นแรก หาขนาดพื้นฐาน จากนั้น คำนวณพื้นที่ว่าง (บวกหรือลบ) สุดท้าย กระจายพื้นที่นั้นตามกฎ grow/shrink
บทสรุป
อัลกอริทึมการกำหนดขนาดของ CSS Flexbox ไม่ใช่เวทมนตร์ที่ไร้หลักการ แต่เป็นระบบที่ถูกกำหนดมาอย่างดี มีตรรกะ และทรงพลังอย่างยิ่งในการรับรู้ถึงเนื้อหา ด้วยการก้าวข้ามการจับคู่ property-value แบบง่ายๆ และทำความเข้าใจกระบวนการที่อยู่เบื้องหลัง คุณจะได้รับความสามารถในการคาดการณ์ ดีบัก และออกแบบเลย์เอาต์ด้วยความมั่นใจและแม่นยำ
ครั้งต่อไปที่ flex item ทำงานผิดปกติ คุณไม่จำเป็นต้องเดาอีกต่อไป คุณสามารถไล่ตามอัลกอริทึมในใจได้: ตรวจสอบ flex-basis
, พิจารณาขนาดภายในของเนื้อหา, วิเคราะห์พื้นที่ว่าง, และใช้กฎของ flex-grow
หรือ flex-shrink
ตอนนี้คุณมีความรู้ที่จะสร้าง UI ที่ไม่เพียงแต่สวยงาม แต่ยังยืดหยุ่น ปรับตัวเข้ากับธรรมชาติที่ไม่หยุดนิ่งของเนื้อหาได้อย่างสวยงาม ไม่ว่าเนื้อหานั้นจะมาจากที่ใดในโลกก็ตาม