CSS: Làm cách nào để đặt hai phần tử chồng lên nhau mà không cần chỉ định chiều cao?


96

Tôi có hai DIV mà tôi cần đặt chính xác chồng lên nhau. Tuy nhiên, khi tôi làm điều đó, định dạng hoàn toàn bị rối vì DIV có chứa hoạt động như không có chiều cao. Tôi nghĩ rằng đây là hành vi được mong đợi với position:absolutenhưng tôi cần tìm cách đặt hai yếu tố này chồng lên nhau và có vùng chứa kéo dài khi nội dung trải dài:

Cạnh trên bên trái của .layer2phải được căn chỉnh chính xác với cạnh trên cùng bên trái củalayer1

<!-- HTML -->
<div class="container_row">
    <div class="layer1">
        Lorem ipsum...
    </div>
    <div class="layer2">
        More lorem ipsum...
    </div>
</div>
<div class="container_row">
    ...same HTML as above. This one should never overlap the .container_row above.
</div>

/* CSS */
.container_row {}

.layer1 {
    position:absolute;
    z-index: 1;
}

.layer2 {
    position:absolute;
    z-index: 2;
}

1
position: absolutekhông phải là phong cách phù hợp để sử dụng sau đó.
BoltClock

vâng, position:absolutecảm thấy không ổn. Phong cách phù hợp sẽ là gì?
Andrew

Các phần tử .layer1.layer2có kích thước đã biết không?
mu quá ngắn

Không, chúng cũng có kích thước không xác định.
Andrew

Câu trả lời:


81

Trước hết, bạn thực sự nên bao gồm vị trí trên các yếu tố được định vị tuyệt đối nếu không bạn sẽ bắt gặp hành vi kỳ quặc và khó hiểu; bạn có thể muốn thêm top: 0; left: 0vào CSS cho cả hai phần tử được định vị tuyệt đối của mình. Bạn cũng sẽ muốn position: relativebật .container_rownếu bạn muốn các phần tử được định vị tuyệt đối được định vị đối với phần tử gốc của chúng thay vì phần thân của tài liệu :

Nếu phần tử có 'vị trí: tuyệt đối', khối chứa được thiết lập bởi tổ tiên gần nhất với 'vị trí' là 'tuyệt đối', 'tương đối' hoặc 'cố định' ...

Vấn đề của bạn là position: absolutexóa các phần tử khỏi quy trình bình thường :

Nó bị loại bỏ hoàn toàn khỏi dòng chảy bình thường (nó không ảnh hưởng đến anh chị em sau này). Một hộp được định vị tuyệt đối thiết lập một khối chứa mới cho các con dòng bình thường và các con được định vị tuyệt đối (nhưng không cố định). Tuy nhiên, nội dung của một phần tử được định vị tuyệt đối không chảy xung quanh bất kỳ hộp nào khác.

Điều này có nghĩa là các phần tử được định vị tuyệt đối không ảnh hưởng gì đến kích thước của phần tử mẹ của chúng và phần tử đầu tiên của bạn <div class="container_row">sẽ có chiều cao bằng 0.

Vì vậy, bạn không thể làm những gì bạn đang cố gắng làm với các phần tử được định vị hoàn toàn trừ khi bạn biết chúng sẽ cao bao nhiêu (hoặc, tương đương, bạn có thể chỉ định chiều cao của chúng). Nếu bạn có thể chỉ định độ cao thì bạn có thể đặt cùng độ cao vào .container_rowvà mọi thứ sẽ thẳng hàng; bạn cũng có thể đặt margin-topvào giây thứ hai .container_rowđể chừa chỗ cho các phần tử được định vị tuyệt đối. Ví dụ:

http://jsfiddle.net/ambiguous/zVBDc/


Câu trả lời tuyệt vời, cảm ơn! Tôi đoán tôi có thể cần phải tìm ra chiều cao động bằng cách sử dụng javascript. Tôi chỉ hy vọng nó sẽ không phải đến như vậy. = [
Andrew

@Andrew: Vâng, chào mừng bạn đến với hệ thống định cỡ / vị trí / căn chỉnh theo chiều dọc của CSS: nếu bạn không biết kích thước cụ thể của những thứ bạn thường gặp may. Những thứ theo chiều ngang dễ xử lý hơn nhưng hầu hết chúng vẫn có mùi như được thiết kế bởi "những người in bố cục cố định" hơn là "những người bố trí động".
mu quá ngắn

1
Không position: absolutecần thiết. Vui lòng kiểm tra: stackoverflow.com/a/51949049/1736186
thay vào đó,

63

Trên thực tế, điều này là có thể mà không cần vị trí absolutevà chỉ định bất kỳ chiều cao nào. Tất cả những gì bạn cần làm là sử dụng display: gridtrên phần tử cha và đặt các phần tử con vào cùng một hàng và cột.

Vui lòng kiểm tra ví dụ bên dưới, dựa trên HTML của bạn. Tôi chỉ thêm <span>và một số màu, vì vậy bạn có thể xem kết quả.

Bạn cũng có thể dễ dàng thay đổi z-indextừng phần tử con, để điều khiển khả năng hiển thị của nó (cái nào nên ở trên cùng).

.container_row{
  display: grid;
}

.layer1, .layer2{
  grid-column: 1;
  grid-row: 1;
}

.layer1 span{
  color: #fff;
  background: #000cf6;
}

.layer2{
  background: rgba(255, 0, 0, 0.4);
}
<div class="container_row">
    <div class="layer1">
        <span>Lorem ipsum...<br>Test test</span>
    </div>
    <div class="layer2">
        More lorem ipsum...
    </div>
</div>
<div class="container_row">
    ...same HTML as above. This one should never overlap the .container_row above.
</div>


11
Đẹp. Nhưng phải công bằng, display: gridkhông tồn tại bảy năm trước đây :)
mu quá ngắn

