Làm thế nào để vô hiệu hóa sụp đổ lề?


202

Có cách nào để vô hiệu hóa sụp đổ biên hoàn toàn không? Các giải pháp duy nhất tôi đã tìm thấy (theo tên "unollapsing") đòi hỏi phải sử dụng đường viền 1px hoặc đệm 1px. Tôi thấy điều này không thể chấp nhận được: pixel ngoại lai làm phức tạp các tính toán mà không có lý do chính đáng. Có cách nào hợp lý hơn để vô hiệu hóa sự sụp đổ lề này không?


4
Sử dụng bố cục Flex hoặc Grid, trong đó thu hẹp lề không tồn tại: stackoverflow.com/a/46496701/3597276
Michael Benjamin

Đơn giản chỉ cần cung cấp cho các phần tử một giá trị cho margin-bottomnhưng để lại margin-toplà 0.
Dan Bray

Tôi đã thực hiện một gói để làm cho phép tính dễ dàng hơn: npmjs.com/package/collapsed-margin
Owen M

Câu trả lời:


254

Có hai loại sụp đổ lề chính:

  • Thu hẹp lề giữa các yếu tố liền kề
  • Thu gọn lề giữa các yếu tố cha mẹ và con

Sử dụng một miếng đệm hoặc đường viền sẽ ngăn chặn sự sụp đổ chỉ trong trường hợp sau. Ngoài ra, bất kỳ giá trị nào overflowkhác với giá trị mặc định ( visible) được áp dụng cho cha mẹ sẽ ngăn chặn sự sụp đổ. Như vậy, cả hai overflow: autooverflow: hiddensẽ có tác dụng như nhau. Có lẽ sự khác biệt duy nhất khi sử dụng hiddenlà hậu quả không lường trước của việc ẩn nội dung nếu cha mẹ có chiều cao cố định.

Các thuộc tính khác, một khi được áp dụng cho cha mẹ, có thể giúp khắc phục hành vi này là:

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

Bạn có thể kiểm tra tất cả chúng ở đây: http://jsfiddle.net/XB9wX/1/ .

Tôi nên thêm rằng, như thường lệ, Internet Explorer là ngoại lệ. Cụ thể hơn, trong IE 7 lề không sụp đổ khi một số loại bố cục được chỉ định cho phần tử cha, chẳng hạn như width.

Nguồn: Bài viết của Sitepoint Thu gọn lề


1
lưu ý rằng phần đệm cũng có thể ảnh hưởng đến điều này nếu nó không có giá trị bằng 0
Mladen Janjetovic

3
Lưu ý rằng overflow: autocó thể gây ra thanh cuộn xuất hiện trong các yếu tố phụ huynh, thay vì để tràn nội dung tràn theo overflow: visible.
Leo

'tràn: tự động' dường như không hoạt động trong Chrome v44.
tkane2000

3
Cảm ơn đã hiển thị: inline-block, nó đã cứu tôi :)
alexcasalboni

3
Bất kỳ giá trị nào flexkhác với mặc định của nó cũng sẽ vô hiệu hóa sự sụp đổ lề
Oly

60

Bạn cũng có thể sử dụng thuật ngữ rõ ràng cũ tốt cho việc này.

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

Xem fiddle cập nhật: http://jsfiddle.net/XB9wX/97/


Đã biến câu trả lời của tôi thành một wiki cộng đồng. Xin vui lòng mở rộng nó với câu trả lời của bạn. Cảm ơn.
hqcasanova

3
Tôi không hiểu điều đó, khi tôi xem ví dụ đó các lề đang sụp đổ (chỉ có không gian dọc 10px giữa các div thay vì 20px)
Andy

1
Điều này chỉ giúp loại bỏ sự sụp đổ giữa anh chị em mà tất cả đều có áp dụng xóa này. Tôi đã lấy ví dụ để chứng minh điều này: jsfiddle.net/dpyuyg07 --- và thậm chí đó không phải là toàn bộ câu chuyện. Nó chỉ loại bỏ sự sụp đổ của lề xuất phát từ con của các yếu tố mà bạn đã áp dụng cách khắc phục đó. Nếu bạn thêm một lề trên chính container, lề vẫn sẽ sụp đổ, có thể thấy trong ngã ba này: jsfiddle.net/oew7qsjx
NicBright

