Chrome / Safari,% 100 esnek ebeveyn yüksekliğini doldurmuyor


235

Belirli bir yükseklikte dikey bir menüye sahip olmak istiyorum.

Her çocuk ebeveynin yüksekliğini doldurmalı ve ortalanmış metin içermelidir.

Çocuk sayısı rastgele, bu yüzden dinamik değerlerle çalışmak zorundayım.

Div .container, .itemher zaman ebeveynin yüksekliğini doldurmak zorunda olan rastgele sayıda çocuk ( ) içerir. Bunu başarmak için flexbox kullandım.

Ortaya hizalanmış metinle bağlantı yapmak için display: table-cellteknik kullanıyorum . Ancak tablo ekranlarını kullanmak% 100 yükseklik gerektirir.

Benim sorunum bu .item-inner { height: 100% }webkit (Chrome) çalışmıyor.

  1. Bu sorunun bir çözümü var mı?
  2. Yoksa tüm .itemmetni ebeveynin yüksekliğini ortada dikey metinle dolduracak farklı bir teknik var mı?

Örnek jsFiddle, Firefox ve Chrome'da görüntülenmelidir

.container {
  height: 20em;
  display: flex;
  flex-direction: column;
  border: 5px solid black
}
.item {
  flex: 1;
  border-bottom: 1px solid white;
}
.item-inner {
  height: 100%;
  width: 100%;
  display: table;
}
a {
  background: orange;
  display: table-cell;
  vertical-align: middle;
}
<div class="container">
  <div class="item">
    <div class="item-inner">
      <a>Button</a>
    </div>
  </div>

  <div class="item">
    <div class="item-inner">
      <a>Button</a>
    </div>
  </div>

  <div class="item">
    <div class="item-inner">
      <a>Button</a>
    </div>
  </div>
</div>



3
Bu özellikle OP ile ilgili değildir, ancak buraya "safari ekran mutlak yüksekliği% 100 çalışmıyor" veya benzeri bir şey için gelen Google çalışanları için alakalı olabilir. Ben esnek bir konteyner içinde böyle bir eleman var ve belirtmek top:0ve left:0beklendiği gibi görünmesi gerekiyordu.
AlexMA

1
@vsync henüz düzeltilmedi: stackoverflow.com/questions/46226298/…
TylerH

Yanıtlar:


408

Çözüm

İç içe geçmiş esnek kaplar kullanın.

Yüzde yüksekliklerinden kurtulun. Tablo özelliklerinden kurtulun. Kurtul vertical-align. Mutlak konumlandırmadan kaçının. Sadece flexbox ile sonuna kadar devam edin.

display: flexEsneme maddesine ( .item) uygulayın ve esneyerek esnek bir kap yapın. Bu align-items: stretch, çocuğa ( .item-inner) ebeveynin tam yüksekliğini genişletmesini söyleyen otomatik olarak ayarlanır .

Önemli: Bu yöntemin çalışması için esnek nesnelerden belirtilen yükseklikleri kaldırın. Bir çocuğun yüksekliği belirtilmişse (örn. height: 100%), O zaman align-items: stretchebeveynin gelmesini göz ardı eder . İçin stretchçalışmalarına varsayılan çocuğun yüksekliği hesaplamak gerekir auto (tam açıklama ).

