อัตรากำไรขั้นต้นในองค์ประกอบลูกย้ายองค์ประกอบหลัก


414

ฉันมีdiv( ผู้ปกครอง ) ที่มีอีกdiv( เด็ก ) Parent เป็นองค์ประกอบแรกที่bodyไม่มีสไตล์ CSS เฉพาะ เมื่อฉันตั้ง

.child
{
    margin-top: 10px;
}

ผลลัพธ์ที่ได้คือด้านบนของลูกของฉันยังคงสอดคล้องกับผู้ปกครอง แทนที่จะเป็นลูกที่ถูกเลื่อนลง 10px ผู้ปกครองของฉันขยับลง 10px

ฉันมีการตั้งค่าDOCTYPEXHTML Transitional

ฉันหายไปนี่อะไร

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

แก้ไข 2
พฤติกรรมนี้เหมือนกันบน FF, IE และ CR


188
พฤติกรรมนี้ไม่สมเหตุสมผลเลย มาร์จิ้นควรจะอยู่ข้างในพ่อแม่ ไม่ย้ายผู้ปกครอง ใครเป็นคนเขียนกฎเหล่านี้
มูฮัมหมัดอูเมอ

10
+2 สำหรับความคิดเห็นล่าสุด กฎข้อนี้อย่างจริงจังข้อบกพร่องฉัน "60% ของเวลาทำงานทุกครั้ง" - ระยะขอบนั่น
Casey Dwayne

29
ฉันเห็นด้วยกับผู้วิจารณ์ทั้งสองคนโดยสิ้นเชิง นี่มันบ้า มีอะไรที่น่าสนใจคือการเพิ่มเส้นขอบ 1px ไปยังผู้ปกครองที่ทำให้มันทำงานได้ถูกต้อง แต่วิธีการนี้คุณต้องชายแดน ... ถ้านี้เป็นพฤติกรรมที่คาดหวังแล้วนี้เป็นเรื่องน่าขัน
erdomester

1
สิ่งนี้อาจช่วยคุณได้เช่นกัน :) stackoverflow.com/questions/35337043/…
Bhojendra Rauniyar

5
สิ่งนี้ทำให้ฉันนึกถึงกฎการกำหนดขนาดกล่องเริ่มต้น: " เราจำเป็นต้องจัดส่งกล่องกล่องต้องไม่ใหญ่กว่า 100 ซม. เราต้องการช่องว่างภายใน 10 ซม. ภายในกล่องเพื่อให้แน่ใจว่าเนื้อหาของเราจะไม่แตกระหว่างการจัดส่ง กล่อง 120 ซม.! "เป็นเรื่องตลก
Nolonar

คำตอบ:


492

พบทางเลือกที่องค์ประกอบเด็กที่มีระยะขอบภายใน DIVคุณยังสามารถเพิ่ม:

.parent { overflow: auto; }

หรือ:

.parent { overflow: hidden; }

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

.parent {
    padding-top: 1px;
    margin-top: -1px;
}

อัปเดตตามคำขอยอดนิยม: จุดจบของการยุบทั้งหมดคือการจัดการเนื้อหาที่เป็นข้อความ ตัวอย่างเช่น:

h1, h2, p, ul {
  margin-top: 1em;
  margin-bottom: 1em;
}
<h1>Title!</h1>
<div class="text">
  <h2>Title!</h2>
  <p>Paragraph</p>
</div>
<div class="text">
  <h2>Title!</h2>
  <p>Paragraph</p>
  <ul>
    <li>list item</li>
  </ul>
</div>

เนื่องจากเบราว์เซอร์ยุบระยะขอบข้อความจะปรากฏตามที่คุณคาดหวังและ<div>แท็กตัวตัดคำจะไม่ส่งผลต่อระยะขอบ แต่ละองค์ประกอบทำให้แน่ใจว่ามันมีระยะห่างรอบตัว แต่ระยะห่างจะไม่เพิ่มเป็นสองเท่า ระยะขอบของ<h2>และ<p>จะไม่เพิ่มขึ้น แต่เลื่อนเข้าหากัน (ยุบลง) สิ่งเดียวกันนี้เกิดขึ้นกับองค์ประกอบ<p>และ<ul>

น่าเศร้าด้วยการออกแบบที่ทันสมัยความคิดนี้สามารถกัดคุณเมื่อคุณต้องการภาชนะบรรจุอย่างชัดเจน สิ่งนี้เรียกว่าบริบทการจัดรูปแบบบล็อกใหม่ใน CSS speak overflowหรือเคล็ดลับขอบจะให้คุณทราบว่า


