วิธีปิดการใช้งานการยุบขอบ?


202

มีวิธีปิดใช้งานการยุบขอบทั้งหมดหรือไม่ วิธีแก้ปัญหาเดียวที่ฉันพบ (โดยใช้ชื่อ "uncollapsing") เกี่ยวข้องกับการใช้ 1px border หรือ 1px padding ฉันพบสิ่งที่ยอมรับไม่ได้: พิกเซลที่ไม่เกี่ยวข้องนั้นทำให้การคำนวณซับซ้อนขึ้นโดยไม่มีเหตุผลที่ดี มีวิธีที่เหมาะสมกว่าในการปิดใช้งานการยุบขอบนี้หรือไม่


4
ใช้เค้าโครงแบบยืดหยุ่นหรือกริดที่ไม่มีการยุบตัวของขอบ: stackoverflow.com/a/46496701/3597276
Michael Benjamin

เพียงให้องค์ประกอบเป็นค่าmargin-bottomแต่ปล่อยให้margin-topเป็น 0
Dan Bray

ฉันทำแพคเกจเพื่อทำให้การคำนวณง่ายขึ้น: npmjs.com/package/collapsed-margin
Owen M

คำตอบ:


254

การยุบระยะขอบมีสองประเภทหลัก:

  • การยุบระยะขอบระหว่างองค์ประกอบที่อยู่ติดกัน
  • การยุบระยะขอบระหว่างองค์ประกอบหลักและองค์ประกอบย่อย

การใช้ช่องว่างภายในหรือเส้นขอบจะป้องกันการยุบในกรณีหลังเท่านั้น นอกจากนี้ค่าใด ๆ ที่overflowแตกต่างจากค่าเริ่มต้น ( visible) ที่ใช้กับพาเรนต์จะป้องกันการยุบ ดังนั้นทั้งoverflow: autoและoverflow: hiddenจะมีผลเช่นเดียวกัน บางทีความแตกต่างเพียงอย่างเดียวเมื่อใช้hiddenเป็นผลมาจากการซ่อนเนื้อหาถ้าผู้ปกครองมีความสูงคงที่

คุณสมบัติอื่น ๆ ที่เมื่อนำไปใช้กับผู้ปกครองสามารถช่วยแก้ไขพฤติกรรมนี้คือ:

  • float: left / right
  • position: absolute
  • display: inline-block / flex

คุณสามารถทดสอบทั้งหมดของพวกเขาที่นี่: http://jsfiddle.net/XB9wX/1/

ฉันควรเพิ่มสิ่งนั้นตามปกติ Internet Explorer เป็นข้อยกเว้น โดยเฉพาะอย่างยิ่งใน IE 7 widthอัตรากำไรขั้นต้นไม่ยุบเมื่อชนิดของรูปแบบบางอย่างที่ระบุไว้สำหรับองค์ประกอบหลักเช่น

แหล่งที่มา: บทความของ Sitepoint Margin Margins


1
โปรดทราบว่าการขยายอาจส่งผลกระทบต่อสิ่งนี้หากไม่มีค่าเป็นศูนย์
Mladen Janjetovic

3
โปรดทราบว่าอาจทำให้เกิดการเลื่อนจะปรากฏในองค์ประกอบหลักมากกว่าการปล่อยให้ล้นล้นเนื้อหาตามoverflow: auto overflow: visible
Leo

'ล้น: อัตโนมัติ' ดูเหมือนจะไม่ทำงานใน Chrome v44
tkane2000

3
ขอบคุณสำหรับการแสดง: บล็อกแบบอินไลน์มันช่วยฉัน :)
alexcasalboni

3
ค่าใด ๆ ที่flexแตกต่างจากค่าเริ่มต้นจะปิดใช้งานการล่มของระยะขอบ
Oly

60

คุณยังสามารถใช้ micro clearfix แบบเก่าที่ดีสำหรับเรื่องนี้

#container:before, #container:after{
    content: ' ';
    display: table;
}

ดูซอที่อัพเดท: http://jsfiddle.net/XB9wX/97/


เปลี่ยนคำตอบของฉันเป็นวิกิชุมชน โปรดส่งต่อพร้อมคำตอบของคุณ ขอบคุณ
hqcasanova

