Tại sao phần tử khối nội tuyến này bị đẩy xuống?


238

Sau đây là mã của tôi và tôi muốn hiểu rằng tại sao #firstDiv lại bị tất cả các trình duyệt đẩy xuống. Tôi thực sự muốn hiểu hoạt động bên trong của thực tế là tại sao nó bị đẩy xuống dưới chứ không phải kéo nó lên bằng cách này hay cách khác. (và tôi biết làm thế nào để sắp xếp ngọn của họ :))

Và tôi biết rằng nó tràn: ẩn mà gây ra nó nhưng không chắc tại sao nó lại đẩy div đó xuống.

body {
  width: 350px;
  margin: 0px auto;
}

#container {
  border: 15px solid orange;
}

#firstDiv {
  border: 10px solid brown;
  display: inline-block;
  width: 70px;
  overflow: hidden;
}

#secondDiv {
  border: 10px solid skyblue;
  float: left;
  width: 70px;
}

#thirdDiv {
  display: inline-block;
  border: 5px solid yellowgreen;
}
<div id="container">
  <div id="firstDiv">FIRST</div>
  <div id="secondDiv">SECOND</div>
  <div id="thirdDiv">THIRD
    <br>some more content<br> some more content
  </div>
</div>

http://jsfiddle.net/WGCyu/ .

Câu trả lời:


360

Về cơ bản, bạn đã thêm nhiều lộn xộn trong mã của mình, điều này tạo ra nhiều sự nhầm lẫn hơn, vì vậy trước tiên tôi cố gắng loại bỏ sự lộn xộn gây cản trở việc hiểu vấn đề thực sự.

Trước hết chúng ta phải xác định đó là câu hỏi thực sự? Đó là lý do tại sao " inline-block" yếu tố được đẩy xuống.

Bây giờ chúng ta bắt đầu hiểu nó và loại bỏ sự lộn xộn đầu tiên.

1 - Tại sao không cho cả ba div cùng độ rộng đường viền? Hãy cho nó.

2 - Phần tử nổi có bất kỳ kết nối nào với phần tử khối nội tuyến được đẩy xuống không? Không, nó không có gì để làm với nó.

Vì vậy, chúng tôi đã loại bỏ div đó hoàn toàn . Và bạn đang chứng kiến ​​hành vi tương tự của yếu tố khối nội tuyến bị đẩy xuống.

Ở đây đến lượt một số tài liệu để nắm bắt ý tưởng về các hộp dòng và cách chúng được xếp trong cùng một dòng đặc biệt đọc đoạn cuối một cách cẩn thận bởi vì có câu trả lời cho câu hỏi của bạn.

Đường cơ sở của 'khối nội tuyến' là đường cơ sở của hộp dòng cuối cùng của nó trong luồng bình thường, trừ khi nó không có hộp dòng trong dòng hoặc nếu thuộc tính 'tràn' của nó có giá trị được tính khác với 'hiển thị', trong trong trường hợp đường cơ sở là cạnh lề dưới.

Nếu bạn không chắc chắn về đường cơ sở thì đây là lời giải thích ngắn gọn bằng những từ đơn giản.

Tất cả các ký tự ngoại trừ 'gjpqy' được viết trên đường cơ sở mà bạn có thể nghĩ về đường cơ sở như thể bạn vẽ một đường ngang đơn giản giống như gạch chân bên dưới các "ký tự ngẫu nhiên" này, sau đó sẽ là đường cơ sở nhưng bây giờ nếu bạn viết bất kỳ 'gjpqy' nào (các) ký tự trên cùng một dòng thì phần dưới của các ký tự này sẽ nằm dưới dòng.

Vì vậy, chúng ta có thể nói rằng tất cả các ký tự ngoại trừ 'gjpqy' được viết hoàn toàn trên đường cơ sở trong khi một số phần của các ký tự này được viết bên dưới đường cơ sở.