Có một câu trả lời khác bên dưới, do @Cornelius viết. Anh ấy sử dụng flex, hiện nay có hỗ trợ trình duyệt tốt hơn nhiều.
Oleg Cherr

20

Câu trả lời tuyệt vời, "mu quá ngắn". Tôi đang tìm kiếm điều tương tự, và sau khi đọc bài đăng của bạn, tôi đã tìm thấy một giải pháp phù hợp với vấn đề của tôi.

Tôi đang có hai phần tử có cùng kích thước và muốn xếp chúng lại. Vì mỗi loại đều có cùng kích thước, điều tôi có thể làm là tạo ra

position: absolute;
top: 0px;
left: 0px;

chỉ trên phần tử cuối cùng. Bằng cách này, phần tử đầu tiên được chèn chính xác, "đẩy" chiều cao của cha mẹ và phần tử thứ hai được đặt trên cùng.

Hy vọng điều này sẽ giúp những người khác đang cố gắng xếp chồng 2 phần tử trở lên có cùng chiều cao (không xác định).


1
NB: Với cách tiếp cận này, bạn sẽ vẫn cần biết phần tử nào là phần tử cao hơn, để bạn có thể chọn position: aboslutephần tử còn lại .
Alec

10

Đây là một giải pháp khác sử dụng display: flex thay vì position: tuyệt đối hoặc display: grid.

.container_row{
  display: flex;
}

.layer1 {
  width: 100%;
  background-color: rgba(255,0,0,0.5);  // red
}

.layer2{
  width: 100%;
  margin-left: -100%;
  background-color: rgba(0,0,255,0.5);  // blue
}
<div class="container_row">
    <div class="layer1">
        <span>Lorem ipsum...</span>
    </div>
    <div class="layer2">
        More lorem ipsum...
    </div>
</div>
<div class="container_row">
    ...same HTML as above. This one should never overlap the .container_row above.
</div>


Giải pháp tuyệt vời. Cảm ơn!
Oleg Cherr

5

Tôi phải đặt

Container_height = Element1_height = Element2_height

.Container {
    position: relative;
}

.ElementOne, .Container ,.ElementTwo{
    width: 283px;
    height: 71px;
}

.ElementOne {
    position:absolute;
}

.ElementTwo{
    position:absolute;
}

Sử dụng có thể sử dụng z-index để đặt cái nào ở trên cùng.


4

Dưới đây là một số css có thể tái sử dụng sẽ bảo toàn chiều cao của từng phần tử mà không cần sử dụng position: absolute:

.stack {
    display: grid;
}
.stack > * {
    grid-row: 1;
    grid-column: 1;
}

Yếu tố đầu tiên trong của bạn stacklà hậu cảnh và yếu tố thứ hai là tiền cảnh.


2

Do định vị tuyệt đối loại bỏ các yếu tố khỏi vị trí dòng tài liệu: tuyệt đối không phải là công cụ phù hợp cho công việc. Tùy thuộc vào bố cục chính xác mà bạn muốn tạo, bạn sẽ thành công khi sử dụng lề âm, vị trí: tương đối hoặc thậm chí có thể chuyển đổi: dịch. Cho chúng tôi xem mẫu về những gì bạn muốn làm, chúng tôi có thể giúp bạn tốt hơn.


1

Tất nhiên, vấn đề chỉ là lấy lại chiều cao của bạn. Nhưng làm thế nào bạn có thể làm điều đó nếu bạn không biết trước chiều cao? Chà, nếu bạn biết bạn muốn cung cấp cho vùng chứa tỷ lệ khung hình nào (và giữ cho nó luôn phản hồi), bạn có thể lấy lại chiều cao của mình bằng cách thêm phần đệm vào một phần tử con khác của vùng chứa, được biểu thị bằng phần trăm.

Bạn thậm chí có thể thêm một hình nộm divvào vùng chứa và đặt một cái gì đó giống như padding-top: 56.25%để cung cấp cho phần tử giả một chiều cao tương ứng với chiều rộng của vùng chứa. Thao tác này sẽ đẩy vùng chứa ra và tạo cho nó một tỷ lệ khung hình, trong trường hợp này là 16: 9 (56,25%).

Padding và margin sử dụng tỷ lệ phần trăm của chiều rộng, đó thực sự là mẹo ở đây.


0

Sau nhiều thử nghiệm, tôi đã xác minh rằng câu hỏi ban đầu đã đúng; chỉ thiếu một vài cài đặt:

  • các container_rowPHẢI cóposition: relative;
  • những đứa trẻ (...), PHẢI có position: absolute; left:0;
  • để đảm bảo các con (...) sắp xếp chính xác với nhau, container_rowcần có thêm kiểu dáng:
    • height:x; line-height:x; vertical-align:middle;
    • text-align:center; cũng có thể giú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.