CSS: Bagaimana memposisikan dua elemen di atas satu sama lain, tanpa menentukan ketinggian?

96

Saya memiliki dua DIV yang harus saya posisikan tepat di atas satu sama lain. Namun, ketika saya melakukan itu, pemformatan menjadi kacau karena DIV yang berisi bertindak seperti tidak ada ketinggian. Saya pikir ini adalah perilaku yang diharapkan position:absolutetetapi saya perlu menemukan cara untuk memposisikan kedua elemen ini di atas satu sama lain dan memiliki wadah yang meregang saat konten membentang:

Tepi kiri atas .layer2harus persis sejajar dengan tepi kiri ataslayer1

<!-- 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;
}
Andrew
sumber
1
position: absolutebukan gaya yang tepat untuk digunakan saat itu.
BoltClock
ya, position:absoluterasanya tidak benar. Apa gaya yang tepat?
Andrew
Apakah elemen .layer1dan .layer2memiliki ukuran yang diketahui?
mu terlalu pendek
Tidak, ukurannya juga tidak diketahui.
Andrew

Jawaban:

81

Pertama-tama, Anda benar-benar harus memasukkan posisi pada elemen yang benar-benar diposisikan atau Anda akan menemukan perilaku yang aneh dan membingungkan; Anda mungkin ingin menambahkan top: 0; left: 0ke CSS untuk kedua elemen yang benar-benar diposisikan. Anda juga akan ingin memiliki position: relativepada .container_rowjika Anda ingin elemen benar-benar diposisikan untuk diposisikan sehubungan dengan orang tua mereka daripada tubuh dokumen :

Jika elemen memiliki 'position: absolute', blok berisi ditetapkan oleh leluhur terdekat dengan 'position' dari 'absolute', 'relative' atau 'fixed' ...

Masalah Anda adalah position: absolutemenghilangkan elemen dari aliran normal :

Itu dihapus dari aliran normal sepenuhnya (tidak berdampak pada saudara kandung nanti). Kotak yang diposisikan secara mutlak menetapkan blok penampung baru untuk turunan aliran normal dan turunan yang diposisikan secara mutlak (tetapi tidak tetap). Namun, konten elemen yang diposisikan secara absolut tidak mengalir di sekitar kotak lain.

Ini berarti bahwa elemen yang diposisikan secara mutlak tidak berpengaruh apa pun pada ukuran elemen induknya dan elemen pertama Anda <div class="container_row">akan memiliki tinggi nol.

Jadi, Anda tidak dapat melakukan apa yang Anda coba lakukan dengan elemen yang diposisikan secara absolut kecuali jika Anda mengetahui tingginya (atau, setara, Anda dapat menentukan tingginya). Jika Anda dapat menentukan tinggi badan maka Anda dapat meletakkan ketinggian yang sama di atas .container_rowdan semuanya akan berbaris; Anda juga bisa meletakkan margin-topdi kedua .container_rowuntuk meninggalkan ruang untuk elemen yang benar-benar diposisikan. Sebagai contoh:

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

mu terlalu pendek
sumber
Jawaban bagus, terima kasih! Saya rasa saya mungkin perlu mencari tahu ketinggian secara dinamis menggunakan javascript. Saya hanya berharap tidak harus sampai seperti itu. = [
Andrew
@ Andrew: Ya, selamat datang di sistem ukuran / posisi / penyelarasan vertikal CSS: jika Anda tidak mengetahui ukuran tertentu dari hal-hal yang biasanya Anda kurang beruntung. Hal-hal horizontal lebih mudah ditangani tetapi sebagian besar masih berbau seperti itu dirancang oleh "orang cetak tata letak tetap" daripada "orang tata letak dinamis".
mu terlalu pendek
1
Tidak position: absoluteperlu. Silakan periksa: stackoverflow.com/a/51949049/1736186
sebagai gantinya
63

Sebenarnya ini mungkin tanpa posisi absolutedan menentukan ketinggian apapun. Yang perlu Anda lakukan adalah menggunakan display: gridelemen induk dan meletakkan turunannya, ke dalam baris dan kolom yang sama.

Silakan periksa contoh di bawah ini, berdasarkan HTML Anda. Saya hanya menambahkan <span>dan beberapa warna, sehingga Anda dapat melihat hasilnya.

Anda juga dapat dengan mudah mengubah z-indexsetiap elemen turunan, untuk memanipulasi visibilitasnya (yang mana yang harus di atas).

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

sebagai gantinya
sumber
11
Bagus. Tapi agar adil, display: gridtidak ada tujuh tahun yang lalu :)
mu terlalu pendek
Ada jawaban lain di bawah ini, yang ditulis oleh @Cornelius. Dia menggunakan flex, yang memiliki dukungan browser yang jauh lebih baik saat ini.
Oleg Cherr
20

