Pusatkan DIV yang tidak seimbang menggunakan CSS

23

Saya memusatkan DIV di dalam DIV lain menggunakan flexbox. Pikirkan jendela dialog yang muncul di tengah layar bila diperlukan.

Ini berfungsi dengan baik, namun akan terlihat jauh lebih baik jika ruang di atas dan di bawah dialog tidak persis sama, memiliki 40% dari ruang yang tersisa berada di atas dan 60% di bawah dialog. Itu menjadi rumit karena ketinggian dialog bervariasi dengan jumlah teks di dalamnya.

Jadi misalnya, jika tinggi browser 1000 px, dan tinggi jendela dialog adalah 400 px, saya ingin ruang vertikal yang tersisa (600 px) menjadi 240 px di atas dan 360 px di bawah dialog. Saya bisa melakukannya dengan Javascript, tapi saya ingin tahu apakah ada cara pintar dengan CSS. Saya mencoba menambahkan margin bawah ke #dialogBox DIV, tetapi itu tidak berfungsi ketika tinggi dialog semakin mendekati tinggi browser.

#dialogBoxPanel
  {
  position:absolute;
  display:flex;
  align-items:center;
  justify-content:center;
  left:0px;
  top:0px;
  width:100%;
  height:100%;
}
#dialogBox
  {
  width:350px;
}
<div id="dialogBoxPanel">
  <div id="dialogBox">Text</div>
</div>

Björn Morén
sumber
Apakah Anda memerlukan panel luar untuk menutupi seluruh viewport? Jika tidak, saya akan pergi dengan solusi dari css-tricks.com/centering-css-complete-guide , bagian "Baik Secara Horisontal dan Vertikal / Apakah elemen lebar dan tinggi tidak diketahui?", Dan memodifikasi nilai persentase terjemahan. (Dan bahkan jika Anda benar-benar membutuhkan ukuran viewport penuh induk [latar belakang?], Anda harus dapat menggabungkan keduanya - menghapus barang fleksibel, tetap menginap.)
04FS
Ya saya memiliki efek peredupan pada panel luar sehingga perlu untuk menutupi seluruh viewport. Tapi saya bisa menambahkan DIV lain di dalamnya, dan solusi Anda akan berfungsi dengan baik. Terima kasih 04FS!
Björn Morén
Demi akurasi, Anda berbicara tentang perataan vertikal, bukan pemusatan.
Michael Benjamin

Jawaban:

11

Gunakan elemen pseudo dan arah kolom untuk mensimulasikan ruang putih. Cukup sesuaikan flex-growelemen pseudo untuk mengontrol berapa banyak ruang kosong yang harus diambil masing-masing. Flex-grow yang setara akan memberikan ruang yang sama:

Anda juga dapat menggunakan 2dan 3. Kami hanya perlu menjaga rasio yang sama:

Gagasan lain adalah menggunakan nilai teratas sama dengan 40%dan memperbaiki posisi dengan menerjemahkan (logika yang sama dengan 50%saat pemusatan)

#dialogBoxPanel {
  position: absolute;;
  left: 0px;
  top: 0px;
  width: 100%;
  height: 100%;
  /* the center */
  background:linear-gradient(red,red) center/100% 1px no-repeat;
}

#dialogBox {
  position:relative;
  top:40%;
  width: 350px;
  transform:translateY(-40%);
  margin:auto;
  border:1px solid;
}
<div id="dialogBoxPanel">
  <div id="dialogBox">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc hendrerit diam eu nisl fringilla ornare. Pellentesque aliquam quam et tellus egestas sodales. Interdum et malesuada fames ac ante ipsum primis in faucibus. Proin bibendum,</div>
</div>

Temani Afif
sumber
Terima kasih banyak Temani! Kedua solusi bekerja dengan sempurna, dan tampak identik kecuali untuk kasus khusus di mana dialog lebih tinggi daripada browser. Solusi pertama menjaga bagian atas dialog tetap sejajar dengan bagian atas browser, memotong di bagian bawah. Tanaman kedua bagian bawah dan atas. Hanya masalah preferensi.
Björn Morén
5

Solusi ini menggunakan display: grid, ini fitur baru jadi pastikan untuk memeriksa dukungan browser dan klik di sini untuk mempelajari lebih lanjut.

