Margin-Top đẩy div bên ngoài xuống


126

Tôi có một div tiêu đề là thành phần đầu tiên trong div trình bao bọc của mình, nhưng khi tôi thêm lề trên vào h1 bên trong div tiêu đề, nó sẽ đẩy toàn bộ div tiêu đề xuống. Tôi nhận ra điều này xảy ra bất cứ khi nào tôi áp dụng lề trên cho phần tử hiển thị đầu tiên trên trang.

Đây là một đoạn mã mẫu. Cảm ơn!

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>

Câu trả lời:


193

đưa overflow:autovào phụ huynh div
xem thêm trong liên kết này


29
overflow:hiddenlà tốt hơn cho 90% các trường hợp.
vsync

1
Tại sao sẽ tràn: ẩn sẽ tốt hơn?
peterchon

5
@peterchon - vì tự động có thể gây ra thanh cuộn
vsync

3
không hoạt động nữa, câu trả lời của @ SW4 trong liên kết này tốt hơn
am05mhz

1
overflow: hiddenhoặc overflow: autocó thể gây ra tác dụng phụ không mong muốn, một số trong đó bạn có thể không nhìn thấy từ cái nhìn đầu tiên. Tôi đã thấy rằng việc thay đổi marginđể paddingthực hiện mánh khóe, như câu trả lời dưới đây cho thấy. Tuy nhiên, vẫn không hiểu tại sao toàn bộ vấn đề xảy ra.
Gilad Barner

34

Tôi không có một lời giải thích chắc chắn về lý do tại sao điều này xảy ra, nhưng tôi đã sửa nó bằng cách thay đổi top-margin để top-padding, hoặc thêm display: inline-blockvào phong cách phần tử.

EDIT: Đây là lý thuyết của tôi

Tôi có cảm giác nó có liên quan đến cách thu hẹp lợi nhuận (kết hợp).

từ lề thu hẹp W3C :

Trong đặc điểm kỹ thuật này, các lề thu gọn biểu thức có nghĩa là các lề liền kề (không có nội dung không trống, phần đệm hoặc vùng biên hoặc giải phóng chúng tách biệt) của hai hoặc nhiều hộp (có thể nằm cạnh nhau hoặc lồng nhau) kết hợp để tạo thành một lề duy nhất .

Lý thuyết của tôi là vì yếu tố đầu tiên của bạn nằm cạnh cơ thể, hai lề kết hợp và được áp dụng cho cơ thể: điều này buộc nội dung của cơ thể bắt đầu bên dưới lề bị sụp đổ được áp dụng theo mô hình hộp .

Có những tình huống mà các lề không sụp đổ có thể đáng để chơi xung quanh (từ Thu gọn lề ):

* 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
Ngoài ra, phần đệm hoặc đường viền trên phần tử có lề bị sập (phần bên trong) sẽ hủy bỏ phần tử đó.
Ẩn danh

Điều này làm việc cho tôi - Tôi có các yếu tố tuyệt đối (thả xuống) trong thùng chứa của mình, vì vậy, tràn: tự động không hoạt động.
mwilcox

17

Đây là một số cách để tránh sụp đổ lề giữa các yếu tố cha-con. Sử dụng một trong những phù hợp hơn với phần còn lại của phong cách của bạn:

  • Đặt displaythành khácblock .
  • Đặt floatthành khácnone .
  • Xóa lề và sử dụng thay thế padding. Ví dụ nếu bạn có margin-top: 10px, thay thế bằngpadding-top: 10px; .
  • Di chuyển bên lề, và sử dụng thay vì position( absolutehoặc relative) với các thuộc tính top, bottomvv Ví dụ, nếu bạn có margin-top: 10px, thay thế với position: relative; top: 10px;.
  • Thêm một paddinghoặc một borderbên trong đó các lề được thu gọn, vào phần tử cha . Đường viền có thể là 1px và trong suốt.
  • Đặt overflowđể khác hơn là visibleđể các mẹ phần tử.

5

Tôi biết đây là một vấn đề cũ, tôi đã gặp nó nhiều lần. Vấn đề là tất cả các bản sửa lỗi ở đây là các bản hack có khả năng gây ra hậu quả không lường trước được.

Trước hết, có một lời giải thích dễ dàng cho vấn đề gốc. Do cách thức thu gọn lề hoạt động, nếu phần tử đầu tiên bên trong một container có lề trên, thì lề trên đó được áp dụng hiệu quả cho chính vùng chứa chính. Bạn có thể tự kiểm tra điều này bằng cách làm như sau:

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

Trong trình gỡ lỗi, mở cái này lên và di chuyển div. Bạn sẽ nhận thấy rằng chính div thực sự được đặt ở nơi lề trên của phần tử H1 dừng lại . Hành vi này được dự định bởi trình duyệt.