3 - Tại sao không kiểm tra đường cơ sở của dòng chúng ta ở đâu? Tôi đã thêm một vài ký tự hiển thị đường cơ sở của dòng chúng tôi.

4 - Tại sao không thêm một số ký tự trong div của chúng ta để tìm đường cơ sở của chúng trong div? Ở đây, một số ký tự được thêm vào div để làm rõ đường cơ sở .

Bây giờ khi bạn hiểu về đường cơ sở, hãy đọc phiên bản đơn giản hóa sau về đường cơ sở của các khối nội tuyến.

i) Nếu khối nội tuyến trong câu hỏi có thuộc tính tràn được đặt thành hiển thị (theo mặc định nên không cần đặt mặc dù). Sau đó, đường cơ sở của nó sẽ là đường cơ sở của khối chứa dòng.

ii) Nếu khối nội tuyến trong câu hỏi có thuộc tính tràn được đặt thành KHÁC. Sau đó, lề dưới của nó sẽ nằm trên đường cơ sở của dòng hộp chứa.

  • Điểm đầu tiên chi tiết

Bây giờ hãy nhìn vào điều này một lần nữa để làm rõ khái niệm của bạn rằng những gì đang xảy ra với div xanh . Nếu có bất kỳ sự nhầm lẫn nào thì ở đây được thêm nhiều ký tự gần với div xanh để thiết lập đường cơ sở của khối chứa và đường cơ sở div xanh được căn chỉnh.

Chà, bây giờ tôi đang tuyên bố rằng họ có cùng đường cơ sở? ĐÚNG?

5 - Vậy thì tại sao không chồng chúng lên nhau và xem liệu chúng có phù hợp với nhau không? Vì vậy, tôi mang div thứ ba: 35px; để kiểm tra xem bây giờ họ có cùng đường cơ sở không?

Bây giờ, chúng tôi đã có điểm đầu tiên của chúng tôi chứng minh.

  • Điểm thứ hai chi tiết

Chà, sau khi giải thích về điểm thứ hai, điểm thứ hai có thể dễ dàng tiêu hóa và bạn thấy rằng div đầu tiên có thuộc tính tràn được đặt thành khác không nhìn thấy (ẩn) có lề dưới của nó trên đường cơ sở của dòng.

Bây giờ, bạn có thể thực hiện một vài thí nghiệm để minh họa thêm.

  1. Đặt tràn div đầu tiên: hiển thị (hoặc loại bỏ hoàn toàn) .
  2. Đặt tràn div thứ hai: khác với hiển thị .
  3. Đặt cả hai div tràn: khác với hiển thị .

Bây giờ mang lại sự lộn xộn của bạn và xem nếu mọi thứ đang tốt đẹp với bạn.

  1. Mang lại div nổi của bạn (tất nhiên cần phải
    tăng một số chiều rộng của cơ thể) Bạn thấy nó không có tác dụng.
  2. Mang lại lợi nhuận kỳ lạ tương tự .
  3. Đặt div màu xanh lá cây thành tràn: hiển thị khi bạn đặt câu hỏi của mình (sự sai lệch đó là do tăng độ rộng đường viền từ 1px đến 5px vì vậy nếu điều chỉnh âm trái, bạn sẽ thấy không có vấn đề gì)
  4. Bây giờ loại bỏ các ký tự bổ sung mà tôi đã thêm để giúp hiểu . (và tất nhiên loại bỏ tiêu cực trái)
  5. Cuối cùng giảm chiều rộng cơ thể vì chúng ta không còn cần rộng hơn nữa.

Và bây giờ chúng tôi trở lại nơi chúng tôi bắt đầu.

Hy vọng tôi đã trả lời câu hỏi của bạn.


1
Cảm ơn về một lời giải thích tuyệt vời như vậy nhưng tôi đã không nhận được ý kiến ​​của bạn "Sau đó, đường cơ sở của nó sẽ là đường cơ sở của khối chứa dòng." Có giống như đường cơ sở của dòng như bạn đã làm rõ ở điểm thứ hai?
Shawn Taylor

