Chrome / Safari tidak mengisi 100% tinggi induk fleksibel

235

Saya ingin memiliki menu vertikal dengan ketinggian tertentu.

Setiap anak harus mengisi ketinggian induk dan memiliki teks garis tengah.

Jumlah anak-anak adalah acak, jadi saya harus bekerja dengan nilai-nilai dinamis.

Div .containerberisi jumlah acak anak-anak ( .item) yang selalu harus mengisi ketinggian orangtua. Untuk mencapai itu saya menggunakan flexbox.

Untuk membuat tautan dengan teks disejajarkan dengan tengah saya menggunakan display: table-cellteknik. Tetapi menggunakan tampilan tabel membutuhkan menggunakan ketinggian 100%.

Masalah saya adalah itu .item-inner { height: 100% }tidak berfungsi di webkit (Chrome).

  1. Apakah ada perbaikan untuk masalah ini?
  2. Atau adakah teknik yang berbeda untuk membuat semua .itemmengisi ketinggian induk dengan teks yang lurus rata ke tengah?

Contoh di sini jsFiddle, harus dilihat di Firefox dan Chrome

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

Ricardo Castañeda
sumber
1
sekarang telah diperbaiki - bugs.chromium.org/p/chromium/issues/detail?id=426898
vsync
3
Ini tidak secara spesifik relevan dengan OP, tetapi mungkin relevan untuk googler yang mendarat di sini untuk "safari display absolute absolute 100% tidak berfungsi" atau yang serupa. Saya memiliki elemen seperti ini di dalam wadah fleksibel dan harus menentukan top:0dan left:0membuatnya muncul seperti yang diharapkan.
AlexMA
1
@vsync belum diperbaiki: stackoverflow.com/questions/46226298/...
TylerH

Jawaban:

408

Larutan

Gunakan wadah fleksibel bersarang.

Singkirkan persentase ketinggian. Singkirkan properti tabel. Singkirkan vertical-align. Hindari penentuan posisi absolut. Tetap dengan flexbox sepanjang jalan.

Oleskan display: flexke item fleksibel ( .item), menjadikannya wadah fleksibel. Ini secara otomatis mengatur align-items: stretch, yang memberitahu anak ( .item-inner) untuk memperluas ketinggian penuh dari induk.

Penting: Hapus ketinggian yang ditentukan dari item fleksibel agar metode ini berfungsi. Jika seorang anak memiliki ketinggian yang ditentukan (misalnya height: 100%), maka ia akan mengabaikan align-items: stretchkedatangan dari orang tua. Agar stretchdefault berfungsi, tinggi anak harus dihitung dengan auto (penjelasan lengkap ).

Coba ini (tidak ada perubahan pada HTML):

Demo jsFiddle


Penjelasan

Masalah saya adalah itu .item-inner { height: 100% }tidak berfungsi di webkit (Chrome).

Ini tidak berfungsi karena Anda menggunakan tinggi persentase dengan cara yang tidak sesuai dengan implementasi tradisional spesifikasi.

10.5 Tinggi konten: heightproperti

persentase
Menentukan tinggi persentase. Persentase dihitung sehubungan dengan ketinggian blok berisi kotak yang dihasilkan. Jika ketinggian blok yang mengandung tidak ditentukan secara eksplisit dan elemen ini tidak benar-benar diposisikan, nilai dihitung auto.

otomatis
Ketinggiannya tergantung pada nilai properti lainnya.

Dengan kata lain, agar persentase tinggi untuk bekerja pada anak dalam-aliran, orang tua harus memiliki tinggi yang ditetapkan.

Dalam kode Anda, wadah tingkat atas memiliki ketinggian yang ditentukan: .container { height: 20em; }

Wadah tingkat ketiga memiliki ketinggian yang ditentukan: .item-inner { height: 100%; }

Tetapi di antara mereka, wadah tingkat kedua - .item- tidak memiliki ketinggian yang ditentukan. Webkit melihatnya sebagai tautan yang hilang.

.item-innermemberitahu Chrome: beri sayaheight: 100% . Chrome mencari ke induk ( .item) untuk referensi dan menjawab: 100% dari apa? Saya tidak melihat apa-apa (mengabaikan flex: 1aturan yang ada). Akibatnya, itu berlaku height: auto(tinggi konten), sesuai dengan spesifikasi.

Firefox, di sisi lain, sekarang menerima tinggi fleksibel orangtua sebagai referensi untuk tinggi persentase anak. IE11 dan Edge juga menerima ketinggian fleksibel.

Juga, Chrome akan menerima flex-growsebagai referensi induk yang memadai jika digunakan bersama denganflex-basis (nilai numerik apa pun berfungsi ( autotidak akan), termasuk flex-basis: 0). Namun pada tulisan ini, solusi ini gagal di Safari.


Empat Solusi

1. Tentukan ketinggian pada semua elemen induk

Solusi lintas-browser yang andal adalah menentukan ketinggian pada semua elemen induk. Ini mencegah tautan yang hilang, yang oleh peramban berbasis Webkit dianggap sebagai pelanggaran terhadap spesifikasi.

Perhatikan itu min-heightdan max-heighttidak dapat diterima. Itu pasti heightproperti.

Lebih detail di sini: Bekerja dengan heightproperti CSS dan nilai persentase

2. Posisi Relatif & Mutlak CSS

Berlaku position: relativeuntuk orang tua dan position: absoluteanak.