Bunu deneyin (HTML'de değişiklik yok):

jsFiddle demosu


açıklama

Benim sorunum bu .item-inner { height: 100% }webkit (Chrome) çalışmıyor.

Çalışmıyor çünkü yüzde yüksekliğini, spesifikasyonun geleneksel uygulamasına uymayan bir şekilde kullanıyorsunuz.

10.5 İçerik yüksekliği: heightözellik

yüzde
Yüzde yüksekliğini belirtir. Yüzde, üretilen kutunun içerdiği bloğun yüksekliğine göre hesaplanır. Kapsayıcı bloğun yüksekliği açıkça belirtilmezse ve bu öğe tam olarak konumlandırılmazsa, değer hesaplanır auto.

Oto
Yükseklik, diğer özelliklerin değerlerine bağlıdır.

Diğer bir deyişle, yüzde yüksekliğin bir akış içi çocuk üzerinde çalışması için, ebeveynin ayarlanmış bir yüksekliğe sahip olması gerekir .

Kodunuzda, üst düzey kapsayıcı tanımlanmış bir yüksekliğe sahiptir: .container { height: 20em; }

Üçüncü seviye kabın belirlenmiş bir yüksekliği vardır: .item-inner { height: 100%; }

Ama aralarında, ikinci seviye konteyner - .item- değil tanımlanmış bir yüksekliğe sahiptir. Webkit bunu eksik bir bağlantı olarak görüyor.

.item-innerChrome'a ​​söylüyor: verheight: 100% . Chrome .item, başvuru için parent ( ) öğesine bakar ve yanıt verir: Neyin% 100'ü? Hiçbir şey görmüyorum ( flex: 1orada olan kuralı görmezden gelmek ). Sonuç olarak, geçerliheight: auto spesifikasyona uygun olarak (içerik yüksekliği) .

Öte yandan Firefox, artık bir ebeveynin esnek yüksekliğini çocuğun yüzde yüksekliğine referans olarak kabul ediyor. IE11 ve Edge esnek yükseklikleri de kabul eder.

Ayrıca, Chrome ile bağlantılı olarak kullanıldığında (varsa, herhangi bir sayısal değer işe yarar ( olmaz)) flex-growyeterli bir üst referans olarak kabul eder . Ancak bu yazı itibariyle bu çözüm Safari'de başarısız oluyor.flex-basisautoflex-basis: 0


Dört Çözüm

1. Tüm üst öğelerde yükseklik belirtme

Güvenilir bir çapraz tarayıcı çözümü, tüm üst öğelerde yükseklik belirtmektir. Bu, Webkit tabanlı tarayıcıların spesifikasyonun ihlal edildiğini düşündüğü eksik bağlantıları önler.

Unutmayın min-heightve max-heightkabul edilemez. heightMülkiyet olmalı .

Daha fazla ayrıntı burada: CSS heightözelliği ve yüzde değerleriyle çalışma

2. CSS Göreli ve Mutlak Konumlandırma

Ebeveyne position: relativeve position: absoluteçocuğa uygulayın.

Boyutu ile çocuk height: 100%ve width: 100%ya kullanmak ofset özellikleri: top: 0, right: 0, bottom: 0,left: 0 .

Mutlak konumlandırma ile yüzde yüksekliği, üst öğe üzerinde belirli bir yükseklik olmadan çalışır.

3. Gereksiz HTML kapsayıcılarını kaldırın (önerilir)

Etrafta iki konteynere ihtiyaç var mı button? Neden kaldırmaz .itemya .item-inner, ya da her ikisi? buttonÖğeler bazen esnek kaplar olarak başarısız olsa da, esnek öğeler olabilirler. buttonBir çocuk yapmayı .containerveya .itemzahmetli işaretlemeyi kaldırmayı düşünün .

İşte bir örnek:

4. İç içe Flex Konteynerler (önerilir)

Yüzde yüksekliklerinden kurtulun. Tablo özelliklerinden kurtulun. Kurtul vertical-align. Mutlak konumlandırmadan kaçının. Sadece flexbox ile sonuna kadar devam edin.

display: flexEsneme maddesine ( .item) uygulayın ve esneyerek esnek bir kap yapın. Bu align-items: stretch, çocuğa ( .item-inner) ebeveynin tam yüksekliğini genişletmesini söyleyen otomatik olarak ayarlanır .

Önemli: Bu yöntemin çalışması için esnek nesnelerden belirtilen yükseklikleri kaldırın. Bir çocuğun yüksekliği belirtilmişse (örn. height: 100%), O zaman align-items: stretchebeveynin gelmesini göz ardı eder . İçin stretchçalışmalarına varsayılan çocuğun yüksekliği hesaplamak gerekir auto (tam açıklama ).

Bunu deneyin (HTML'de değişiklik yok):

jsFiddle


3
Yüksekliği kullanarak
sorunumu çözdüm

sadece bu büyük yazının açıklama bağlantısından alınan bazı açıklamalar - "hizalama öğeleri: streç" esnek çocukları kabın çapraz ekseni boyunca genişlemesini sağlar - yani çocukları yüksekliğe kadar uzatmak için, esnek kabın esnek yönü olmalıdır satır olarak.
littlewhywhat

3
İç içe geçmiş esnek kapların kullanılmasının en iyi sonucu verdiğini doğrulayabilirim. Menüimizde flexbox'u tutarsız kullandık. Flex: 1 ve display: flex kullanmak yerine ana kaplarda bazı yerlerde yükseklik:% 100 kullandık. Karşılık gelen tanımları değiştirdikten sonra her şey beklendiği gibi çalıştı. @Michael_B ipucu için teşekkürler! :)
Flocbit

1
@JamesHarrington, CSS zamanla büyüdü ve karmaşık ;-)
DerMike

Her çözüm farklı bir cevap olmalıdır. Belirli bir çözümde bu şekilde nasıl oy kullanabilirim?
Jp_


10

Benim için çalışılan kaba esnek bir özellik belirtmek:

.container {
    flex: 0 0 auto;
}

Bu, yüksekliğin ayarlanmasını ve aynı zamanda büyümemesini sağlar.


6

Mobil Safari için Bir Tarayıcı düzeltmesi var. iOS cihazlar için -webkit-box eklemeniz gerekir .

Ör.

display: flex;
display: -webkit-box;
flex-direction: column;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-webkit-flex-direction: column;
align-items: stretch;

align-items: stretch;üst öğe için özellik kullanıyorsanız height : 100%, alt öğeden kaldırın .


2

İOS 8, 9 ve 10'da benzer bir sorun yaşadım ve yukarıdaki bilgiler düzeltemedi, ancak bunun üzerinde çalıştıktan bir gün sonra bir çözüm buldum. Herkes için işe yaramadı, ancak benim durumumda öğelerim bir sütunda istiflendi ve içerik yüksekliği olması gerektiğinde 0 yüksekliğe sahipti. Css'in satır ve sarma olacak şekilde değiştirilmesi sorunu düzeltti. Bu sadece tek bir öğeniz varsa işe yarar ve yığılmış ama bunu bulmak için bir günümden beri düzeltmemi paylaşmam gerektiğini düşündüm!

.wrapper {
    flex-direction: column; // <-- Remove this line
    flex-direction: row; // <-- replace it with
    flex-wrap: wrap; // <-- Add wrapping
}

.item {
    width: 100%;
}

0

Benzer bir hata vardı, ancak yükseklik için sabit bir sayı kullanırken ve yüzde değil. Ayrıca vücut içinde (yüksekliği belirlenmiş olmayan) esnek bir kaptı. Safari'de, esnek kabımın bir nedenden ötürü 9 piksel yüksekliğe sahip olduğu ortaya çıktı, ancak diğer tüm tarayıcılarda stil sayfasında belirtilen doğru 100 piksel yüksekliğini görüntüledi.

CSS sınıfına hem heightve min-heightözelliklerini ekleyerek çalışmayı başardım .

Aşağıdakiler benim için Safari 13.0.4 ve Chrome 79.0.3945.130'da çalıştı:

.flex-container {
  display: flex;
  flex-direction: column;
  min-height: 100px;
  height: 100px;
}

Bu yardımcı olur umarım!

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.