2
Phản ứng muộn. Tôi chỉ lưu ý vấn đề tương tự, và tôi chỉ muốn cảm ơn Gary Lindahl vì lời giải thích của NICE.
TimSPQR

+1 ntgCleaner Mặc dù tôi đánh giá cao câu trả lời hay, nhưng Gary Lindahl rất nhiều để đọc và tôi chỉ thiếu vài dòng trong đó có dòng chữ 'Giải pháp: XY'
cơ bản

Tôi tìm thấy lời giải thích chi tiết vô cùng thông tin này, cảm ơn bạn. Tôi đã vật lộn với một khái niệm trong một thời gian, và đã tạo ra một Fiddle cập nhật có thể làm rõ cho những người khác.
jonsanders101

@ntgCleaner cảm ơn người đàn ông .. thậm chí sau tất cả những lời giải thích tôi không thể làm cho nó hoạt động. nhưng bình luận của bạn đã làm điều đó :)
supersan

329

Giá trị mặc định cho vertical-alignCSS là baseline& quy tắc này cũng được áp dụng với việc inline-blockđọc http://www.brunasy.org/test/inline-block.html này

Viết vertical-align:toptrong inline-blockDIV của bạn .

Kiểm tra http://jsfiddle.net/WGCyu/1/


3
Bạn đã đọc câu hỏi của tôi? Tôi không bao giờ yêu cầu sửa vấn đề.
Shawn Taylor

23
@ShawnTaylor: Tiêu đề câu hỏi rất sai lệch. Chúng tôi theo bản năng đọc tiêu đề sau đó bắn cho mã, nếu có. Chúng tôi hiếm khi đọc văn bản thực tế. Đó là một thói quen xấu nhưng có lẽ bạn nên hiểu tại sao nó lại xảy ra. : P
Purag

@sandeep: liên quan đến chỉnh sửa của bạn, tại sao FirstDiv được căn chỉnh lên hàng đầu ngay cả khi căn chỉnh dọc được xóa khỏi nó
Shawn Taylor

@sandeep: Liên kết bạn cung cấp có nhiều thông tin, nhưng nó không giúp ích gì cho câu hỏi này vì nó không mô tả hành vi display:inline-blockkết hợp với float:left/right.
Zeta

2
@ThomasMcCabe Khó; nếu ai đó đăng một câu trả lời không hay, nó đáng bị hạ thấp để báo hiệu cho người xem trong tương lai rằng có điều gì đó không ổn với nó, bất kể ý định tốt của họ là gì. Điều đó nói rằng, tôi không nghĩ rằng câu trả lời này đã từng xứng đáng với một downvote; ngay cả ở dạng ban đầu, nó đã cung cấp một phần chính của câu đố bị bỏ qua bởi câu trả lời được chấp nhận - rằng căn chỉnh đường cơ sở không phải là cách duy nhất mà các phần tử được căn chỉnh theo chiều dọc và nếu bạn thay đổi thuộc vertical-aligntính, thì không có sự phức tạp nào được mô tả trong câu trả lời được chấp nhận áp dụng.
Đánh dấu Amery


9

Xem ví dụ thay thế này . Lý do cho hành vi như vậy được mô tả trong mô-đun CSS3: line: 3.2. Gói hộp [1] :

Nói chung, cạnh bắt đầu của hộp dòng chạm vào cạnh bắt đầu của khối chứa và cạnh cuối chạm vào cạnh cuối của khối chứa. Tuy nhiên, các hộp nổi có thể nằm giữa cạnh khối chứa và cạnh hộp dòng. Do đó, mặc dù các hộp dòng trong cùng bối cảnh định dạng nội tuyến thường có cùng tiến trình phát triển nội tuyến giống nhau (của khối chứa), chúng có thể thay đổi nếu không gian tiến trình nội tuyến có sẵn bị giảm do thả nổi [...]