4
Tôi có thể đặt điều này chính xác hơn nữa: phương pháp Clearfix chỉ ngăn chặn sự sụp đổ lề giữa cha mẹ và con cái. Nó không ảnh hưởng đến sự sụp đổ giữa anh chị em liền kề.
NicBright

Tôi nghĩ bây giờ tôi hiểu xu hướng của Bootstrap để lấp đầy DOM :before:aftercác yếu tố. Bây giờ tôi đã thêm quy tắc này vào biểu định kiểu của mình : div:before, div:after{content: ' '; display: table;}. Tuyệt diệu. Đột nhiên công cụ bắt đầu cư xử như mong đợi.
Stijn de Witt

59

Một mẹo nhỏ để vô hiệu hóa thu hẹp lề không có tác động trực quan, theo như tôi biết, là đặt phần đệm của cha mẹ thành 0.05px:

.parentClass {
    padding: 0.05px;
}

Phần đệm không còn là 0 nên việc sập sẽ không còn xảy ra nữa, nhưng đồng thời phần đệm đủ nhỏ để trực quan nó sẽ làm tròn xuống 0.

Nếu một số phần đệm khác là mong muốn, thì chỉ áp dụng phần đệm cho "hướng" trong đó thu hẹp lề không mong muốn, chẳng hạn padding-top: 0.05px;.

Ví dụ làm việc:

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

Chỉnh sửa: thay đổi giá trị từ 0.1thành 0.05. Như Chris Morgan đã đề cập trong một bình luận dưới đây, và từ bài kiểm tra nhỏ này , có vẻ như thực sự Firefox đã 0.1pxxem xét phần đệm. Mặc dù, 0.05pxdường như để làm các mẹo.


2
Đây là giải pháp yêu thích của tôi. Bạn thậm chí có thể bao gồm điều này như một phong cách mặc định. Tại sao không? *{padding-top:0.1px}. Chúng tôi có chắc chắn rằng nó hoạt động trong tất cả các trình duyệt mặc dù?
Nick Manning

Làm việc khá tốt cho tôi cho đến nay, nhưng tôi không khẳng định đã kiểm tra kỹ lưỡng trong hầu hết các trình duyệt.
Nicu Surdu

2
Giải pháp rất hay, nó dường như hoạt động như mong đợi trên hầu hết các trình duyệt. Cảm ơn đã chia sẻ nó!
Wiredolphin

1
Đây là một giải pháp tinh ranh như nó không thêm điểm ảnh phụ trong những hoàn cảnh khác nhau, do màn hình cao DPI và tính toán subpixel. (Firefox đã thực hiện bố cục subpixel từ lâu, tôi tin rằng các trình duyệt khác có sự phù hợp tương đối gần đây.)
Chris Morgan

0.05pxCó vẻ như vẫn là một lựa chọn cụ thể, không phải là số lừa đảo trình duyệt ngẫu nhiên, tôi thích 0.01px.
Volker E.

22

overflow:hidden ngăn chặn sự sụp đổ lợi nhuận nhưng nó không có tác dụng phụ - cụ thể là nó ... che giấu tràn.

Ngoài hình thức này và những gì bạn đã đề cập, bạn chỉ cần học trực tiếp với nó và học cho ngày hôm nay khi chúng thực sự hữu ích (cứ sau 3 đến 5 năm).


Đã biến câu trả lời của tôi thành một wiki cộng đồng. Tôi nghĩ rằng tôi đã đề cập đến hiệu ứng phụ mà bạn đã đề cập trong hai dòng cuối của đoạn thứ hai: Có lẽ sự khác biệt duy nhất khi sử dụng ẩn là hậu quả không lường trước của việc ẩn nội dung nếu cha mẹ có chiều cao cố định . Nhưng nếu bạn cảm thấy cần làm rõ thêm, xin vui lòng đóng góp. Cảm ơn.
hqcasanova