41
ฉันอยากรู้ว่าทำไมสิ่งนี้ถึงเกิดขึ้นได้ดีกับทุกคน สถานการณ์นี้ 'คุณสมบัติ' หมายถึงอะไร
มูฮัมหมัดอูเมอ

2
@ MuhammadUmer, สิ่งนี้เกี่ยวข้องกับเนื้อหาข้อความ ตัวอย่างเช่นชุดของ<h2>, <p>, <ul>จะไม่ได้รับช่องว่างที่แปลกหรือ "คู่" อัตรากำไรด้วยวิธีนี้
vdboor

7
คุณยกตัวอย่างได้บ้าง สมมติว่าฉันมี div เป็นพื้นหลัง ด้วย h1, h2 และ p ในนั้น ตอนนี้ฉันต้องการเลื่อน h1 ลงเล็กน้อยดังนั้นมันจึงไม่ใกล้กับขอบด้านบนของ div พื้นหลัง แต่ยังไม่ขยายองค์ประกอบ h1 ฉันคิดว่าจะเพิ่มกำไรขั้นต้น ซึ่งมีความชัดเจน แต่เมื่อฉันทำอย่างนั้นภูมิหลังอันรุ่งโรจน์ตัดสินใจที่จะย้ายลงไปด้วย คุณลักษณะนี้เป็นอย่างไร วิธีนี้ช่วยในการเว้นวรรคระหว่าง h1, h2 และ p ช่วยฉันดูสิ่งที่คุณพูด
มูฮัมหมัดอูเมอ

1
ฉันได้เพิ่มตัวอย่างให้คุณ
vdboor

3
ฉันคาดหวังว่าจะเพิ่มระยะขอบมากขึ้น การยุบขอบคือสิ่งที่น่ารำคาญที่สุดในอาชีพการพัฒนาของฉัน หากฉันใส่ 2 divs ติดกับmargin: 5px 10px;id โดยคาดว่า 2 divs 5 px จากด้านบนและ 20px ระหว่างพวกเขาไม่ใช่ 5 px จากด้านบนและ 10px ระหว่างพวกเขา ถ้าผมต้องการ 10 px ระหว่าง id margin: 5px 5px;ของพวกเขาได้ระบุไว้ ฉันหวังว่าจะมีกฎรากที่ฉันสามารถวางที่จะหยุดการยุบทั้งหมด ฉันเกลียดที่ฉันต้องเพิ่มขนาดของระยะขอบบนกระดาษเพื่อให้พวกเขาทำสิ่งที่ฉันต้องการบนหน้าจอจริง และสิ่งที่ดีที่สุด ... สิ่งนี้เป็นหายนะ
JL Griffin

50

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

ในการรับพฤติกรรมที่คุณต้องการคุณต้อง:

.child {
    margin-top: 0;
}

.parent {
    padding-top: 10px;
}

3
การเพิ่มเส้นขอบให้กับผู้ปกครองจะส่งผลต่อระยะขอบของเด็กด้วยลอง.parent {border: solid 1px;}
okw

1
มาร์จิ้นไม่ได้เพิ่มไปยังช่องว่างภายใน ... มันใช้แยกกัน แต่เอฟเฟ็กต์ภาพเหมือนกัน
Brilliand

1
ถ้าคุณต้องการให้มีกำไรสูงสุด ... ไม่ใช่ทางออกจริงๆ
feeela

3
เช่นเดียวกับ feeela ที่กล่าวมา - นี่ไม่ใช่วิธีแก้ปัญหาหากจำเป็นต้องมีกำไรขั้นต้นสูงสุด คำตอบของ vdboor เหมาะสมกว่า
Joey Morani

1
มีวิธีแก้ปัญหามากมายคุณเพียงแค่ต้องมีความคิดสร้างสรรค์มากพอ ไชโย :-)
Slavik Meltser

23