Ini adalah garis yang mengontrol ruang atas dan bawah:

grid-template-rows: 40fr [content-start] auto [content-end] 60fr;

Konten teks potongan dapat diedit untuk Anda untuk memeriksa bahwa kotak tetap berada di tengah bahkan jika ketinggiannya berubah.

#dialogBoxPanel {
    display: grid;
    place-content: center;
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    grid-template-rows: 40fr [content-start] auto [content-end] 60fr;
}
#dialogBox {
    border: 1px solid;
    width: 350px;
    grid-area: content;
}
<div id="dialogBoxPanel">
   <div id="dialogBox" contenteditable>Text</div>
</div>

rafaelcastrocouto
sumber
1
Saya akan mempertimbangkan penggunaan 4fr auto 6fr. Apa yang Anda miliki berfungsi tetapi dengan beberapa overflow karena 40% + 60% + 1fr akan selalu lebih besar dari 100% dan Anda memusatkan sehingga overlow akan dibagi rata dari atas dan bawah: jsfiddle.net/cobutn0e/2 . Anda juga akan melihat bahwa itu tidak 100% seperti yang diharapkan
Temani Afif
Saya baru saja mengubah 1fr menjadi otomatis, saya lebih suka membiarkannya% untuk mencocokkan nilai pertanyaan. Terima kasih banyak untuk menunjukkan kesalahan!
rafaelcastrocouto
otomatis dan 1fr akan memberikan hasil yang sama dalam kasus Anda, masalahnya adalah penggunaan persentase; 1fr=minmax(auto,1fr)dan dalam kasus Anda itu akan jatuh ke autokarena tidak ada ruang kosong sejak 40% + 60% = 100% (itu sebabnya Anda akan selalu memiliki meluap)
Temani Afif
1
di sini ada biola lain untuk mengilustrasikan poin saya: jsfiddle.net/cobutn0e/3 perhatikan bagaimana 3 pertama adalah sama, yang ketiga jatuh ke 0 dan yang terakhir adalah apa yang saya sarankan
Temani Afif
Sekarang saya mengerti, masuk akal. Akan menggunakan 40fr dan 60fr karena itu sama di akhir hari. Sekali lagi terima kasih telah meluangkan waktu untuk mengajari saya!
rafaelcastrocouto
4

Anda dapat menambahkan div spacer dan mengatur flex-grow dengan rasio 4: 6.

#dialogBoxPanel {
  position: absolute;
  display: flex;
  flex-direction: column;
  align-items: center;

  left: 0px;
  top: 0px;
  width: 100%;
  height: 100%;
}

#dialogBox {
  width: 350px;
  border: 1px solid black;
}

.spacer-top{
  flex-grow: 4;
}
.spacer-bottom{
  flex-grow: 6;
<div id="dialogBoxPanel">
  <div class="spacer-top"></div>
  <div id="dialogBox">Text</div>
  <div class="spacer-bottom"></div>
</div>

Itay Gal
sumber
Baru sekarang melihat jawaban @Temani Afif, tetapi bekerja sama dengan "setelah" dan "sebelum"
Itay Gal
0

Cara sederhana menggunakan posisi dan margin, saya berasumsi bahwa tinggi dialog Anda selalu 40% dari tinggi browser.

.modal{
            max-height:50%;
            width:400px;
            margin: 10% auto 5% auto;
            position:absolute;
            top:0;
            bottom:0;
            right:0;
            left:0;
            overflow-y: auto
        }
        .modal-body{
            background-color: beige;
            padding: 20px;
            line-height: 21px
        }

HTML

<div class="modal">
 <div class="modal-body">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea </div>
</div>
Anshul Chaurasia
sumber
Hai selamat datang, lain kali tolong baca pertanyaan dengan seksama, ini menyatakan: "tinggi dialog bervariasi dengan jumlah teks di dalamnya."
rafaelcastrocouto
1
@rafaelcastrocouto - sekarang mengendalikannya melalui tinggi maksimum dalam persentase, karena membiarkannya tanpa tinggi tidak akan menyelesaikan pertanyaan tujuan estetika ruang atas dan bawah.
Anshul Chaurasia