Ký quỹ trên phần tử con di chuyển phần tử cha


415

Tôi có một div( cha mẹ ) có chứa một div( con ) khác. Parent là thành phần đầu tiên bodykhông có kiểu CSS cụ thể. Khi tôi đặt

.child
{
    margin-top: 10px;
}

Kết quả cuối cùng là đầu của con tôi vẫn được liên kết với cha mẹ. Thay vì con bị dịch chuyển 10px xuống, bố mẹ tôi di chuyển xuống 10px.

Của tôi DOCTYPEđược thiết lập để XHTML Transitional.

Tôi đang thiếu gì ở đây?

chỉnh sửa 1
Cha mẹ tôi cần phải có các kích thước được xác định nghiêm ngặt bởi vì nó có nền phải được hiển thị bên dưới từ trên xuống dưới (pixel perfect). Vì vậy, thiết lập lề dọc trên đó là không nên .

chỉnh sửa 2
Hành vi này giống nhau trên FF, IE cũng như CR.


188
hành vi này không có ý nghĩa gì bao giờ. Margin được cho là ở bên trong cha mẹ. Không di chuyển cha mẹ. Ai viết những quy tắc này.
Muhammad Umer

10
+2 cho nhận xét cuối cùng. nghiêm túc quy tắc này lỗi tôi. "60% thời gian nó hoạt động mọi lúc" - đó là lợi nhuận.
Casey Dwayne

29
Tôi hoàn toàn đồng ý với hai người bình luận cuối cùng. Điều này là điên rồ. Điều thú vị là việc thêm đường viền 1px cho cha mẹ làm cho nó hoạt động đúng, tuy nhiên điều này có nghĩa là bạn có đường viền ... nếu đây là hành vi được mong đợi thì điều này thật nực cười
erdomester

1
Điều này cũng có thể giúp bạn :) stackoverflow.com/questions353337043/ Cách
Bhojendra Rauniyar

5
Điều này nhắc nhở tôi về quy tắc định cỡ hộp mặc định: " Chúng tôi cần gửi một hộp. Hộp không được lớn hơn 100cm. Chúng tôi cần 10cm đệm bên trong hộp để đảm bảo nội dung của chúng tôi không bị vỡ trong quá trình vận chuyển. cái hộp 120cm! "Thật là một trò đùa.
Nolonar

Câu trả lời:


492

Tìm thấy một sự thay thế ở các phần tử con có lề trong DIV Bạn cũng có thể thêm:

.parent { overflow: auto; }

hoặc là:

.parent { overflow: hidden; }

Điều này ngăn chặn lợi nhuận sụp đổ . Biên giới và đệm làm tương tự. Do đó, bạn cũng có thể sử dụng các cách sau để ngăn sập lề trên:

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

Cập nhật theo yêu cầu phổ biến: Toàn bộ điểm thu hẹp lợi nhuận là xử lý nội dung văn bản. Ví dụ:

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>

Vì trình duyệt thu gọn lề, văn bản sẽ xuất hiện như bạn mong đợi và các <div>thẻ trình bao bọc không ảnh hưởng đến lề. Mỗi phần tử đảm bảo nó có khoảng cách xung quanh nó, nhưng khoảng cách sẽ không được nhân đôi. Các lề của <h2><p>sẽ không cộng lại, nhưng trượt vào nhau (chúng sụp đổ). Điều tương tự cũng xảy ra đối với phần tử <p><ul>.

Đáng buồn thay, với thiết kế hiện đại, ý tưởng này có thể cắn bạn khi bạn rõ ràng muốn có một container. Đây được gọi là bối cảnh định dạng khối mới trong CSS speak. Thủ thuật overflowhoặc lề sẽ cung cấp cho bạn điều đó.


41
tôi muốn biết tại sao điều này xảy ra với những gì tốt cho bất cứ ai. Tình huống này 'tính năng' có nghĩa là gì.
Muhammad Umer

2
@MuhammadUmer, điều này có liên quan đến nội dung văn bản. Ví dụ, một loạt các <h2>, <p>, <ul>sẽ không có được những khoảng trống lạ hoặc lợi nhuận "kép" theo cách này.
vdboor 17/03/13

7
Bạn có thể cho một số ví dụ. Hãy nói rằng tôi có div làm nền. Với h1, h2 và p trong đó. Bây giờ tôi muốn di chuyển h1 xuống một chút để nó không quá gần với cạnh trên của nền div, nhưng vẫn không mở rộng phần tử h1. Tôi nghĩ rằng thêm lợi nhuận hàng đầu. Đó là điều hiển nhiên. Nhưng khi tôi làm điều đó, nền tảng vinh quang quyết định chuyển xuống cùng với nó. Làm thế nào đây là một tính năng. Làm thế nào điều này giúp khoảng cách giữa h1, h2 và p. Giúp tôi xem những gì bạn đang nói.
Muhammad Umer 17/03/13