Ukuran anak dengan height: 100%dan width: 100%, atau menggunakan sifat offset: top: 0, right: 0, bottom: 0, left: 0.

Dengan penentuan posisi absolut, persentase tinggi berfungsi tanpa ketinggian yang ditentukan pada induk.

3. Hapus wadah HTML yang tidak perlu (disarankan)

Apakah ada kebutuhan untuk dua kontainer di sekitar button? Mengapa tidak menghapus .itematau .item-inner, atau keduanya? Meskipun buttonelemen terkadang gagal sebagai wadah fleksibel , mereka bisa berupa benda lentur. Pertimbangkan untuk membuat buttonanak dari .containeratau .item, dan menghapus mark-up gratis.

Ini sebuah contoh:

4. Container Flex Bersarang (disarankan)

Singkirkan persentase ketinggian. Singkirkan properti tabel. Singkirkan vertical-align. Hindari penentuan posisi absolut. Tetap dengan flexbox sepanjang jalan.

Oleskan display: flexke item fleksibel ( .item), menjadikannya wadah fleksibel. Ini secara otomatis mengatur align-items: stretch, yang memberitahu anak ( .item-inner) untuk memperluas ketinggian penuh dari induk.

Penting: Hapus ketinggian yang ditentukan dari item fleksibel agar metode ini berfungsi. Jika seorang anak memiliki ketinggian yang ditentukan (misalnya height: 100%), maka ia akan mengabaikan align-items: stretchkedatangan dari orang tua. Agar stretchdefault berfungsi, tinggi anak harus dihitung dengan auto (penjelasan lengkap ).

Coba ini (tidak ada perubahan pada HTML):

jsFiddle

Michael Benjamin
sumber
3
Saya memperbaiki masalah saya menggunakan ketinggian: otomatis
Alfrex92
hanya beberapa komentar yang diambil dari tautan penjelasan pos luar biasa ini - "menyelaraskan-item: peregangan" membuat anak lentur melebar melintasi sumbu silang wadah - yaitu untuk merentangkan anak-anak ke ketinggian, wadah lentur harus memiliki arah fleksibel sebagai baris.
littlewhywhat
3
Saya dapat mengonfirmasi bahwa menggunakan wadah fleksibel bersarang berfungsi paling baik. Kami menggunakan flexbox secara tidak konsisten dalam menu kami. Alih-alih menggunakan flex: 1 dan display: flex pada wadah induk kami menggunakan tinggi: 100% di beberapa tempat. Semuanya berfungsi seperti yang diharapkan setelah kami mengganti definisi yang sesuai. Terima kasih @Michael_B untuk petunjuknya! :)
flocbit
1
@ Jamesames, CSS telah berkembang dari waktu ke waktu dan kompleks ;-)
DerMike
Setiap solusi harus menjadi jawaban yang berbeda. Bagaimana saya dapat memilih dalam solusi spesifik dengan cara ini?
Jp_
14

Solusi: Hapus height: 100%di .item-batin dan menambahkan display: flexdi .item

Demo: https://codepen.io/tronghiep92/pen/NvzVoo

nghiepit
sumber
Terima kasih, ini membantu saya. Apakah anak-anak yang lentur secara otomatis melakukan peregangan sesuai ketinggian wadah mereka? Apakah ini mengapa ini berhasil?
Reece Kenney
@ReeceKenney, ya, untuk pertanyaan Anda. Ini dijelaskan dalam jawaban saya. Lihat solusi # 4.
Michael Benjamin
10

Menentukan atribut flex ke wadah berfungsi untuk saya:

.container {
    flex: 0 0 auto;
}

Ini memastikan ketinggian diatur dan tidak tumbuh.

huseyin39
sumber
6

Untuk Mobile Safari Ada perbaikan Browser. Anda perlu menambahkan -webkit-box untuk perangkat iOS.

Ex.

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

jika Anda menggunakan align-items: stretch;properti untuk elemen induk, hapus height : 100%dari elemen turunan.

Narasinghe
sumber
2

Saya memiliki masalah serupa di iOS 8, 9 dan 10 dan info di atas tidak dapat memperbaikinya, namun saya menemukan solusi setelah seharian mengerjakan ini. Memang itu tidak akan bekerja untuk semua orang, tetapi dalam kasus saya item saya ditumpuk dalam kolom dan memiliki tinggi 0 padahal seharusnya tinggi konten. Mengganti css menjadi baris dan membungkus memperbaiki masalah. Ini hanya berfungsi jika Anda memiliki satu item dan mereka ditumpuk tetapi karena saya butuh waktu sehari untuk mengetahuinya, saya pikir saya harus membagikan perbaikan saya!

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

.item {
    width: 100%;
}
Desainer023
sumber
0

Saya memiliki bug serupa, tetapi saat menggunakan nomor tetap untuk tinggi dan bukan persentase. Itu juga wadah fleksibel di dalam tubuh (yang tidak memiliki ketinggian yang ditentukan). Tampaknya di Safari, wadah fleksibel saya memiliki ketinggian 9px karena alasan tertentu, tetapi di semua peramban lain ditampilkan ketinggian 100px yang benar yang ditentukan dalam stylesheet.

Saya berhasil membuatnya bekerja dengan menambahkan properti heightdan min-heightke kelas CSS.

Hal berikut ini berfungsi untuk saya di Safari 13.0.4 dan Chrome 79.0.3945.130:

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

Semoga ini membantu!

Carlton Lindsay
sumber