3
ฉันไม่เข้าใจเมื่อฉันดูตัวอย่างว่าระยะขอบกำลังยุบลง (เฉพาะพื้นที่แนวตั้ง 10px ระหว่าง divs แทนที่จะเป็น 20px)
Andy

1
ซึ่งจะช่วยในการลบการยุบระหว่างพี่น้องที่มีการใช้ clearfix นี้ทั้งหมด ฉันได้ยกตัวอย่างเพื่อสาธิตสิ่งนี้: jsfiddle.net/dpyuyg07 --- และถึงแม้จะไม่ใช่เรื่องทั้งหมด มันจะกำจัดการยุบของระยะขอบที่เกิดจากลูกขององค์ประกอบที่คุณได้ใช้การแก้ไขนั้น หากคุณต้องการเพิ่มระยะขอบบนคอนเทนเนอร์ตัวเองขอบจะยังคงยุบซึ่งสามารถเห็นได้ในส้อมนี้: jsfiddle.net/oew7qsjx
NicBright

4
ฉันสามารถใส่สิ่งนี้ได้อย่างแม่นยำยิ่งขึ้น: วิธี clearfix จะป้องกันการยุบขอบระหว่างผู้ปกครองและเด็กเท่านั้น มันไม่ได้ส่งผลกระทบต่อการล่มสลายระหว่างพี่น้องที่อยู่ติดกัน
NicBright

ฉันคิดว่าตอนนี้ฉันเข้าใจแนวโน้มของ Bootstrap ในการเติม DOM :beforeและ:afterองค์ประกอบต่างๆ ตอนนี้ฉันได้เพิ่มกฎนี้ลงในสไตล์ชีทของฉัน: div:before, div:after{content: ' '; display: table;}. น่าอัศจรรย์ ทันใดนั้นสิ่งต่าง ๆ เริ่มทำงานตามที่คาดไว้
Stijn de Witt

59

เคล็ดลับอย่างหนึ่งในการปิดใช้งานการยุบขอบที่ไม่มีผลกระทบต่อภาพเท่าที่ฉันรู้คือการตั้งค่าการเติมเต็มของพาเรนต์เป็น0.05px:

.parentClass {
    padding: 0.05px;
}

การซ้อนไม่มี 0 อีกต่อไปดังนั้นการยุบจะไม่เกิดขึ้นอีก แต่ในขณะเดียวกันการขยายมีขนาดเล็กพอที่จะทำให้การมองเห็นลดลงเป็น 0

หากมีช่องว่างอื่น ๆ ที่เป็นที่ต้องการแล้วใช้ช่องว่างภายในเท่านั้นที่จะ "ทิศทาง" padding-top: 0.05px;ซึ่งมีอัตรากำไรยุบไม่ได้ต้องการเช่น

ตัวอย่างการทำงาน:

.noCollapse {
  padding: 0.05px;
}

.parent {
  background-color: red;
  width: 150px;
}

.children {
  margin-top: 50px;

  background-color: lime;      
  width: 100px;
  height: 100px;
}
<h3>Border collapsing</h3>
<div class="parent">
  <div class="children">
  </div>
</div>

<h3>No border collapsing</h3>
<div class="parent noCollapse">
  <div class="children">
  </div>
</div>

แก้ไข:เปลี่ยนค่าจากไป0.1 0.05ดังที่คริสมอร์แกนพูดถึงในคอมเมนต์เบลล์และจากการทดสอบขนาดเล็กนี้ดูเหมือนว่าแน่นอนว่า Firefox จะ0.1pxคำนึงถึงการพิจารณา แม้ว่า0.05pxดูเหมือนจะทำเคล็ดลับ


2
นี่คือทางออกที่ฉันโปรดปราน คุณสามารถรวมสิ่งนี้เป็นสไตล์เริ่มต้นได้ ทำไมจะไม่ล่ะ? *{padding-top:0.1px}. เราแน่ใจว่าใช้ได้กับเบราว์เซอร์ทั้งหมดหรือไม่
Nick Manning

ทำงานได้ค่อนข้างดีสำหรับฉัน แต่ฉันไม่ได้อ้างว่าได้ทำการทดสอบอย่างละเอียดในเบราว์เซอร์ส่วนใหญ่
Nicu Surdu

