CSS: Bir yükseklik belirtmeden iki öğe üst üste nasıl konumlandırılır?


101

Tam olarak üst üste yerleştirmem gereken iki DIV var. Bununla birlikte, bunu yaptığımda, biçimlendirme tamamen bozulur çünkü içeren DIV, yükseklik yokmuş gibi davranır. Bunun beklenen davranış olduğunu düşünüyorum, position:absoluteancak bu iki öğeyi üst üste yerleştirmenin bir yolunu bulmam ve içerik genişledikçe kapsayıcıyı uzatmam gerekiyor:

Öğesinin sol üst kenarı, sayfanın sol üst kenarına .layer2tam olarak hizalanmalıdır.layer1

<!-- 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: absoluteo zaman kullanmak için doğru stil değil.
BoltClock

evet, position:absolutedoğru gelmiyor. Doğru stil ne olurdu?
Andrew

Do .layer1ve .layer2elementler bilinen bir büyüklüğe sahip?
mu çok kısa

Hayır, boyutları da bilinmemektedir.
Andrew

Yanıtlar:


82

Her şeyden önce, pozisyonu kesinlikle konumlandırılmış unsurlara dahil etmelisiniz, yoksa tuhaf ve kafa karıştırıcı davranışlarla karşılaşırsınız; muhtemelen top: 0; left: 0her iki kesinlikle konumlandırılmış öğeleriniz için de CSS'ye eklemek istersiniz . Kesin olarak konumlandırılmış öğelerin , belgenin gövdesinden ziyade üst öğelerine göre konumlandırılmasını istiyorsanız, position: relativeaçık olmasını da isteyeceksiniz :.container_row

Elemanın 'konumu: mutlak' varsa, kapsayıcı blok, 'mutlak', 'göreceli' veya 'sabit' bir 'konumu' ile en yakın ata tarafından oluşturulur ...

Sorununuz, position: absoluteöğeleri normal akıştan çıkarmasıdır :

Normal akıştan tamamen çıkarılır (sonraki kardeşler üzerinde etkisi yoktur). Mutlak şekilde konumlandırılmış bir kutu, normal akışlı çocuklar ve kesinlikle (ancak sabit değil) konumlanmış torunlar için yeni bir taşıyıcı blok oluşturur. Bununla birlikte, mutlak olarak konumlandırılmış bir elemanın içeriği diğer kutuların etrafından akmaz.

Bu, kesinlikle konumlandırılmış öğelerin ana öğelerinin boyutu üzerinde hiçbir etkisinin olmadığı ve ilk öğenizin <div class="container_row">sıfır yüksekliğe sahip olacağı anlamına gelir.

Dolayısıyla, ne kadar uzun olacaklarını bilmiyorsanız (veya eşdeğer olarak, yüksekliklerini de belirleyebilirsiniz), kesinlikle konumlandırılmış öğelerle yapmaya çalıştığınız şeyi yapamazsınız. Yükseklikleri belirleyebiliyorsanız, aynı yükseklikleri üzerine koyabilirsiniz .container_rowve her şey sıralanacaktır; Ayrıca , kesinlikle konumlandırılmış elemanlara yer bırakmak margin-topiçin saniyeye bir de koyabilirsiniz .container_row. Örneğin:

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


Harika cevap, teşekkürler! Sanırım yüksekliği javascript kullanarak dinamik olarak hesaplamam gerekebilir. Sadece o noktaya gelmemesini umuyordum. = [
Andrew

@Andrew: Evet, CSS'nin dikey boyutlandırma / konumlandırma / hizalama sistemine hoş geldiniz: Eğer şeylerin belirli boyutlarını bilmiyorsanız, genellikle şansınız kalmaz. Yatay şeylerle uğraşmak daha kolaydır, ancak çoğu hala "dinamik yerleşimli insanlar" yerine "sabit yerleşimli yazıcılar" tarafından tasarlanmış gibi kokuyor.
mu çok kısa

1
Gerek yok position: absolute. Lütfen kontrol edin: stackoverflow.com/a/51949049/1736186
bunun yerine

69

Aslında bu, konum olmadan absoluteve herhangi bir yükseklik belirtmeden mümkündür . Yapmanız gereken tek şey, display: gridüst öğe üzerinde kullanmak ve alt öğeleri aynı satır ve sütuna yerleştirmektir.

Lütfen HTML'nize göre aşağıdaki örneği kontrol edin. Sadece <span>ve bazı renkler ekledim , böylece sonucu görebilirsiniz.

z-indexGörünürlüğünü değiştirmek için alt öğelerin her birini kolayca değiştirebilirsiniz (hangisi üstte olmalıdır).

.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
Güzel. Ama adil olmak gerekirse, display: gridyedi yıl önce yoktu :)
mu çok kısa