1
Tôi đã thêm một ví dụ cho bạn
vdboor

3
tôi hy vọng nó sẽ tăng thêm lợi nhuận. sụp đổ lợi nhuận là điều khó chịu nhất trong sự nghiệp phát triển của tôi. nếu tôi đặt 2 div cạnh nhau với margin: 5px 10px;id thì 2 div 5 px từ đỉnh và 20px giữa chúng không phải là 5 px từ đỉnh và 10px giữa chúng. nếu tôi muốn 10 px giữa chúng id đã chỉ định margin: 5px 5px;. Tôi thành thật mong muốn có một quy tắc gốc mà tôi có thể đặt nó sẽ ngăn chặn tất cả sự sụp đổ lề. tôi ghét rằng tôi phải tăng gấp đôi kích thước lề trên giấy để khiến họ thực sự làm những gì tôi muốn trên màn hình. và điều hàng đầu này ... thật là một thảm họa
JL Griffin

50

Đây là hành vi bình thường (ít nhất trong số các triển khai trình duyệt). Ký quỹ không ảnh hưởng đến vị trí của trẻ liên quan đến cha mẹ của nó, trừ khi cha mẹ có phần đệm, trong trường hợp đó, hầu hết các trình duyệt sẽ thêm phần lề của con vào phần đệm của cha mẹ.

Để có được hành vi bạn muốn, bạn cần:

.child {
    margin-top: 0;
}

.parent {
    padding-top: 10px;
}

3
Thêm đường viền cho cha mẹ cũng sẽ ảnh hưởng đến lề của trẻ, hãy thử.parent {border: solid 1px;}
okw

1
Lề không thêm vào phần đệm ... nó được áp dụng riêng. Nhưng hiệu ứng hình ảnh là như nhau.
Brilliand

1
Điều gì sẽ xảy ra nếu bạn muốn có một lợi nhuận cao nhất Không thực sự là một giải pháp.
feeela

3
Giống như feeela đã nói - đây thực sự không phải là một giải pháp nếu yêu cầu mức lãi cao nhất. câu trả lời của vdboor phù hợp hơn.
Joey Morani

1
Có rất nhiều giải pháp, bạn chỉ cần đủ sáng tạo. Chúc mừng. :-)
Slasta Meltser

23

Mặc dù tất cả các câu trả lời đều khắc phục được vấn đề nhưng chúng đi kèm với sự đánh đổi / điều chỉnh / thỏa hiệp như

  • floats, Bạn phải nổi các yếu tố
  • border-top, Điều này sẽ đẩy cha mẹ xuống ít nhất 1px xuống, sau đó sẽ được điều chỉnh bằng cách giới thiệu -1pxlề cho chính phần tử cha. Điều này có thể tạo ra vấn đề khi cha mẹ đã có margin-toptrong các đơn vị tương đối.
  • padding-top, tác dụng tương tự như sử dụng border-top
  • overflow: hidden, Không thể được sử dụng khi cha mẹ sẽ hiển thị nội dung tràn, như menu thả xuống
  • overflow: auto, Giới thiệu thanh cuộn cho phần tử cha có nội dung (cố ý) tràn (như bóng hoặc hình tam giác của đầu công cụ)

Vấn đề có thể được giải quyết bằng cách sử dụng các yếu tố giả CSS3 như sau

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

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


margin-top: -1pxdường như là không cần thiết Nhưng tôi thích nó.
Flimm

3
Trên thực tế, cả hai margin-top: -1pxheight: 0dường như không cần thiết. Đã thử nghiệm trong Chrome. Nhưng giải pháp tốt nhất.
NinjaFart

Phương pháp này chủ yếu hoạt động, nhưng sẽ không tôn trọng lề dưới cho phần tử cuối cùng trong vùng chứa. Nó không phải là một sửa chữa bằng nhau để tràn: ẩn; ví dụ.
Michael Giovanni Pumo

1
@MichaelGiovanniPumo câu trả lời có thể được sửa đổi để hoạt động với lề dưới của phần tử cuối bằng cách sử dụng.parent:after...
Ejaz

Đây chắc chắn là câu trả lời chính xác nhất hiện nay. Hoạt động hoàn hảo (đặt nó trên cả sau và trước), tôi hy vọng mọi người dám di chuyển qua những người khác!
fgblomqvist


9

phần tử cha mẹ không được để trống ít nhất là đặt &nbsp;trước phần tử con.


