Tại sao kiểu CSS lề trên này không hoạt động?


321

Tôi cố gắng thêm các giá trị lề trên một div bên trong một div khác. Tất cả hoạt động tốt, ngoại trừ giá trị hàng đầu, nó dường như bị bỏ qua. Nhưng tại sao?

Tôi mong đợi điều gì:
Những gì tôi mong đợi với lề: 50px 50px 50px 50px;

Những gì tôi nhận được:
Những gì tôi nhận được với lề: 50px 50px 50px 50px;

Mã số:

#outer {
    	width: 500px; 
    	height: 200px; 
    	background: #FFCCCC;
    	margin: 50px auto 0 auto;
    	display: block;
}
#inner {
    	background: #FFCC33;
    	margin: 50px 50px 50px 50px;
    	padding: 10px;
    	display: block;
}
<div id="outer">
  <div id="inner">
  	Hello world!
  </div>
</div>

W3Schools không có lời giải thích cho lý do tại sao lề hành xử theo cách này.


4
bạn đã thử nổi cái bên trong chưa?
Dậu

6
hum .. Với float:left;nó hoạt động ... nhưng tại sao điều này là cần thiết. Tôi không muốn nó nổi. Và tại sao lề cho trái / phải làm việc?
jamietelin

44
Chào mừng bạn đến với thế giới thú vị của thuật toán thu gọn lề CSS!
GordonM

10
W3Schools so với W3CDocs ... Tôi nghĩ chúng ta có một người chiến thắng. : D
enderskill

15
jsFiddle của nó, để cứu anh chàng tiếp theo 25 giây jsfiddle.net/kLeu9
CodyBugstein

Câu trả lời:


453

Bạn thực sự đang thấy lề trên của #innerphần tử sụp đổ vào cạnh trên của #outerphần tử, chỉ còn lại phần #outerlề còn nguyên (mặc dù không được hiển thị trong hình ảnh của bạn). Các cạnh trên của cả hai hộp được đặt cạnh nhau vì lề của chúng bằng nhau.

Dưới đây là các điểm có liên quan từ thông số W3C:

8.3.1 Thu hẹp lề

Trong CSS, các lề liền kề của hai hoặc nhiều hộp (có thể là hoặc không phải là anh em ruột) có thể kết hợp để tạo thành một lề duy nhất. Lợi nhuận kết hợp theo cách này được cho là sụp đổ , và kết quả lề kết hợp được gọi là lề bị sụp đổ .

Liền kề lề dọc sụp đổ [...]

Hai lề là liền kề khi và chỉ khi:

  • cả hai đều thuộc các hộp cấp khối trong luồng tham gia vào cùng một bối cảnh định dạng khối
  • không có hộp đường, không giải phóng mặt bằng, không có đệm và không có đường viền ngăn cách chúng
  • cả hai đều thuộc các cạnh hộp liền kề theo chiều dọc, tức là tạo thành một trong các cặp sau:
    • lề trên của hộp và lề trên của con đầu tiên trong dòng

Bạn có thể thực hiện bất kỳ thao tác nào sau đây để ngăn chặn biên độ sụp đổ:

Lý do các tùy chọn trên ngăn chặn biên độ sụp đổ là vì:

  • Các lề giữa một hộp nổi và bất kỳ hộp nào khác không bị sụp đổ (thậm chí không giữa một phao nổi và các con trong dòng chảy của nó).
  • Các lề của các phần tử thiết lập bối cảnh định dạng khối mới (chẳng hạn như phao và các phần tử có 'tràn' khác với 'hiển thị') không bị sụp đổ với các phần tử con của chúng.
  • Lợi nhuận của các hộp khối nội tuyến không sụp đổ (ngay cả với những đứa trẻ trong dòng chảy của chúng).

Các lề trái và phải hoạt động như bạn mong đợi bởi vì:

Lề ngang không bao giờ sụp đổ.



2
Câu trả lời này đá! Chỉ cần một cái gì đó để thêm. Câu nói của bạn về w3c đã nói nhưng tôi chỉ nhận ra bây giờ. Vì vậy, để rõ ràng cho những người khác, bạn cũng có thể cung cấp cho #outer một đường viền.
Driechel

Liên kết trong Floating dường như bị phá vỡ.
EP

@episanty: Đó là những gì xảy ra khi bạn liên kết với một bình luận. Không liên kết.
BoltClock