Aşağıda @Cornelius tarafından yazılmış bir cevap daha var. flexGünümüzde çok daha iyi tarayıcı desteğine sahip olan kullanıyor .
Oleg Cherr

@muistooshort ama şu anda var ve bu sorunun pek çok görünümü var
boroboris

@boroboris Bu yüzden bu olumlu oylardan biri benim.
mu çok kısa

20

Harika cevap, "mu çok kısa". Ben de tam olarak aynı şeyi arıyordum ve yazınızı okuduktan sonra sorunuma uyan bir çözüm buldum.

Aynı boyutta iki öğeye sahiptim ve onları istiflemek istedim. Her biri aynı boyutta olduğu için yapabileceğim şey yapmaktı

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

sadece son elementte. Bu şekilde, birinci öğe, üst öğe yüksekliğini "iterek" doğru bir şekilde yerleştirilir ve ikinci öğe, üstüne yerleştirilir.

Bunun, aynı (bilinmeyen) yükseklikte 2'den fazla öğeyi istiflemeye çalışan diğer insanlara yardımcı olacağını umuyor.


1
Not: Bu yaklaşımla, diğerini yapabilmeniz position: abosluteiçin hangi öğenin daha uzun olduğunu bilmeniz gerekir .
Alec

12

İşte display: position yerine flex'i kullanan başka bir çözüm: mutlak veya 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>


Harika çözüm. Teşekkürler!
Oleg Cherr

5

Ayarlamak zorundaydım

Container_height = Element1_height = Element2_height

.Container {
    position: relative;
}

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

.ElementOne {
    position:absolute;
}

.ElementTwo{
    position:absolute;
}

Hangisinin en üstte olacağını ayarlamak için z-endeksini kullanabilirsiniz.


4

İşte her bir öğenin yüksekliğini kullanmadan koruyacak bazı yeniden kullanılabilir css'ler position: absolute:

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

Sizdeki ilk öğe stackarka plandadır ve ikincisi ön plandır.


2

Belge akış konumundan öğeleri kaldırarak mutlak konumlandırma nedeniyle: mutlak, iş için doğru araç değildir. Oluşturmak istediğiniz tam düzene bağlı olarak, negatif kenar boşlukları, konum: göreli veya hatta belki dönüştürme: çeviri kullanarak başarılı olacaksınız. Bize yapmak istediklerinizin bir örneğini gösterin, size daha iyi yardımcı olabiliriz.


1

Elbette, sorun tamamen boyunuzu geri almakla ilgili. Ama önceden yüksekliği bilmiyorsanız bunu nasıl yapabilirsiniz? Peki, konteynere hangi en boy oranını vermek istediğinizi biliyorsanız (ve duyarlı olmasını sağlayabilirsiniz), konteynerin başka bir çocuğuna yüzde olarak ifade edilen dolgu ekleyerek boyunuzu geri alabilirsiniz.

Kaba bir kukla bile ekleyebilir ve kukla elemana kabın genişliğinin bir oranı olan bir yükseklik vermek divgibi bir şey ayarlayabilirsiniz padding-top: 56.25%. Bu, kabı dışarı iter ve ona bir en boy oranı verir, bu durumda 16: 9 (% 56.25).

Dolgu ve kenar boşluğu, genişliğin yüzdesini kullanır, buradaki hile bu gerçekten.


0

Pek çok test yaptıktan sonra, orijinal sorunun zaten doğru olduğunu doğruladım; sadece birkaç ayar eksik:

  • container_rowİÇERMELİDİRposition: relative;
  • çocuklar (...), OLMALIDIR position: absolute; left:0;
  • Çocukların (...) tam olarak birbirlerinin üzerine gelmesini sağlamak container_rowiçin ek stillere sahip olmalıdır:
    • height:x; line-height:x; vertical-align:middle;
    • text-align:center; yardımcı olabilir.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.