อะไรคือความแตกต่างระหว่างความยืดหยุ่นและความกว้าง?


224

มีคำถามและบทความเกี่ยวกับเรื่องนี้ แต่ไม่มีข้อสรุปใด ๆ เท่าที่ฉันสามารถบอกได้ บทสรุปที่ดีที่สุดที่ฉันสามารถหาได้คือ

flex-basedช่วยให้คุณสามารถระบุขนาดเริ่มต้น / เริ่มต้นขององค์ประกอบก่อนที่จะคำนวณสิ่งอื่นใด อาจเป็นเปอร์เซ็นต์หรือค่าสัมบูรณ์

... ซึ่งในตัวมันเองไม่ได้พูดอะไรมากเกี่ยวกับพฤติกรรมขององค์ประกอบที่มีการตั้งค่าแบบยืดหยุ่น ด้วยความรู้ปัจจุบันเกี่ยวกับ flexbox ของฉันฉันไม่เห็นสาเหตุที่ไม่สามารถอธิบายความกว้างได้

ฉันต้องการทราบว่าflex-baseแตกต่างจากความกว้างในทางปฏิบัติอย่างไร

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

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


บทความที่ดีที่สุดอธิบายพื้นฐานการยืดหยุ่นดิ้นขยายและหดตัวพร้อมกัน
ZenVentzi

คำตอบ:


339

พิจารณา flex-direction

สิ่งแรกที่มาถึงใจเมื่ออ่านคำถามของคุณคือการที่ไม่เคยนำไปใช้กับflex-basiswidth

เมื่อflex-directionเป็นrow, flex-basisการควบคุมความกว้าง

แต่เมื่อflex-directionเป็นcolumn, flex-basisการควบคุมความสูง


ความแตกต่างที่สำคัญ

นี่คือความแตกต่างที่สำคัญระหว่างflex-basisและwidth/ height:

  • flex-basisใช้กับไอเท็ม flex เท่านั้น ภาชนะ Flex (ที่ไม่ได้นอกจากนี้ยังมีรายการ flex) จะไม่สนใจflex-basisแต่สามารถใช้และwidthheight

  • flex-basisทำงานบนแกนหลักเท่านั้น ตัวอย่างเช่นถ้าคุณอยู่ในflex-direction: columnที่widthสถานที่ให้บริการจะต้องใช้สำหรับการปรับขนาดรายการแนวนอนดิ้น

  • flex-basisจะไม่มีผลกับไอเท็มเฟล็กซ์ตำแหน่งที่แน่นอน widthและheightคุณสมบัติจะมีความจำเป็น อย่างตำแหน่งรายการดิ้นไม่ได้มีส่วนร่วมในรูปแบบเฟล็กซ์

  • โดยใช้flexสถานที่ให้บริการสามคุณสมบัติ - flex-grow, flex-shrinkและflex-basis- สามารถรวมกันได้อย่างเรียบร้อยเป็นหนึ่งในการประกาศ ใช้widthกฎเดียวกันจะต้องมีรหัสหลายบรรทัด


พฤติกรรมเบราว์เซอร์

ในแง่ของวิธีที่พวกเขาจะแสดงผลควรจะมีความแตกต่างระหว่างflex-basisและwidthเว้นแต่flex-basisเป็นหรือautocontent

จากสเป็ค:

7.2.3 flex-basisคุณสมบัติ

สำหรับค่าอื่น ๆ ทั้งหมดกว่าautoและcontent, flex-basisได้รับการแก้ไขแบบเดียวกับwidthในโหมดการเขียนในแนวนอน

แต่ผลกระทบของautoหรือcontentอาจจะน้อยหรือไม่มีอะไรเลย เพิ่มเติมจากสเป็ค:

auto

เมื่อระบุไว้ในรายการเฟล็กซ์ที่คำหลักดึงค่าของหลักคุณสมบัติขนาดเป็นที่ใช้auto flex-basisหากค่าที่เป็นตัวเองแล้วค่าที่ใช้คือautocontent

content

ระบุขนาดอัตโนมัติขึ้นอยู่กับเนื้อหาของรายการที่ยืดหยุ่น

หมายเหตุ: ค่านี้ไม่ปรากฏในรุ่นที่วางจำหน่ายครั้งแรกของ Flexible Box Layout ดังนั้นการใช้งานรุ่นเก่าบางอย่างจะไม่สนับสนุน ผลเทียบเท่าสามารถทำได้โดยการใช้autoร่วมกันที่มีขนาดหลัก ( widthหรือheight) autoของ