แม้ว่าคำตอบทั้งหมดจะแก้ไขปัญหาได้ แต่พวกเขาก็มาพร้อมกับการแลกเปลี่ยน / การปรับ / การประนีประนอมเช่น

  • floatsคุณต้องลอยองค์ประกอบ
  • border-topสิ่งนี้จะผลักดันพาเรนต์อย่างน้อย 1px ลงซึ่งควรจะปรับด้วยการแนะนำมาร์-1pxจิ้นกับองค์ประกอบพาเรนต์เอง สิ่งนี้สามารถสร้างปัญหาเมื่อผู้ปกครองมีอยู่แล้วmargin-topในหน่วยที่เกี่ยวข้อง
  • padding-topผลเช่นเดียวกับการใช้ border-top
  • overflow: hiddenไม่สามารถใช้เมื่อผู้ปกครองควรแสดงเนื้อหาที่ล้นเช่นเมนูแบบเลื่อนลง
  • overflow: autoแนะนำแถบเลื่อนสำหรับองค์ประกอบพาเรนต์ที่มีเนื้อหาล้น (โดยเจตนา) (เช่นเงาหรือสามเหลี่ยมของเครื่องมือปลาย)

ปัญหาสามารถแก้ไขได้โดยใช้องค์ประกอบหลอก CSS3 ดังต่อไปนี้

.parent::before {
  clear: both;
  content: "";
  display: table;
  margin-top: -1px;
  height: 0;
}

https://jsfiddle.net/hLgbyax5/1/


margin-top: -1pxดูเหมือนจะไม่จำเป็น แต่ฉันชอบสิ่งนี้
Flimm

3
อันที่จริงทั้งสองmargin-top: -1pxและheight: 0ดูเหมือนว่าไม่จำเป็น ทดสอบใน Chrome แล้ว แต่ทางออกที่ดีที่สุด
NinjaFart

วิธีนี้ส่วนใหญ่ใช้งานได้ แต่จะไม่เคารพขอบล่างขององค์ประกอบสุดท้ายภายในคอนเทนเนอร์ มันไม่ใช่การแก้ไขอย่างล้นหลาม: ซ่อนอยู่; ตัวอย่างเช่น.
Michael Giovanni Pumo

1
@MichaelGiovanniPumo คำตอบที่สามารถปรับเปลี่ยนการทำงานกับขอบด้านล่างขององค์ประกอบสุดท้ายโดยใช้.parent:after...
Ejaz

นี่เป็นคำตอบที่ถูกต้องที่สุดในปัจจุบัน ทำงานได้อย่างไม่มีที่ติ (วางไว้ทั้งหลังและก่อนหน้า) ฉันหวังว่าผู้คนกล้าที่จะเลื่อนดูคนอื่น ๆ !
fgblomqvist


9

องค์ประกอบหลักจะต้องไม่ว่างเปล่า&nbsp;ก่อนวางองค์ประกอบย่อย


2
ใช่บางครั้งสิ่งนี้เท่านั้นที่สามารถช่วย ... หรือดีกว่าใส่อะไรเช่นนี้: <div style = 'width: 0; height: 0'> & nbsp; </div>
Pigalev Pavel


2

ฉันพบว่าภายใน. cs ของคุณ> หากคุณตั้งค่าคุณสมบัติการแสดงผลขององค์ประกอบ div ให้เป็นแบบอินไลน์บล็อกมันจะช่วยแก้ปัญหาได้ และอัตรากำไรขั้นต้นจะทำงานตามที่คาดไว้


2

แก้ไข CSS-only ให้เรียบร้อย

ใช้รหัสต่อไปนี้เพื่อเพิ่มลูกคนแรกที่ไร้เนื้อหาให้กับ div ที่ไม่ได้ตั้งใจย้าย:

.parent:before
{content: '';position: relative;height: 0px;width: 0px;overflow: hidden;white-space: pre;}

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

การสนับสนุนองค์ประกอบแบบหลอกมีการแพร่กระจายอย่างกว้างขวาง: Firefox 3+, Safari 3+, Chrome 3+, Opera 10+ และ IE 8+ สิ่งนี้จะทำงานในเบราว์เซอร์สมัยใหม่ใด ๆ (โปรดระมัดระวังกับเวอร์ชันใหม่กว่านี้::beforeซึ่งไม่รองรับใน IE8)

บริบท

ถ้าลูกคนแรกขององค์ประกอบมี margin-topผู้ปกครองจะปรับตำแหน่งของมันเป็นวิธีการยุบขอบซ้ำซ้อน ทำไม? มันเป็นอย่างนั้น

รับปัญหาต่อไปนี้:

<style type="text/css">
div {position: relative;}
.parent {background-color: #ccc;}
.child {margin-top: 40px;}
</style>

<div class="parent"><!--This div moves 40px too-->
    <div class="child">Hello world!</div>
</div>

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

<style type="text/css">
div {position: relative;}
.parent {background-color: #ccc;}
.child {margin-top: 40px;}
.fix {position: relative;white-space: pre;height: 0px;width: 0px;overflow: hidden;}
</style>

<div class="parent"><!--This div won't move anymore-->
    <div class="fix"></div>
    <div class="child">Hello world!</div>
</div>

ในกรณีที่position: relative;มั่นใจได้ว่าตำแหน่งของการแก้ไขถูกต้อง และwhite-space: pre;ทำให้คุณไม่ต้องเพิ่มเนื้อหาใด ๆ - เช่นพื้นที่สีขาว - ในการแก้ไข และheight: 0px;width: 0px;overflow: hidden;ทำให้แน่ใจว่าคุณจะไม่เห็นการแก้ไข

คุณอาจต้องเพิ่มline-height: 0px;หรือmax-height: 0px;ตรวจสอบให้แน่ใจว่าความสูงเป็นศูนย์ในเบราว์เซอร์ IE โบราณ (ฉันไม่แน่ใจ) และเป็นทางเลือกคุณสามารถเพิ่มลง<!--dummy-->ในเบราว์เซอร์ IE รุ่นเก่าถ้ามันไม่ทำงาน

ในระยะสั้นคุณสามารถทำสิ่งนี้ได้ด้วย CSS เท่านั้น (ซึ่งไม่จำเป็นต้องเพิ่มลูกที่แท้จริงลงใน HTML DOM-tree):

<style type="text/css">
div {position: relative;}
.parent {background-color: #ccc;}
.child {margin-top: 40px;}

.parent:before {content: '';position: relative;height: 0px;width: 0px;overflow: hidden;white-space: pre;}
</style>

<div class="parent"><!--This div won't move anymore-->
    <div class="child">Hello world!</div>
</div>

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


1

marginขององค์ประกอบที่มีอยู่ภายใน.childจะถูกยุบ

<html>
<style type="text/css" media="screen">
    #parent {background:#dadada;}
    #child {background:red; margin-top:17px;}
</style>
<body>
<div id="parent">

    <p>&amp;</p>

    <div id="child">
        <p>&amp;</p>    
    </div>

</div>
</body>
</html>

ในตัวอย่างนี้pกำลังรับ a marginจากสไตล์เริ่มต้นของเบราว์เซอร์ เบราว์เซอร์เริ่มต้นfont-sizeคือ 16px โดยทั่วไป ด้วยการมีmargin-topมากกว่า 16px เมื่อ#childคุณเริ่มสังเกตเห็นว่ามันเป็นการย้ายตำแหน่ง


1

ฉันมีปัญหานี้เช่นกัน แต่ต้องการป้องกันการแฮ็กระยะขอบติดลบดังนั้นฉันจึงใส่

<div class="supercontainer"></div>

รอบ ๆ มันทั้งหมดที่มีช่องว่างภายในแทนที่จะเป็นระยะขอบ แน่นอนว่านี่หมายถึงการอักเสบมากขึ้น แต่อาจเป็นวิธีที่สะอาดที่สุดในการทำสิ่งนี้ให้ถูกต้อง


1

ที่น่าสนใจวิธีแก้ปัญหาโปรดของฉันยังไม่ได้กล่าวถึงที่นี่: ใช้ลอย

HTML:

<div class="parent">
    <div class="child"></div>
</div>

CSS:

.parent{width:100px; height:100px;}
.child{float:left; margin-top:20px; width:50px; height:50px;}

ดูที่นี่: http://codepen.io/anon/pen/Iphol

โปรดทราบว่าในกรณีที่คุณต้องการความสูงแบบไดนามิกบนพาเรนต์มันก็ต้องลอยเช่นกันดังนั้นแทนที่height:100px;ด้วยfloat:left;


1

ทางเลือกที่ฉันพบก่อนที่ฉันจะรู้คำตอบที่ถูกต้องคือการเพิ่มเส้นขอบโปร่งใสให้กับองค์ประกอบหลัก

กล่องของคุณจะใช้พิกเซลพิเศษแม้ว่า ...

.parent {
    border:1px solid transparent;
}

0

การใช้topแทนที่จะmargin-topเป็นวิธีแก้ปัญหาอื่นที่เหมาะสมหากเหมาะสม

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