Tôi biết - chỉ muốn cho bạn biết. Vì bạn đã được kích hoạt, tôi cho rằng bạn có thể muốn khôi phục lại nhận xét - hoặc thay đổi bài đăng của mình cho phù hợp. Cảm ơn câu trả lời tốt, nhân tiện.
EP

92

Hãy thử sử dụng display: inline-block;trên div bên trong.

#outer {
    width:500px; 
    height:200px; 
    background:#FFCCCC;
    margin:50px auto 0 auto;
    display:block;
}
#inner {
    background:#FFCC33;
    margin:50px 50px 50px 50px;
    padding:10px;
    display:inline-block;
}

6
Câu trả lời tốt. Sẽ tốt hơn nếu nó giải thích tại sao thay đổi này khắc phục vấn đề.
JohnFx

1
Ok, đó là quái dị! Tại sao nó hoạt động? Giải thích hợp lý cho lý do tại sao nó không hoạt động như người ta mong đợi. Ký quỹ trái / phải hoạt động mà không có display:inline-block;. Đồng thời đặt lại khi sử dụng display:inline-block;là bạn mất chiều rộng 100% trên div.
jamietelin

3
chuyển đổi nó sang khối nội tuyến buộc trình duyệt phải đánh giá lại kích thước của div sau khi được đặt và các quy tắc khác được áp dụng.
Dậu

Đã thử nó cho vấn đề của tôi, tạo ra một hiệu ứng cầu thang.
Jonny

1
display:inline-blockđã làm cho tôi. Cảm ơn bạn rất nhiều.
starkeen

24

Những gì @BoltClock đề cập là khá vững chắc. Và ở đây tôi chỉ muốn thêm một vài giải pháp cho vấn đề này. kiểm tra lề w3c_collapsing này . Các phần màu xanh là suy nghĩ tiềm năng làm thế nào vấn đề này có thể được giải quyết.

Giải pháp 1

Các lề giữa một hộp nổi và bất kỳ hộp nào khác không bị sụp đổ (thậm chí không giữa một phao nổi và các con trong dòng chảy của nó).

điều đó có nghĩa là tôi có thể thêm float:leftvào #outerhoặc #inner demo1 .

cũng lưu ý rằng floatsẽ làm mất hiệu lực autotrong lề.

Giải pháp 2

Các lề của các phần tử thiết lập bối cảnh định dạng khối mới (chẳng hạn như phao và các phần tử có 'tràn' khác với 'hiển thị') không bị sụp đổ với các phần tử con của chúng.

ngoài ra visible, hãy đưa overflow: hiddenvào #outer. Và cách này có vẻ khá đơn giản và phong nha. Tôi thích nó.

#outer{
    width: 500px;
    height: 200px;
    background: #FFCCCC;
    margin: 50px auto;
    overflow: hidden;
}
#inner {
    background: #FFCC33;
    height: 50px;
    margin: 50px;
}

Giải pháp 3

Lợi nhuận của các hộp được định vị tuyệt đối không bị sụp đổ (ngay cả với những đứa trẻ trong dòng chảy của chúng).

#outer{
    width: 500px;
    height: 200px;
    background: #FFCCCC;
    margin: 50px auto;
    position: absolute; 
}
#inner{
    background: #FFCC33;
    height: 50px;
    margin: 50px;
}

hoặc là

#outer{
    width: 500px;
    height: 200px;
    background: #FFCCCC;
    margin: 50px auto;
    position: relative; 
}
#inner {
    background: #FFCC33;
    height: 50px;
    margin: 50px;
    position: absolute;
}

hai phương pháp này sẽ phá vỡ dòng chảy bình thường của div

Giải pháp 4

Lợi nhuận của các hộp khối nội tuyến không sụp đổ (ngay cả với những đứa trẻ trong dòng chảy của chúng).

giống như @enderskill

Giải pháp 5

Lề dưới của phần tử cấp khối trong dòng chảy luôn sụp đổ với lề trên của anh chị em cấp khối trong dòng tiếp theo, trừ khi anh chị em đó có giải phóng mặt bằng.

Điều này không có nhiều việc phải làm với câu hỏi vì đó là biên độ sụp đổ giữa anh chị em. nó thường có nghĩa là nếu hộp trên cùng có margin-bottom: 30pxvà hộp anh chị em có margin-top: 10px. Tổng số tiền lãi giữa chúng là 30pxthay vì 40px.