ดังนั้นตามข้อมูลจำเพาะflex-basisและwidthแก้ไขเหมือนกันเว้นแต่flex-basisเป็นหรือauto contentในกรณีเช่นนี้flex-basisอาจใช้ความกว้างของเนื้อหา (ซึ่งน่าจะเป็นwidthคุณสมบัติที่ใช้เช่นกัน)


flex-shrinkปัจจัย

สิ่งสำคัญคือต้องจดจำการตั้งค่าเริ่มต้นของ flex container การตั้งค่าบางอย่างเหล่านี้รวมถึง:

  • flex-direction: row - รายการที่ยืดหยุ่นจะจัดเรียงในแนวนอน
  • justify-content: flex-start - ไอเท็มแบบเฟล็กจะเรียงซ้อนกันที่จุดเริ่มต้นของบรรทัดบนแกนหลัก
  • align-items: stretch - รายการที่ยืดหยุ่นจะขยายเพื่อครอบคลุมขนาดข้ามของคอนเทนเนอร์
  • flex-wrap: nowrap - รายการที่ยืดหยุ่นจะถูกบังคับให้อยู่ในบรรทัดเดียว
  • flex-shrink: 1 - ไอเท็มเฟล็กซ์ได้รับอนุญาตให้หด

บันทึกการตั้งค่าล่าสุด

เนื่องจากรายการดิ้นได้รับอนุญาตให้หดตัวตามค่าเริ่มต้น (ซึ่งป้องกันไม่ให้ล้นภาชนะ) ที่ระบุflex-basis/ width/ heightอาจถูกแทนที่

ตัวอย่างเช่น flex-basis: 100pxหรือwidth: 100pxประกอบกับflex-shrink: 1จะไม่จำเป็นต้องเป็น 100px

ในการแสดงความกว้างที่ระบุ - และคงไว้ - คุณจะต้องปิดการหดตัว:

div {
   width: 100px;
   flex-shrink: 0;
}  

หรือ

div {
  flex-basis: 100px;
  flex-shrink: 0;
}

หรือตามคำแนะนำของสเป็ค:

flex: 0 0 100px;    /* don't grow, don't shrink, stay fixed at 100px */

7.2 ส่วนประกอบของความยืดหยุ่น

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


ข้อบกพร่องของเบราว์เซอร์

เบราว์เซอร์บางตัวมีปัญหาในการปรับขนาดรายการ flex ในคอนเทนเนอร์แบบซ้อนที่ซ้อนกัน

flex-basisละเว้นในคอนเทนเนอร์ flex แบบซ้อน widthโรงงาน

เมื่อใช้flex-basisคอนเทนเนอร์จะไม่สนใจขนาดของลูกและเด็ก ๆ จะล้นภาชนะ แต่ด้วยwidthคุณสมบัติภาชนะที่เคารพขนาดของเด็กและขยายตาม

อ้างอิง:

ตัวอย่าง:


งอรายการที่ใช้flex-basisและคอนเทนเนอร์ white-space: nowrapล้น โรงงานinline-flexwidth

ดูเหมือนว่าชุดเฟล็กซ์คอนเทนเนอร์จะinline-flexไม่รู้จักflex-basisกับเด็กเมื่อแสดงผล sibling ด้วยwhite-space: nowrap(แม้ว่ามันอาจเป็นเพียงรายการที่มีความกว้างไม่ได้กำหนด) คอนเทนเนอร์ไม่ขยายเพื่อรองรับรายการ

แต่เมื่อwidthคุณสมบัติถูกนำมาใช้แทนflex-basisภาชนะที่เคารพขนาดของเด็กและขยายตาม นี่ไม่ใช่ปัญหาใน IE11 และ Edge

อ้างอิง:

ตัวอย่าง:


flex-basis(และflex-grow) ไม่ทำงานกับองค์ประกอบตาราง

อ้างอิง:


flex-basisล้มเหลวใน Chrome และ Firefox เมื่อคอนเทนเนอร์ grandparent เป็นองค์ประกอบย่อให้พอดี การตั้งค่าทำงานได้ดีใน Edge

เช่นเดียวกับในตัวอย่างที่นำเสนอในลิงค์ด้านบนซึ่งเกี่ยวข้องกับposition: absoluteการใช้floatและinline-blockจะทำให้การแสดงผลมีข้อบกพร่องเหมือนกัน ( สาธิต jsfiddle )