2
ทางออกที่ดีมากดูเหมือนว่าจะทำงานได้ตามที่คาดหวังในเบราว์เซอร์ส่วนใหญ่ ขอบคุณสำหรับการแบ่งปัน!
wiredolphin

1
นี่เป็นวิธีการหลบซึ่งจะเพิ่มพิกเซลพิเศษในสถานการณ์ต่าง ๆ เนื่องจากการแสดง DPI สูงและการคำนวณพิกเซลย่อย (Firefox ทำเลย์เอาท์พิกเซลย่อยสำหรับทุกวัยฉันเชื่อว่าเบราว์เซอร์อื่น ๆ มีชุดสูทที่ติดตามมาไม่นานนี้)
Chris Morgan

0.05px0.01pxดูเหมือนว่ายังคงเหมือนทางเลือกที่เฉพาะเจาะจงไม่ได้เป็นจำนวนเบราว์เซอร์กลอุบายสุ่มฉันไม่ต้องการ
Volker E.

22

overflow:hidden ป้องกันการยุบของขอบ แต่มันไม่มีผลข้างเคียง - นั่นคือ ... ซ่อนล้น

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


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

7
overflow: autoเป็นสิ่งที่ดีที่จะใช้เพื่อป้องกันการล้นที่ซ่อนอยู่และยังคงป้องกันการยุบขอบ
Gavin

@Gavin overflow:auto;ทำให้พื้นที่เนื้อหาของฉันได้รับแถบเลื่อนในบางหน้า
รีด

13

จริงๆแล้วมีสิ่งหนึ่งที่ทำงานได้อย่างไร้ที่ติ:

แสดงผล: ดิ้น; ดิ้นทิศทาง: คอลัมน์;

ตราบใดที่คุณสามารถอยู่ได้ด้วยการรองรับ IE10 ขึ้นไป

.container {
  display: flex;
  flex-direction: column;
    background: #ddd;
    width: 15em;
}

.square {
    margin: 15px;
    height: 3em;
    background: yellow;
}
<div class="container">
    <div class="square"></div>
    <div class="square"></div>
    <div class="square"></div>
</div>
<div class="container">
    <div class="square"></div>
    <div class="square"></div>
    <div class="square"></div>
</div>


เพื่อให้การทำงานเป็นโซลูชันทั่วไปต้องเพิ่มส่วนเพิ่มเติม<div>ภายใน.containerมิฉะนั้น.containerจะควบคุมโมเดลกล่องของลูก ตัวอย่างเช่นองค์ประกอบแบบอินไลน์จะกลายเป็นองค์ประกอบบล็อกแบบเต็มความกว้าง หากพวกเขามีอัตรากำไรขั้นต้นเหล่านั้นก็จะถูกยุบขอบ
zupa

9

ทุกเบราว์เซอร์ WebKit -webkit-margin-collapseตามควรสนับสนุนคุณสมบัติ นอกจากนี้ยังมีคุณสมบัติย่อยเพื่อตั้งค่าเฉพาะสำหรับระยะขอบด้านบนหรือด้านล่าง คุณสามารถให้ค่ายุบ (ค่าเริ่มต้น), ทิ้ง (ตั้งค่าระยะขอบเป็น 0 หากมีระยะขอบใกล้เคียง) และแยก (ป้องกันการยุบขอบ)

ฉันได้ทำการทดสอบแล้วว่าใช้งานได้กับ Chrome และ Safari เวอร์ชัน 2014 น่าเสียดายที่ฉันไม่คิดว่าจะรองรับ IE เพราะมันไม่ได้อยู่บนเว็บคิต

อ่านการอ้างอิง Safari Safari ของ Appleสำหรับคำอธิบายแบบเต็ม

หากคุณตรวจสอบหน้าส่วนขยาย CSS webkit ของ Mozillaพวกเขาจะแสดงรายการคุณสมบัติเหล่านี้ว่าเป็นกรรมสิทธิ์และไม่แนะนำให้ใช้ นี่เป็นเพราะพวกเขามีแนวโน้มที่จะไม่เข้าสู่ CSS มาตรฐานทุกเวลาเร็ว ๆ นี้และมีเพียงเบราว์เซอร์ที่ใช้ webkit เท่านั้นที่จะสนับสนุนพวกเขา