Vì vậy, có một cách khắc phục dễ dàng cho vấn đề này mà không cần phải dùng đến các bản hack lạ, vì hầu hết các bài đăng ở đây đều làm (không có ý xúc phạm, đó chỉ là sự thật) - chỉ cần quay lại giải thích ban đầu - ...if the first element inside a container has a top margin...- Theo đó, bạn sẽ cần phần tử đầu tiên trong một thùng chứa KHÔNG có lề trên. Được rồi, nhưng làm thế nào để bạn làm điều đó mà không thêm các yếu tố không can thiệp vào ngữ nghĩa với tài liệu của bạn?

Dễ dàng! Yếu tố giả! Bạn có thể làm điều này thông qua một lớp hoặc một mixin được xác định trước. Thêm một :beforeyếu tố giả:

CSS thông qua một lớp:

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

Với điều này, theo ví dụ đánh dấu ở trên, bạn sẽ sửa đổi div của mình như sau:

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

Tại sao điều này làm việc?

Phần tử đầu tiên trong một thùng chứa, nếu nó không có lề trên, đặt vị trí bắt đầu của lề trên của phần tử tiếp theo. Bằng cách thêm một :beforeyếu tố giả, trình duyệt thực sự thêm một yếu tố phi ngữ nghĩa (nói cách khác là tốt cho SEO) vào thùng chứa cha trước đó phần tử đầu tiên của bạn.

Q. Tại sao chiều cao: .0000001em?

A. Cần có chiều cao để trình duyệt đẩy phần tử lề xuống. Chiều cao này thực sự bằng không, nhưng nó vẫn sẽ cho phép bạn thêm phần đệm vào chính vùng chứa chính. Vì nó thực sự bằng không, nên nó cũng không ảnh hưởng đến cách bố trí của container. Xinh đẹp.

Bây giờ bạn có thể thêm một lớp (hoặc tốt hơn, trong SASS / LESS, mixin!) Để khắc phục sự cố này thay vì thêm các kiểu hiển thị lạ sẽ gây ra hậu quả không mong muốn khi bạn muốn làm những việc khác với các phần tử của mình, cố tình loại bỏ lề trên các phần tử và / hoặc thay thế nó bằng phần đệm, hoặc các kiểu vị trí / hình nổi lạ thực sự không có ý định giải quyết vấn đề này.


2
.0000001em thực sự được làm tròn thành 0 trong IE11, phá vỡ sự sửa chữa của bạn. Khi tôi thay đổi nó thành .01em nó hoạt động mặc dù.
Esger

1
Tôi tưởng tượng rằng .01em sẽ đủ để vẫn có hiệu quả bằng không. Điểm tốt. Mặt khác, bây giờ là năm 2018, rất nhiều người trong chúng ta sẽ sớm bỏ hỗ trợ cho IE11, đặc biệt với thông báo gần đây rằng MS sẽ lại xây dựng một trình duyệt mới (ngoại trừ lần này, dựa trên chromium, có nghĩa là về mặt lý thuyết - sẽ không hoàn toàn hút). : D
dudewad

2

display: flexsẽ làm việc trong trường hợp này. Cung cấp phần tử cha display: flex;và sau đó đưa ra mức ký quỹ theo yêu cầu của bạn cho h1thẻ.


0

Chạy vào vấn đề này ngày hôm nay.

overflow: hidden đã không làm việc như mong đợi khi tôi có nhiều yếu tố theo sau.

Vì vậy, tôi đã cố gắng thay đổi thuộc tính hiển thị của div cha và display: flexlàm việc !!!

Hy vọng điều này có thể giúp một ai đó. :)


0

Thêm một chút phần đệm vào phần tử cha có thể khắc phục vấn đề này.

.parent{
  padding-top: 0.01em;
}

Điều này hữu ích nếu bạn cần một phần tử bên trong cha mẹ hiển thị bên ngoài phần tử cha, giống như nếu bạn đang tạo hiệu ứng chồng lấp.


0

Điều này xảy ra vì sự sụp đổ lề. Khi phần tử con chạm vào ranh giới của phần tử cha và bất kỳ phần tử nào được áp dụng với lề sau đó:

  1. Biên độ lớn nhất sẽ giành chiến thắng (áp dụng).

  2. nếu bất kỳ ai trong số họ có lợi nhuận thì cả hai sẽ chia sẻ như nhau.

Các giải pháp

  1. áp dụng đường viền cho cha mẹ làm cho cha mẹ và con cái tách ra.
  2. áp dụng đệm cho cha mẹ mà làm cho cha mẹ và con cái tách ra.
  3. áp dụng tràn hơn là hiển thị trên cha mẹ.
  4. sử dụng trước hoặc sau để tạo phần tử ảo trong div cha có thể khác nhau giữa con và cha mẹ được áp dụng.
  5. tạo một phần tử html giữa con được áp dụng lề và cha mẹ cũng có thể tách chúng ra.
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.