Như bạn có thể thấy, phần tử thứ ba được đẩy xuống, mặc dù nó không có thuộc overflowtính. Lý do phải ở một nơi khác để tìm. Hành vi thứ hai mà bạn nhận thấy được mô tả trong Cascading Style Sheets Cấp 2 Phiên bản 1 (CSS 2.1) Đặc điểm kỹ thuật: 9.5 Floats [2] :

Vì phao không nằm trong luồng, các hộp khối không định vị được tạo trước và sau hộp phao chảy theo chiều dọc như thể phao không tồn tại. Tuy nhiên, các hộp dòng hiện tại và tiếp theo được tạo bên cạnh phao được rút ngắn khi cần thiết để nhường chỗ cho hộp lề của phao.

Tất cả các display:inline-block;div của bạn đang sử dụng một loại đặc biệt baselinetrong trường hợp này 10.8 Tính toán chiều cao của dòng: thuộc tính 'line-height' và 'vertical-align' (rất cuối) [3] :

Đường cơ sở của 'khối nội tuyến' là đường cơ sở của hộp dòng cuối cùng của nó trong luồng bình thường, trừ khi nó không có hộp dòng trong dòng hoặc nếu thuộc tính 'tràn' của nó có giá trị được tính khác với 'hiển thị', trong trong trường hợp đường cơ sở là cạnh lề dưới.

Vì vậy, khi bạn đang sử dụng các phần tử và inline-blockphần tử nổi, phần tử nổi sẽ được đẩy sang một bên và định dạng nội tuyến sẽ được tính toán lại theo 1 . Mặt khác, các yếu tố tiếp theo được rút ngắn nếu chúng không phù hợp. Vì bạn đã làm việc với một không gian tối thiểu, không có cách nào khác để sửa đổi các yếu tố của bạn sau đó đẩy chúng 2 . Trong trường hợp này, phần tử cao nhất sẽ xác định kích thước của div gói của bạn, do đó xác định baseline 3 , trong khi đó, việc sửa đổi vị trí và chiều rộng được nêu trong 2 không thể được áp dụng cho các phần tử chiều cao tối đa cách nhau tối thiểu như vậy. Trong trường hợp này, một hành vi như trong bản demo đầu tiên của tôi sẽ có kết quả.

Cuối cùng, lý do ý chí của bạn overflow:hiddensẽ #firstDivbị đẩy xuống cạnh dưới của bạn #container, mặc dù tôi không thể tìm thấy lý do trong phần 11 . Không có overflow:hiddennó hoạt động như bị loại trừ và được xác định bởi 23 . Bản giới thiệu

TL; DR: Có cái nhìn rất gần về các khuyến nghị của W3 và các triển khai trong trình duyệt. Theo ý kiến ​​khiêm tốn của tôi, các yếu tố nổi được xác định để thể hiện hành vi bất ngờ nếu bạn không biết tất cả những thay đổi mà chúng thực hiện đối với các yếu tố xung quanh. Đây là một bản demo khác cho thấy một vấn đề phổ biến với phao.


3
"Tiêu chuẩn" này là một mớ hỗn độn không thể tin được. Thật đáng kinh ngạc họ đã có thể làm cho công cụ này hoạt động nhất quán trên các trình duyệt. Đợi đã, không, họ chưa bao giờ có thể làm điều đó.
Triynko

6

Ban đầu tôi bắt đầu trả lời câu hỏi này , nhưng nó đã bị khóa dưới dạng dupe trước khi tôi có thể kết thúc, vì vậy tôi đăng câu trả lời ở đây để thay thế.

Đầu tiên, chúng ta cần hiểu những gì inline-blocklà.
Các định nghĩa trong MDN nói:

Phần tử tạo ra một hộp phần tử khối sẽ được truyền với nội dung xung quanh như thể nó là một hộp nội tuyến duy nhất (hoạt động giống như một phần tử được thay thế)