Jawaban yang bagus, "mu terlalu pendek". Saya mencari hal yang persis sama, dan setelah membaca posting Anda, saya menemukan solusi yang sesuai dengan masalah saya.

Saya memiliki dua elemen dengan ukuran yang sama persis dan ingin menumpuknya. Karena masing-masing memiliki ukuran yang sama, yang bisa saya lakukan adalah membuatnya

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

hanya pada elemen terakhir. Dengan cara ini elemen pertama dimasukkan dengan benar, "mendorong" ketinggian orang tua, dan elemen kedua ditempatkan di atas.

Semoga ini membantu orang lain yang mencoba menumpuk 2+ elemen dengan ketinggian yang sama (tidak diketahui).

kraenhansen
sumber
1
NB: Dengan pendekatan ini, Anda masih perlu tahu mana elemen adalah lebih tinggi satu, sehingga Anda dapat position: aboslutedengan lainnya satu.
Alec
10

Berikut solusi lain yang menggunakan display: flex, bukan position: absolute atau 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>

Cornelius
sumber
Solusi bagus. Terima kasih!
Oleg Cherr
5

Saya harus mengatur

Container_height = Element1_height = Element2_height

.Container {
    position: relative;
}

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

.ElementOne {
    position:absolute;
}

.ElementTwo{
    position:absolute;
}

Gunakan dapat menggunakan z-index untuk mengatur mana yang akan di atas.

Arun Prasad ES
sumber
4

Berikut beberapa css yang dapat digunakan kembali yang akan menjaga tinggi setiap elemen tanpa menggunakan position: absolute:

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

Elemen pertama di Anda stackadalah latar belakang, dan yang kedua adalah latar depan.

Ken Mueller
sumber
2

Karena pemosisian absolut menghilangkan elemen dari posisi aliran dokumen: absolute bukanlah alat yang tepat untuk pekerjaan itu. Bergantung pada tata letak persis yang ingin Anda buat, Anda akan berhasil menggunakan margin negatif, posisi: relatif, atau bahkan mungkin transform: terjemahkan. Tunjukkan contoh apa yang ingin Anda lakukan, kami dapat membantu Anda dengan lebih baik.

Luiz Sócrate
sumber
1

Tentu saja, masalahnya adalah tentang mendapatkan kembali tinggi badan Anda. Tetapi bagaimana Anda bisa melakukannya jika Anda tidak mengetahui ketinggian sebelumnya? Nah, jika Anda tahu rasio aspek apa yang ingin Anda berikan ke penampung (dan menjaganya tetap responsif), Anda bisa mendapatkan kembali tinggi badan Anda dengan menambahkan bantalan ke turunan lain dari penampung, yang dinyatakan sebagai persentase.

Anda bahkan dapat menambahkan boneka divke wadah dan mengatur sesuatu seperti padding-top: 56.25%untuk memberikan elemen boneka tersebut ketinggian yang merupakan proporsi dari lebar wadah. Ini akan mengeluarkan container dan memberikan rasio tinggi lebar, dalam hal ini 16: 9 (56.25%).

Padding dan margin menggunakan persentase lebar, itulah triknya di sini.

Luke Puplett
sumber
0

Setelah banyak pengujian, saya telah memverifikasi bahwa pertanyaan asli sudah benar; hanya kehilangan beberapa pengaturan:

  • yang container_rowHARUS dimilikiposition: relative;
  • anak-anak (...), HARUS position: absolute; left:0;
  • untuk memastikan anak-anak (...) sejajar satu sama lain, container_rowharus memiliki gaya tambahan:
    • height:x; line-height:x; vertical-align:middle;
    • text-align:center; bisa, juga, membantu.
justaguestpassingby
sumber