Margin-Top ดัน div ด้านนอกลง


126

ฉันมี div ส่วนหัวเป็นองค์ประกอบแรกใน wrapper div ของฉัน แต่เมื่อฉันเพิ่มระยะขอบบนลงใน h1 ภายในส่วนหัว div มันจะดันส่วนหัวทั้งหมด div ลง ฉันตระหนักดีว่าสิ่งนี้เกิดขึ้นเมื่อใดก็ตามที่ฉันใช้ระยะขอบบนกับองค์ประกอบแรกที่มองเห็นได้บนหน้า

นี่คือตัวอย่างข้อมูลโค้ด ขอบคุณ!

div#header{
	width: 100%;
	background-color: #eee;
	position: relative;
}

div#header h1{
	text-align: center;
	width: 375px;
	height: 50px;
	margin: 50px auto;
	font-size: 220%;
	background: url('../../images/name_logo.png') no-repeat;
}
<div id="header">
	<h1>Title</h1>
	<ul id="navbar"></ul>
</div>

คำตอบ:


194

ใส่overflow:autoผู้ปกครองdiv
ดูเพิ่มเติมในลิงค์นี้


29
overflow:hiddenดีกว่าสำหรับ 90% ของกรณี
vsync

1
ทำไมล้น: ซ่อนไว้ดีกว่า
peterchon

5
@peterchon - เนื่องจากรถยนต์สามารถทำให้เกิดแถบเลื่อนได้
vsync

3
ไม่ทำงานอีกต่อไปคำตอบโดย @ SW4 ในลิงค์นี้ดีกว่า
am05mhz

1
overflow: hiddenหรือoverflow: autoอาจทำให้เกิดผลข้างเคียงที่ไม่ต้องการซึ่งบางอย่างคุณอาจไม่เห็นตั้งแต่แรกเห็น ฉันพบว่าการเปลี่ยนmarginเป็นการpaddingทำเคล็ดลับตามที่คำตอบด้านล่างแนะนำ ยังไม่เข้าใจว่าทำไมปัญหาทั้งหมดถึงเกิดขึ้น
Gilad Barner

34

ฉันไม่ได้มีคำอธิบายที่เป็นของแข็งที่ว่าทำไมเกิดเหตุการณ์นี้ แต่ฉันคงนี้โดยการเปลี่ยนtop-marginไปtop-paddingหรือเพิ่มdisplay: inline-blockรูปแบบองค์ประกอบ

แก้ไข: นี่คือทฤษฎีของฉัน

ฉันมีความรู้สึกว่ามันเกี่ยวข้องกับการยุบระยะขอบอย่างไร (รวมกัน)

จากW3C Collapsing Margins :

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

ทฤษฎีของฉันคือว่าตั้งแต่องค์ประกอบแรกของคุณคือติดกับร่างกายทั้งสองอัตรากำไรขั้นต้นรวมและถูกนำมาใช้กับร่างกาย: กองกำลังนี้เนื้อหาของร่างกายในการเริ่มต้นดังต่อไปนี้นำไปใช้อัตรากำไรทรุดตัวลงในการปฏิบัติตามรูปแบบกล่อง

มีสถานการณ์ที่ระยะขอบไม่ยุบซึ่งอาจคุ้มค่าที่จะเล่นด้วย (จากCollapsing Margins ):

* floated elements
* absolutely positioned elements
* inline-block elements
* elements with overflow set to anything other than visible (They do not collapse margins with their children.)
* cleared elements (They do not collapse their top margins with their parent block’s bottom margin.)
* the root element

3
นอกจากนี้การเว้นระยะห่างหรือขอบบนองค์ประกอบที่มีระยะขอบยุบ (ด้านใน) จะยกเลิกการยุบ
ไม่ระบุชื่อ

สิ่งนี้ใช้ได้ผลสำหรับฉัน - ฉันมีองค์ประกอบที่แน่นอน (รายการแบบเลื่อนลง) ในคอนเทนเนอร์ของฉันดังนั้นล้น: อัตโนมัติไม่ทำงาน
mwilcox

17

นี่คือบางวิธีในการหลีกเลี่ยงการยุบระยะขอบระหว่างองค์ประกอบแม่ลูก ใช้แบบที่เหมาะกับสไตล์อื่น ๆ ของคุณ:

  • ตั้งค่าdisplayเป็นอื่นที่ไม่ใช่block.
  • ตั้งค่าfloatเป็นอื่นที่ไม่ใช่none.
  • paddingลบขอบและใช้แทน ตัวอย่างเช่นถ้าคุณมีแทนที่ด้วยmargin-top: 10pxpadding-top: 10px;
  • ลบขอบและใช้แทนposition( absoluteหรือrelative) ที่มีคุณลักษณะtop, bottomฯลฯ ตัวอย่างเช่นถ้าคุณมีแทนที่ด้วยmargin-top: 10pxposition: relative; top: 10px;
  • เพิ่ม a paddingหรือborderในด้านที่ระยะขอบยุบลงในองค์ประกอบหลัก เส้นขอบสามารถมีขนาด 1px และโปร่งใสได้
  • ตั้งค่าเป็นองค์ประกอบoverflowอื่นที่ไม่ใช่องค์ประกอบหลักvisible

5

ฉันรู้ว่านี่เป็นปัญหาเก่าฉันเจอมาหลายครั้งแล้ว ปัญหาคือการแก้ไขทั้งหมดที่นี่คือการแฮ็กที่อาจส่งผลที่ไม่คาดคิด

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

<div>
    <h1>Test</h1>