Để hiểu những gì đang diễn ra ở đây, chúng ta cần xem xét vertical-alignvà đó là giá trị mặc định baseline.

trực quan vị trí dọc
Trong hình minh họa này, bạn có biểu đồ màu này:
Blue: Đường cơ sở
Đỏ: Trên cùng và dưới cùng của chiều cao đường thẳng
Green: Trên cùng và dưới cùng của hộp nội dung nội tuyến.

Trong phần tử #left, bạn có một số nội dung văn bản kiểm soát đường cơ sở là gì. Điều này có nghĩa là văn bản bên trong xác định đường cơ sở cho #left.
Trong #right, không có nội dung, vì vậy trình duyệt không có tùy chọn nào khác ngoài việc sử dụng đáy hộp làm đường cơ sở.

Hình dung này trong đó tôi đã vẽ đường cơ sở trên một ví dụ trong đó bộ chứa nội tuyến đầu tiên có một số văn bản và tiếp theo là trống:

Đường cơ sở rút ra

Nếu bạn đặc biệt căn chỉnh một yếu tố lên đầu, bạn thực sự nói rằng bạn căn chỉnh đỉnh của yếu tố này với đầu hộp dòng.

Điều này có thể dễ hiểu hơn bằng một ví dụ.

div {
    display: inline-block;
    width: 100px;
    height: 150px;
    background: gray;
    vertical-align: baseline;
}
div#middle {
    vertical-align: top;
    height: 50px
}
   
div#right {
    font-size: 30px;
    height: 100px
}
<div id="left">
  <span>groovy</span>
</div>
<div id="middle">groovy</div>

<div id="right">groovy</div>

Kết quả là thế này - và tôi đã thêm đường cơ sở màu xanh lam và hộp dòng màu đỏ: Điều gì xảy ra ở đây, là chiều cao của hộp dòng phụ thuộc vào cách trình bày nội dung của toàn bộ dòng. Điều này có nghĩa là để tính toán căn chỉnh trên cùng, việc căn chỉnh đường cơ sở phải được tính toán trước. Phần tử có , vì vậy phần này không được sử dụng cho định vị đường cơ sở. nhưng và được định vị theo chiều dọc để đường cơ sở của chúng được căn chỉnh. Khi điều này được thực hiện, chiều cao của hộp dòng đã tăng lên, bởi vì phần tử đã được đẩy lên một chút do kích thước phông chữ lớn hơn. Sau đó, vị trí trên cùng của phần tử có thể được tính toán và vị trí này nằm dọc theo đỉnh của hộp dòng.Giải thích theo chiều dọc
#middlevertical-align:top#left#right#right#middle


1

vấn đề là bởi vì bạn đã áp dụng float: left trên div thứ hai. Điều này làm cho div thứ hai xuất hiện ở phía bên trái và div đầu tiên của bạn giảm xuống và xuất hiện sau div thứ hai của bạn. Nếu bạn áp dụng float: còn lại trên div đầu tiên, vấn đề của bạn sẽ không còn nữa.

overflow: hidden không gây ra vấn đề gì cho bố cục của bạn, overflow: hidden chỉ ảnh hưởng đến các phần tử bên trong của div, nó không liên quan gì đến các phần tử khác bên ngoài.


Chà, nếu nó bị đẩy bởi vì nó đứng thứ hai sau khi nổi div thì tại sao thirdDiv không đi xuống?
Shawn Taylor

bởi vì div thứ ba có div thứ hai trước nó không có float: left;
Pal Singh

Nhưng quy tắc này được đề cập ở đâu rằng nếu một số div sẽ xuất hiện sau khi div nổi thì nó sẽ giảm xuống? Tôi đã kiểm tra w3.org.
Shawn Taylor

yếu tố không trôi nổi xuống đường cơ sở và nếu bạn đã bỏ phiếu tiêu cực hơn tôi phải nói rằng đó là câu trả lời hợp lý nhất
Pal Singh