ข้อบกพร่องที่มีผลต่อ IE 10 และ 11:


2
แล้วไงmin-width:100px;ล่ะ เป็นตัวเลือกในการปิดการหดตัวหรือไม่?
โมริ

1
@Mori ใช่หยุดที่flex-shrink กฎดิ้นจะเทียบเท่าmin-width flex: 1 0 100px
Michael Benjamin

flex: 1 0 100pxนำไปสู่ผลลัพธ์เดียวกัน แต่ฉันไม่แน่ใจว่าสิ่งที่คุณหมายถึงโดย "เทียบเท่า"
โมริ

ผมหมายถึงว่าทำไมเราไม่ควรคิดว่ามันเท่ากับflex: 0 0 100pxเช่น?
โมริ

2
@Mori แล้วเพราะมันเป็นเพียงแค่เท่ากับความกว้าง มันต้องการดิ้นเติบโต: 1องค์ประกอบที่จะช่วยให้องค์ประกอบที่จะเติบโตจากความกว้างต่ำสุดที่กำหนดโดยดิ้นพื้นฐาน
Michael Benjamin

33

นอกเหนือจากบทสรุปที่ยอดเยี่ยมของ Michael_B มันก็คุ้มค่าที่จะทำสิ่งนี้ซ้ำ:

flex-พื้นฐานช่วยให้คุณสามารถระบุขนาดเริ่มต้น / เริ่มต้นขององค์ประกอบก่อนที่จะมีการคำนวณอย่างอื่น อาจเป็นเปอร์เซ็นต์หรือค่าสัมบูรณ์

ส่วนสำคัญที่นี่คือ การเริ่มต้น

ด้วยตัวเองสิ่งนี้จะแก้ไขความกว้าง / ความสูง จนกว่าคุณสมบัติการขยาย / หดแบบยืดหยุ่นอื่น ๆ จะเข้าสู่การเล่น

ดังนั้น. เด็กด้วย

.child {
 flex-basis:25%;
 flex-grow:1;
}

จะมีความกว้าง 25% ในตอนแรก แต่จากนั้นจะขยายให้มากที่สุดเท่าที่จะทำได้จนกว่าองค์ประกอบอื่น ๆ จะได้รับการพิจารณาหากไม่มีสิ่งใด .. จะมีความกว้าง 100% / สูง

การสาธิตอย่างรวดเร็ว:

การทดลองกับflex-grow, flex-shrinkและflex-basis (หรือจดชวเลขflex :fg fs fb) ... สามารถนำไปสู่ผลที่น่าสนใจ


ฉันพบว่าโดยทั่วไปในบริบทที่ยืดหยุ่นพวกเขาทั้งสองflex-basisและwidth / heightกำหนดขนาดเริ่มต้น / เริ่มต้นขององค์ประกอบ ยกตัวอย่างเช่นพื้นงานเช่นเดียวกับflex-basis: 200px flex-basis: auto; width: 200px;ดูเหมือนว่าเมื่อflex-basisไม่ได้ตั้งค่าautoมันก็แค่แทนที่width / heightค่า ความแตกต่างเพียงอย่างเดียวที่ฉันเห็นคือวิธีจัดการเนื้อหาที่ล้น
Karolis

5

อาจเป็นจุดสำคัญที่สุดในการเพิ่ม:

เกิดอะไรขึ้นถ้าเบราว์เซอร์ไม่สนับสนุนflex? ในกรณีเช่นนี้width/heightยึดครองและใช้ค่าของพวกเขา

มันเป็นความคิดที่ดีมาก - เกือบจำเป็น - การกำหนดองค์ประกอบแม้ว่าคุณแล้วมีค่าที่แตกต่างกันอย่างสมบูรณ์สำหรับwidth/height flex-basisอย่าลืมทดสอบด้วยการปิดการใช้งานdisplay:flexและดูสิ่งที่คุณได้รับ


2
ในบรรดาเบราว์เซอร์หลัก ๆ สิ่งเดียวที่ไม่รองรับคุณสมบัติยืดหยุ่นคือ IE <10 caniuse.com/#search=flex
Michael Benjamin

1
@Michael_B แน่นอนและอาจเป็นเพียงฉัน แต่ฉันต้องสนับสนุนเบราว์เซอร์มือถือด้วยและรวมถึงเบราว์เซอร์ Nintendo 3DS ซึ่งไม่สนับสนุนflexอย่างแน่นอน
Niet the Dark Absolute
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.