Giải pháp 6

Lề trên cùng của phần tử khối trong luồng bị sập với lề trên cùng của khối cấp dòng đầu tiên của nó nếu phần tử không có đường viền trên cùng, không có phần đệm trên cùng và đứa trẻ không có khoảng trống.

Điều này rất thú vị và tôi chỉ có thể thêm một đường viền trên cùng

#outer{
    width: 500px;
    height: 200px;
    background: #FFCCCC;
    margin: 50px auto;
    border-top: 1px solid red;

}
#inner {
    background: #FFCC33;
    height: 50px;
    margin: 50px;

}

Và cũng <div>là cấp độ khối theo mặc định, vì vậy bạn không phải khai báo nó theo mục đích. Xin lỗi vì không thể đăng nhiều hơn 2 liên kết và hình ảnh do danh tiếng người mới của tôi. Ít nhất bạn biết vấn đề đến từ đâu khi bạn thấy điều gì đó tương tự.


14

Không chắc chắn tại sao những gì bạn không làm việc, nhưng bạn có thể thêm

overflow: auto;

để div bên ngoài.


Tải các giải pháp khác nhau cho vấn đề này. Cảm ơn! Câu trả lời này kết hợp với câu trả lời @ BoltClock hè cung cấp thông tin tốt về lý do giải pháp này hoạt động.
jamietelin

12

Nếu bạn thêm bất kỳ phần đệm vào #outer, nó hoạt động.

Bản giới thiệu

#outer {
    width:500px; 
    height:200px; 
    background:#FFCCCC;
    margin:50px auto 0 auto;
    display:block;
    padding-top:1px;
}

11

Không chắc chắn chính xác tại sao, nhưng thay đổi CSS bên trong thành

display:inline-block;

dường như làm việc;


3

Không trả lời "tại sao" (phải là một cái gì đó làm giảm biên), nhưng có vẻ như cách dễ nhất / hợp lý nhất để làm những gì bạn đang cố gắng sẽ chỉ là thêm padding-topvào div bên ngoài :

http://jsfiddle.net/hpU5d/1/

Lưu ý nhỏ - không cần thiết phải đặt div thành display:block;trừ khi có mã nào khác trong mã của bạn bảo nó không bị chặn.


3

thử cái này:

#outer {
    width:500px; 
    height:200px; 
    background:#FFCCCC;
    margin:50px auto 0 auto;
    display:table;
}
#inner {
    background:#FFCC33;
    margin:50px 50px 50px 50px;
    padding:10px;
    display:block;
}​

http://jsfiddle.net/7AXTf/

Chúc may mắn


2

Tôi đoán việc đặt thuộc tính vị trí của div #inner thành tương đối cũng có thể giúp đạt được hiệu ứng. Nhưng dù sao tôi cũng đã thử mã gốc được dán trong Câu hỏi trên IE9 và Google Chrome mới nhất và chúng đã mang lại hiệu quả mong muốn mà không cần sửa đổi gì.


2

Sử dụng padding-top:50pxcho div bên ngoài. Một cái gì đó như thế này:

#outer {
    width:500px; 
    height:200px; 
    background:#FFCCCC;
    margin:50px auto 0 auto;
    display:table;}

Lưu ý: phần đệm sẽ tăng kích thước div của bạn. Trong trường hợp này nếu kích thước div của bạn là quan trọng, ý tôi là nếu nó phải có chiều cao cụ thể. giảm chiều cao xuống 50px.:

#outer {
    width:500px; 
    height:150px; 
    background:#FFCCCC;
    margin:50px auto 0 auto;
    display:table;}

1

Bạn đã cố gắng! Quan trọng trước tất cả, nó sẽ buộc tất cả mọi thứ:

margin:50px 50px 50px 50px !important;

-1

Chỉ để khắc phục nhanh, hãy thử bọc các phần tử con của bạn thành một divphần tử như thế này -

<div id="outer">
   <div class="divadjust" style="padding-top: 1px">
      <div id="inner">
         Hello world!
      </div>
   </div>
</div>

Lợi nhuận của innerdiv sẽ không sụp đổ do phần đệm 1pxở giữa outerinnerdiv. Vì vậy, về mặt logic, bạn sẽ có 1pxthêm không gian cùng với lề innerdiv hiện có .

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.