Không, tôi đã không bỏ phiếu tiêu cực và có câu trả lời của bạn không xứng đáng tiêu cực. Chỉ cần bình chọn trở lên.
Shawn Taylor

0

Hãy thử thêm padding:0;vào cơ thể và loại bỏ lề của divs của bạn.

Thêm background-color:*anymàu ngoài nền * để kiểm tra sự khác biệt.


Chỉnh sửa câu trả lời thành định dạng mã, Bạn có thể định dạng mã bằng cách thêm ký hiệu `trước khi bắt đầu mã và sau khi kết thúc mã. như codeví dụ :. background-color:any color
JINO SHAJI

0

Hãy thử làm tất cả các thuộc tính CSS của tất cả các thành phần giống nhau.

Tôi gặp vấn đề tương tự và trong khi sửa lỗi này, tôi xác định rằng tôi đã bỏ một phần tử có thuộc tính Font vào Div Element.

Sau khi bỏ thuộc tính Element đó với Font, căn chỉnh của tất cả DIV đã bị xáo trộn. Để khắc phục điều này, tôi đặt thuộc tính Font cho tất cả các phần tử DIV giống như phần tử được thả vào nó.

Trong ví dụ sau, phần tử bị rớt của lớp ".dldCuboidButton" được xác định với cỡ chữ: 30 px.

Vì vậy, tôi đã thêm cùng một thuộc tính cho các lớp còn lại, ví dụ: .cuboidRecycle, .liCollect, .dldCollect được sử dụng bởi các phần tử DIV. Theo cách đó, tất cả các phần tử DIV tuân theo các Phép đo giống nhau trước và sau khi thả phần tử vào đó.

.cuboidRecycle {
    height:40px; 
    width:'20px; float:right';
    overflow:'none';
    background-color:#cab287;
    color:#ffffff; 
    border-radius:8px; 
    text-align:'center'; 
    vertical-align:'top';
    display: inline-block;
    font-size: 30px; /* Set a font-size */
}


.liCollect {
    height:40px; 
    width:'20px; float:right';
    overflow:'none';
    background-color:#cab287;
    color:#ffffff; 
    border-radius:8px; 
    text-align:'center'; 
    vertical-align:'top';
    display: inline-block;
    font-size: 30px; /* Set a font-size */
}

.dldCollect {
    height:40px; 
    width:'20px; float:right';
    overflow:'none';
    background-color:#009933;
    color:#ffffff; 
    border-radius:8px; 
    text-align:'center'; 
    vertical-align:'top';
    display: inline-block;
    font-size: 30px; /* Set a font-size */
}


.dldCuboidButton {
    background-color:  #7c6436;
    color: white; /* White text */
    font-size: 30px; /* Set a font-size */
    border-radius: 8px;
    margin-top: 1px;
  }

Dưới đây là ví dụ về HTML được tạo động bằng cách sử dụng CSS ở trên.

$("div#tabs").append(
  "<div id='" + newTabId + "'>#" + uniqueId + 
  "<input type=hidden id=hdn_tmsource_" + uniqueId + "  value='" + divTmpfest + "'>" + 
  "<input type=hidden id=leCuboidInfo_" + uniqueId + " value=''>" + 
  "<div id='" + divRecycleCuboid + "' class=cuboidRecycle ondrop='removeDraggedCuboids(event, ui)'  ondragover='allowDrop(event)'><font size='1' color='red'> Trash bin </font></div>" +
  "<div id='" + divDropLeCuboid  + "' class=liCollect ondrop='dropForLinkExport(event)'  ondragover='allowDrop(event)'><font size='1' color='red'>Drop Template Manifest Cuboid here</font></div>" +
  "<div id='" + divDropDwldCuboid  + "' class=dldCollect ondrop='dropForTMEntry(event)'  ondragover='allowDrop(event)'><font size='1' color='red'>Drop Template Cuboids here..</font></div>" +
  "</div>" 
);
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.