2
có, đôi khi chỉ điều này mới có thể giúp ... hoặc tốt hơn là đặt một cái gì đó như thế này: <div style = 'width: 0; height: 0'> & nbsp; </ div>
Pigalev Pavel


2

Tôi phát hiện ra rằng, bên trong .css> nếu bạn đặt thuộc tính hiển thị của phần tử div thành khối nội tuyến thì nó sẽ khắc phục được sự cố. và ký quỹ sẽ hoạt động như mong đợi.


2

Giải pháp chỉ gọn gàng CSS

Sử dụng mã sau đây để thêm một đứa con đầu tiên không có nội dung vào div di chuyển không chủ ý:

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

Ưu điểm của phương pháp này là bạn không cần thay đổi CSS của bất kỳ yếu tố hiện có nào và do đó có tác động tối thiểu đến thiết kế. Bên cạnh đó, phần tử được thêm vào là phần tử giả, không có trong cây DOM.

Hỗ trợ cho các phần tử giả được phổ biến rộng rãi: Firefox 3+, Safari 3+, Chrome 3+, Opera 10+ và IE 8+. Điều này sẽ hoạt động trong bất kỳ trình duyệt hiện đại nào (hãy cẩn thận với trình duyệt mới hơn ::before, không được hỗ trợ trong IE8).

Bối cảnh

Nếu con đầu tiên của một phần tử có a margin-top, cha mẹ sẽ điều chỉnh vị trí của nó như một cách thu gọn các lề dư thừa. Tại sao? Chỉ như vậy thôi.

Đưa ra vấn đề sau:

<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>

Bạn có thể sửa nó bằng cách thêm một đứa trẻ có nội dung, chẳng hạn như một không gian đơn giản. Nhưng tất cả chúng ta đều ghét thêm không gian cho vấn đề chỉ thiết kế. Do đó, sử dụng white-spacetài sản để nội dung giả mạo.

<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>

Trường hợp position: relative;đảm bảo định vị chính xác của sửa chữa. Và white-space: pre;làm cho bạn không phải thêm bất kỳ nội dung nào - như khoảng trắng - vào bản sửa lỗi. Và height: 0px;width: 0px;overflow: hidden;chắc chắn rằng bạn sẽ không bao giờ thấy sửa chữa.

Bạn có thể cần thêm line-height: 0px;hoặc max-height: 0px;để đảm bảo chiều cao thực sự bằng không trong các trình duyệt IE cổ (tôi không chắc chắn). Và tùy chọn bạn có thể thêm <!--dummy-->nó vào các trình duyệt IE cũ, nếu nó không hoạt động.

Nói tóm lại, bạn có thể thực hiện tất cả điều này chỉ với CSS (loại bỏ nhu cầu thêm một đứa trẻ thực sự vào cây DOM DOM):

<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>

Chỉ sử dụng giải pháp này nếu bạn tuyệt vọng và bạn không thể đặt bất kỳ CSS tùy chỉnh nào cho các thành phần hiện có - nếu không hãy sử dụng giải pháp thực tế: đặt overflow: hidden;cho cha mẹ.
Yeti

2

Để ngăn "Div cha" sử dụng lề của "div con":
Trong cha mẹ sử dụng các css này:

  • Phao nổi
  • Đệm
  • Biên giới
  • Tràn ra

1

Các marginyếu tố chứa trong .childđang sụp đổ.

<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>

Trong ví dụ này, pđang nhận được margintừ các kiểu mặc định của trình duyệt. Trình duyệt mặc định font-sizethường là 16px. Bằng cách có margin-tophơn 16px, #childbạn bắt đầu nhận thấy vị trí của nó di chuyển.


1

Tôi cũng gặp vấn đề này nhưng thích ngăn chặn các vụ hack lợi nhuận âm, vì vậy tôi đặt một

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

xung quanh nó tất cả có miếng đệm thay vì lề. Tất nhiên điều này có nghĩa là viêm nhiều hơn nhưng có lẽ đó là cách sạch nhất để thực hiện điều này đúng cách.


1

thú vị là giải pháp yêu thích của tôi cho vấn đề này chưa được đề cập ở đây: sử dụng phao.

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;}

xem nó ở đây: http://codepen.io/anon/pen/Iphol

lưu ý rằng trong trường hợp bạn cần chiều cao động trên cha mẹ, nó cũng phải nổi, vì vậy chỉ cần thay thế height:100px;bằngfloat:left;


1

Một giải pháp thay thế tôi tìm thấy trước khi tôi biết câu trả lời chính xác là thêm đường viền trong suốt vào phần tử cha.

Hộp của bạn sẽ sử dụng thêm pixel mặc dù ...

.parent {
    border:1px solid transparent;
}

0

Sử dụng topthay vì margin-toplà một giải pháp có thể, nếu thích hợp.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.