7
overflow: autolà tốt để sử dụng để ngăn chặn tràn tràn ẩn và vẫn ngăn chặn lợi nhuận sụp đổ.
Gavin

@Gavin, overflow:auto;làm cho khu vực nội dung của tôi có được một thanh cuộn trên một số trang.
Sậy

13

Trên thực tế, có một hoạt động hoàn hảo:

hiển thị: flex; hướng flex: cột;

miễn là bạn có thể sống với chỉ hỗ trợ IE10 trở lên

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


Để điều này hoạt động như một giải pháp chung, người ta phải thêm một phần bổ sung <div>bên trong .container, nếu không thì .containersẽ điều khiển mô hình hộp của các phần tử con của nó. Ví dụ, các phần tử nội tuyến sẽ trở thành các phần tử khối toàn chiều rộng; nếu họ có lợi nhuận thì họ cũng sẽ bị sụp đổ.
zupa

9

Mỗi trình duyệt dựa trên webkit nên hỗ trợ các thuộc tính -webkit-margin-collapse. Ngoài ra còn có các sản phẩm phụ để chỉ đặt nó cho lề trên hoặc dưới. Bạn có thể cung cấp cho nó giá trị thu gọn (mặc định), loại bỏ (đặt lề thành 0 nếu có lề lân cận) và tách biệt (ngăn chặn thu hẹp lề).

Tôi đã thử nghiệm tính năng này hoạt động trên các phiên bản 2014 của Chrome và Safari. Thật không may, tôi không nghĩ rằng điều này sẽ được hỗ trợ trong IE vì nó không dựa trên webkit.

Đọc tài liệu tham khảo Safari Safari của Apple để được giải thích đầy đủ.

Nếu bạn kiểm tra trang tiện ích mở rộng webkit CSS của Mozilla , họ sẽ liệt kê các thuộc tính này là độc quyền và khuyên không nên sử dụng chúng. Điều này là do họ có thể sẽ không đi vào CSS tiêu chuẩn sớm và chỉ các trình duyệt dựa trên webkit mới hỗ trợ họ.


Điều này thật tuyệt vì nó giúp chúng tôi giải quyết sự không nhất quán trong cách Safari và Chrome xử lý lợi nhuận.
bjudson

8

Tôi biết rằng đây là một bài viết rất cũ nhưng chỉ muốn nói rằng sử dụng flexbox trên phần tử cha sẽ vô hiệu hóa thu gọn lề cho các phần tử con của nó.


Không chỉ đối với các yếu tố con của nó - nó cũng ngăn chặn sự sụp đổ lề giữa cha mẹ và con đầu tiên và con cuối cùng.
Sven Marnach

2

Tôi gặp vấn đề tương tự với sự sụp đổ lề vì cha mẹ đã positionđặt thành tương đối. Dưới đây là danh sách các lệnh bạn có thể sử dụng để vô hiệu hóa thu hẹp lề.

ĐÂY LÀ CHƠI TRÒ CHƠI

Chỉ cần cố gắng gán bất kỳ parent-fix*lớp để div.containeryếu tố, hoặc bất kỳ lớp children-fix*để div.margin. Chọn một trong những phù hợp với nhu cầu của bạn tốt nhất.

Khi nào

  • lề sụp đổngười khuyết tật , div.absolutevới nền đỏ sẽ được bố trí ở phía trên cùng của trang.
  • lề đang sụp đổ div.absolute sẽ được định vị tại cùng tọa độ Y như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>

Dưới đây là jsFiddle với ví dụ bạn có thể chỉnh sửa


1

Trong trình duyệt mới hơn (không bao gồm IE11), một giải pháp đơn giản để ngăn chặn sự sụp đổ lề cha-con là sử dụng display: flow-root. Tuy nhiên, bạn vẫn sẽ cần các kỹ thuật khác để ngăn chặn sự sụp đổ của phần tử liền kề.

DEMO (trước)

.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 (sau)

.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

Để biết thông tin của bạn, bạn có thể sử dụng lưới nhưng có tác dụng phụ :)

.parent {
  display: grid
}
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.