นี่เป็นสิ่งที่ดีเพราะมันช่วยให้เรารีดความไม่ลงรอยกันในวิธีที่ Safari และ Chrome จัดการกับระยะขอบ
bjudson

8

ฉันรู้ว่านี่เป็นโพสต์ที่เก่ามาก แต่แค่อยากจะบอกว่าการใช้ flexbox ในองค์ประกอบหลักจะปิดใช้งานการยุบขอบสำหรับองค์ประกอบย่อย


ไม่เพียง แต่สำหรับองค์ประกอบลูก - มันยังป้องกันการยุบขอบระหว่างผู้ปกครองและลูกคนแรกและลูกคนสุดท้าย
Sven Marnach

2

ฉันมีปัญหาที่คล้ายกันกับการยุบขอบเนื่องจากผู้ปกครองpositionตั้งค่าให้ญาติ นี่คือรายการคำสั่งที่คุณสามารถใช้เพื่อปิดใช้งานการยุบขอบ

นี่คือสนามเด็กเล่นเพื่อทดสอบ

เพียงแค่พยายามที่จะกำหนดใด ๆparent-fix*ชั้นdiv.containerองค์ประกอบหรือระดับใดเพื่อchildren-fix* div.marginเลือกหนึ่งที่เหมาะกับความต้องการของคุณที่สุด

เมื่อไหร่

  • การยุบขอบถูกปิดใช้งานโดยdiv.absoluteมีพื้นหลังสีแดงจะถูกวางตำแหน่งที่ด้านบนสุดของหน้า
  • ระยะขอบกำลังยุบ div.absoluteจะถูกวางตำแหน่งที่พิกัด Y เดียวกันกับdiv.margin

html, body { margin: 0; padding: 0; }

.container {
  width: 100%;
  position: relative;
}

.absolute {
  position: absolute;
  top: 0;
  left: 50px;
  right: 50px;
  height: 100px;
  border: 5px solid #F00;
  background-color: rgba(255, 0, 0, 0.5);
}

.margin {
  width: 100%;
  height: 20px;
  background-color: #444;
  margin-top: 50px;
  color: #FFF;
}

/* Here are some examples on how to disable margin 
   collapsing from within parent (.container) */
.parent-fix1 { padding-top: 1px; }
.parent-fix2 { border: 1px solid rgba(0,0,0, 0);}
.parent-fix3 { overflow: auto;}
.parent-fix4 { float: left;}
.parent-fix5 { display: inline-block; }
.parent-fix6 { position: absolute; }
.parent-fix7 { display: flex; }
.parent-fix8 { -webkit-margin-collapse: separate; }
.parent-fix9:before {  content: ' '; display: table; }

/* Here are some examples on how to disable margin 
   collapsing from within children (.margin) */
.children-fix1 { float: left; }
.children-fix2 { display: inline-block; }
<div class="container parent-fix1">
  <div class="margin children-fix">margin</div>
  <div class="absolute"></div>
</div>

นี่คือjsFiddleพร้อมตัวอย่างที่คุณสามารถแก้ไขได้


1

ในเบราว์เซอร์รุ่นใหม่ (ไม่รวม IE11) display: flow-rootวิธีง่ายๆเพื่อป้องกันไม่ให้อัตรากำไรขั้นต้นผู้ปกครองเด็กยุบคือการใช้งาน อย่างไรก็ตามคุณยังคงต้องการเทคนิคอื่น ๆ เพื่อป้องกันการยุบองค์ประกอบที่อยู่ติดกัน

DEMO (ก่อนหน้า)

.parent {
  background-color: grey;
}

.child {
  height: 16px;
  margin-top: 16px;
  margin-bottom: 16px;
  background-color: blue;
}
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>

DEMO (หลัง)

.parent {
  display: flow-root;
  background-color: grey;
}

.child {
  height: 16px;
  margin-top: 16px;
  margin-bottom: 16px;
  background-color: blue;
}
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>


0

สำหรับข้อมูลของคุณคุณสามารถใช้กริด แต่มีผลข้างเคียง :)

.parent {
  display: grid
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.