</div>

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

ดังนั้นจึงมีวิธีแก้ไขที่ง่ายโดยไม่ต้องใช้แฮ็กแปลก ๆ เหมือนที่โพสต์ส่วนใหญ่ทำ (ไม่มีเจตนาดูถูก แต่เป็นความจริง) เพียงกลับไปที่คำอธิบายเดิม - ...if the first element inside a container has a top margin...- หลังจากนั้นคุณจึงต้อง องค์ประกอบแรกในคอนเทนเนอร์ที่ไม่มีขอบด้านบน โอเค แต่คุณจะทำได้อย่างไรโดยไม่ต้องเพิ่มองค์ประกอบที่ไม่รบกวนความหมายกับเอกสารของคุณ

ง่าย! หลอกองค์ประกอบ! คุณสามารถทำได้ผ่านคลาสหรือมิกซ์อินที่กำหนดไว้ล่วงหน้า เพิ่ม:beforeองค์ประกอบหลอก:

CSS ผ่านคลาส:

.top-margin-fix:before {   
    content: ' ';
    display: block;
    width: 100%;
    height: .0000001em;
}

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

<div class="top-margin-fix">
    <h1>Test</h1>
</div>

ทำไมถึงได้ผล?

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

ถามทำไมความสูง: .0000001em?

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

ตอนนี้คุณสามารถเพิ่มคลาส (หรือดีกว่าใน SASS / LESS, mixin!) เพื่อแก้ไขปัญหานี้แทนที่จะเพิ่มรูปแบบการแสดงแปลก ๆ ที่จะทำให้เกิดผลที่ไม่คาดคิดเมื่อคุณต้องการทำสิ่งอื่น ๆ กับองค์ประกอบของคุณโดยมีจุดประสงค์เพื่อกำจัดระยะขอบขององค์ประกอบ และ / หรือแทนที่ด้วยช่องว่างภายในหรือรูปแบบตำแหน่ง / ลอยแปลก ๆ ซึ่งไม่ได้มีจุดประสงค์เพื่อแก้ไขปัญหานี้จริงๆ


2
.0000001em ได้รับการปัดเศษเป็นศูนย์ใน IE11 ซึ่งจะทำลายการแก้ไขของคุณ เมื่อฉันเปลี่ยนเป็น. 01em มันใช้งานได้
Esger

1
ฉันจินตนาการว่า. 01em จะเพียงพอที่จะยังคงเป็นศูนย์ได้อย่างมีประสิทธิภาพ จุดดี. ในทางกลับกันตอนนี้มันเป็นปี 2018 พวกเราหลายคนจะเลิกรองรับ IE11 เร็ว ๆ นี้โดยเฉพาะอย่างยิ่งเมื่อมีการประกาศเมื่อเร็ว ๆ นี้ว่า MS จะสร้างเบราว์เซอร์ใหม่อีกครั้ง (ยกเว้นในครั้งนี้โดยใช้โครเมียมซึ่งหมายความว่าในทางทฤษฎี - จะไม่ดูดทั้งหมด) : D
dudewad

2

display: flexจะทำงานในกรณีนี้ ให้องค์ประกอบหลักdisplay: flex;จากนั้นให้ขอบตามความต้องการของคุณกับh1แท็ก


0

พบปัญหานี้ในวันนี้

overflow: hidden ไม่ได้ผลตามที่คาดไว้เมื่อฉันมีองค์ประกอบเพิ่มเติมตามมา

ดังนั้นฉันจึงลองเปลี่ยนคุณสมบัติการแสดงผลของ div พาเรนต์และdisplay: flexได้ผล !!!

หวังว่านี่อาจช่วยใครบางคนได้ :)


0

การเพิ่มช่องว่างในส่วนบนขององค์ประกอบหลักเล็กน้อยสามารถแก้ไขปัญหานี้ได้

.parent{
  padding-top: 0.01em;
}

สิ่งนี้มีประโยชน์หากคุณต้องการให้องค์ประกอบภายในพาเรนต์มองเห็นได้ภายนอกองค์ประกอบระดับบนสุดเช่นหากคุณกำลังสร้างเอฟเฟกต์ทับซ้อนกัน


0

สิ่งนี้เกิดขึ้นเนื่องจากขอบยุบ เมื่อองค์ประกอบลูกสัมผัสกับขอบเขตขององค์ประกอบหลักและองค์ประกอบใด ๆ ที่ใช้กับระยะขอบแล้ว:

  1. ระยะขอบที่ใหญ่ที่สุดจะเป็นผู้ชนะ (ใช้)

  2. หากคนใดคนหนึ่งมีระยะขอบทั้งสองจะมีส่วนแบ่งเท่ากัน

โซลูชั่น

  1. ใช้เส้นขอบกับผู้ปกครองซึ่งทำให้ผู้ปกครองและเด็กแยกจากกัน
  2. ใช้ช่องว่างภายในกับพาเรนต์ซึ่งทำให้ผู้ปกครองและเด็กแยกจากกัน
  3. ใช้โอเวอร์โฟลว์แทนที่จะมองเห็นได้บนพาเรนต์
  4. ใช้ก่อนหรือหลังเพื่อสร้างองค์ประกอบเสมือนใน div พาเรนต์ซึ่งอาจแตกต่างจากระยะขอบที่ใช้ลูกและพาเรนต์
  5. สร้างองค์ประกอบ html หนึ่งรายการระหว่างลูกที่ใช้มาร์จิ้นและพาเรนต์ยังสามารถแยกองค์ประกอบเหล่านั้นได้
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.