Menggulir flexbox dengan konten yang meluap

214

masukkan deskripsi gambar di sini

Berikut kode yang saya gunakan untuk mencapai tata letak di atas:

.header {
  height: 50px;
}

.body {
  position: absolute;
  top: 50px;
  right: 0;
  bottom: 0;
  left: 0;
  display: flex;
}

.sidebar {
  width: 140px;
}

.main {
  flex: 1;
  display: flex;
  flex-direction: column;
}

.content {
  flex: 1;
  display: flex;
}

.column {
  padding: 20px;
  border-right: 1px solid #999;
}
<div class="header">Main header</div>
<div class="body">
  <div class="sidebar">Sidebar</div>

  <div class="main">
    <div class="page-header">Page Header. Content columns are below.</div>
    <div class="content">
      <div class="column">Column 1</div>
      <div class="column">Column 1</div>
      <div class="column">Column 1</div>
    </div>
  </div>
</div>

Saya menghilangkan kode yang digunakan untuk styling. Anda dapat melihat semuanya di pena .


Di atas berfungsi, tetapi ketika contentkonten daerah meluap, itu membuat seluruh halaman gulir. Saya hanya ingin area konten itu sendiri bergulir, jadi saya menambahkannya overflow: autoke contentdiv .

Masalah dengan ini sekarang adalah bahwa kolom itu sendiri tidak melampaui ketinggian orang tua mereka, sehingga perbatasan terputus di sana juga.

Inilah pena yang menunjukkan masalah pengguliran .

Bagaimana saya bisa mengatur contentarea untuk menggulir secara mandiri, sementara anak-anaknya masih melampaui contentketinggian kotak?

Joseph Silber
sumber

Jawaban:

264

Saya sudah bicara dengan Tab Atkins (penulis spec flexbox) tentang ini, dan inilah yang kami kemukakan:

HTML:

<div class="content">
    <div class="box">
        <div class="column">Column 1</div>
        <div class="column">Column 2</div>
        <div class="column">Column 3</div>
    </div>
</div>

CSS:

.content {
    flex: 1;
    display: flex;
    overflow: auto;
}

.box {
    display: flex;
    min-height: min-content; /* needs vendor prefixes */
}

Ini pulpennya:

  1. Kolom pendek direntangkan .
  2. Kolom yang lebih panjang meluap dan bergulir .

Alasan ini bekerja karena align-items: stretchtidak mengecilkan item yang jika mereka memiliki ketinggian intrinsik, yang dicapai di sini oleh min-content.

Joseph Silber
sumber
3
Mereka bekerja ketika tinggi orang tua tidak tergantung pada anak-anaknya, umumnya, yang terjadi di sini. min-height: 100% memang memperbaiki masalah stretch-even-when-kolom-are-short di Firefox (meskipun tidak di Chrome). Tidak yakin apakah itu bug Chrome atau bug Firefox.
dholbert
1
@dholbert - Tab Atkins membantu saya dengan ini. Saya telah memperbarui jawaban saya.
Joseph Silber
3
Perhatikan bahwa Firefox saat ini hanya mendukung "konten-min" untuk nilai lebar, bukan nilai tinggi - jadi ini tidak akan berfungsi di Firefox, jika itu penting bagi Anda. (Lihat misalnya bugzilla.mozilla.org/show_bug.cgi?id=852367 )
dholbert
2
@ debbert - Masalah dengan pena ini adalah bahwa mereka publik, sehingga siapa pun bisa mengubahnya. Saya mengambil kepemilikan mereka, jadi di sini Anda pergi: codepen.io/JosephSilber/pen/pmyHh
Joseph Silber
5
Ya, ini rusak di IE11
Steve
118

Saya baru saja menyelesaikan masalah ini dengan sangat elegan setelah banyak mencoba-coba.

Lihat posting blog saya: http://geon.github.io/programming/2016/02/24/flexbox-full-page-web-app-layout

Pada dasarnya, untuk membuat sel flexbox dapat digulir, Anda harus membuat semua orang tuanya overflow: hidden; , atau hanya akan mengabaikan pengaturan overflow Anda dan membuat orang tua lebih besar.

geon
sumber
11
Ini berhasil dalam kasus saya juga, tapi wow, saya benar-benar ingin melihat penjelasan mengapa itu bekerja. Sebagian besar waktu, saya menemukan spesifikasi CSS benar-benar tidak dapat dipahami untuk hal semacam ini.
markrian
2
Dari posting blog Anda: "Saya tidak tahu mengapa itu bekerja, dan spesifikasi mengatakan apa-apa" . Jadi, saya mencari penjelasan mengapa itu berhasil. Saya telah membaca spesifikasi, tetapi seperti yang Anda katakan, tidak ada yang melompat keluar.
markrian
3
Setelah memikirkannya lagi, saya pikir itu masuk akal. Perilaku default adalah untuk setiap div diperluas untuk memuat semua anak-anak itu, sehingga tidak akan ada limpahan untuk disembunyikan di node daun. Anda harus memaksakan overflow: disembunyikan dari atas DOM, jadi tidak ada orang tua yang memiliki kesempatan untuk mengakomodasi anak-anak itu sampai Anda turun ke simpul yang ingin Anda overflow dan gulir.
geon
3
Saya tidak yakin itu benar-benar menjelaskannya. Mengatur overflow untuk disembunyikan pada suatu elemen tidak menghentikannya berkembang menjadi mengandung semua anaknya, AFAIK. Menurut MDN: "Properti melimpah menentukan apakah akan klip konten, membuat bilah gulir atau hanya menampilkan konten ketika meluap wadah tingkat blok." Selain itu, pengaturan overflow ke apa pun selain yang terlihat membuat konteks pemformatan blok baru - tetapi itu tidak relevan, karena kontainer fleksibel sudah membuat konteks pemformatan blok mereka sendiri: developer.mozilla.org/en-US/docs/Web/Guide / CSS / ... .
markrian
1
Saya harus menambahkan bahwa saya setuju penjelasan Anda masuk akal secara intuitif , tetapi saya tidak berpikir itu penjelasan teknis yang akurat , yang saya inginkan. Hanya dengan benar-benar memahami alasannya saya dapat mengingat solusinya di masa depan!
markrian
55

Bekerja position:absolute;bersama dengan flex:

Posisikan item fleksibel dengan position: relative. Lalu di dalamnya, tambahkan <div>elemen lain dengan:

position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;

Ini memperluas elemen ke batas-batas induknya yang diposisikan relatif, tetapi tidak memungkinkan untuk memperpanjangnya. Di dalam, overflow: auto;maka akan berfungsi seperti yang diharapkan.

  • potongan kode yang disertakan dalam jawaban - Klik masukkan deskripsi gambar di sinidan kemudian klik Halaman penuhsetelah menjalankan potongan OR
  • Klik di sini untuk CODEPEN
  • Hasil: masukkan deskripsi gambar di sini

.all-0 {
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
}
p {
  text-align: justify;
}
.bottom-0 {
  bottom: 0;
}
.overflow-auto {
  overflow: auto;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css" rel="stylesheet"/>


<div class="p-5 w-100">
  <div class="row bg-dark m-0">
    <div class="col-sm-9 p-0 d-flex flex-wrap">
      <!-- LEFT-SIDE - ROW-1 -->
      <div class="row m-0 p-0">
        <!-- CARD 1 -->
        <div class="col-md-8 p-0 d-flex">
          <div class="my-card-content bg-white p-2 m-2 d-flex flex-column">
            <img class="img img-fluid" src="https://via.placeholder.com/700x250">
            <h4>Heading 1</h4>
            <p>
              Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old...
          </div>
        </div>
        <!-- CARD 2 -->
        <div class="col-md-4 p-0 d-flex">
          <div class="my-card-content bg-white p-2 m-2 d-flex flex-column">
            <img class="img img-fluid" src="https://via.placeholder.com/400x250">
            <h4>Heading 1</h4>
            <p>
              Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old...
          </div>
        </div>
      </div>
      <div class="row m-0">
        <!-- CARD 3 -->
        <div class="col-md-4 p-0 d-flex">
          <div class="my-card-content bg-white p-2 m-2 d-flex flex-column">
            <img class="img img-fluid" src="https://via.placeholder.com/400x250">
            <h4>Heading 1</h4>
            <p>
              Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old...
          </div>
        </div>
        <!-- CARD 4 -->
        <div class="col-md-4 p-0 d-flex">
          <div class="my-card-content bg-white p-2 m-2 d-flex flex-column">
            <img class="img img-fluid" src="https://via.placeholder.com/400x250">
            <h4>Heading 1</h4>
            <p>
              Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old...
          </div>
        </div>
        <!-- CARD 5-->
        <div class="col-md-4 p-0 d-flex">
          <div class="my-card-content bg-white p-2 m-2 d-flex flex-column">
            <img class="img img-fluid" src="https://via.placeholder.com/400x250">
            <h4>Heading 1</h4>
            <p>
              Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old...
          </div>
        </div>
      </div>
    </div>
    <div class="col-sm-3 p-0">
      <div class="bg-white m-2 p-2 position-absolute all-0 d-flex flex-column">
        <h4>Social Sidebar...</h4>
        <hr />
        <div class="d-flex overflow-auto">
          <p>
            Topping candy tiramisu soufflé fruitcake ice cream chocolate bar. Bear claw ice cream chocolate bar donut sweet tart. Pudding cupcake danish apple pie apple pie. Halva fruitcake ice cream chocolate bar. Bear claw ice cream chocolate bar donut sweet tart.
            opping candy tiramisu soufflé fruitcake ice cream chocolate bar. Bear claw ice cream chocolate bar donut sweet tart. Pudding cupcake danish apple pie apple pie. Halva fruitcake ice cream chocolate bar. Bear claw ice cream chocolate bar donut sweet tart.
            opping candy tiramisu soufflé fruitcake ice cream chocolate bar. Bear claw ice cream chocolate bar donut sweet tart. Pudding cupcake danish apple pie apple pie. Halva fruitcake ice cream chocolate bar. Bear claw ice cream chocolate bar donut sweet tart.
            Pudding cupcake danish apple pie apple pie. Halvafruitcake ice cream chocolate bar. Bear claw ice cream chocolate bar donut sweet tart. Pudding cupcake danish apple pie apple pie. Halvafruitcake ice cream chocolate bar. Bear claw ice cream
            chocolate bar donut sweet tart. Pudding cupcake danish apple pie apple pie. Halvafruitcake ice cream chocolate bar. Bear claw ice cream chocolate bar donut sweet tart. Pudding cupcake danish apple pie apple pie. Halvafruitcake ice cream chocolate
            bar. Bear claw ice cream chocolate bar donut sweet tart. Pudding cupcake danish apple pie apple pie. Halva
        </div>
      </div>
    </div>
  </div>

Semoga berhasil...

Akash
sumber
2
Solusi ini sangat berguna jika komponen di dalam memiliki set padding karena akan mengunci dengan baik di posisi di mana pun Anda inginkan. Jauh lebih sederhana. (Ya, Anda bisa mengaturnya box-sizing: border-boxtetapi itu bisa lebih rumit untuk kontrol pihak ketiga tertentu).
Simon_Weaver
2
kamu menyelamatkan malamku!
Botea Florin
2
Terima kasih. Entah bagaimana saya kecewa karena ini perlu, tapi saya bersyukur atas sarannya!
Mathias
9

Agak terlambat tetapi ini bisa membantu: http://webdesign.tutsplus.com/tutorials/how-to-make-respon-scrollable-panels-with-flexbox--cms-23269

Pada dasarnya Anda perlu memasukkan html, bodyke , height: 100%; dan membungkus semua konten Anda menjadi a<div class="wrap"> <!-- content --> </div>

CSS:

html, body {
  height: 100%;
}

.wrap {
  height: 100vh;
  display: flex;
}

Bekerja untukku. Semoga ini bisa membantu

Doua Beri
sumber
Anda harus sangat berhati-hati saat menggunakan "height: 100vh" karena ukurannya berbeda di iOS Safari vs Android. Yang satu memperhitungkan ketinggian bilah URL dan yang lain tidak.
Sean Anderson
7

Tambahkan ini:

align-items: flex-start;

ke aturan untuk .content {}. Itu memperbaikinya di pena Anda untuk saya, setidaknya (di kedua Firefox & Chrome).

Secara default, .contenthas align-items: stretch, yang membuatnya mengukur semua anak dengan tinggi otomatis agar sesuai dengan tinggi badannya sendiri, per http://dev.w3.org/csswg/css-flexbox/#algo-stretch . Sebaliknya, nilai flex-startmemungkinkan anak-anak menghitung ketinggian mereka sendiri, dan menyelaraskan diri mereka sendiri pada ujung awalnya (dan meluap, dan memicu bilah gulir).

dholbert
sumber
Selain itu, kolom tidak akan lagi sama tingginya, yang merupakan salah satu daya tarik utama dari flexbox.
Joseph Silber
BAIK. Tidak jelas bagi saya bahwa itu adalah kendala desain - maaf.
dholbert
Saran bagus
Vlad
1

Salah satu masalah yang saya temui adalah bahwa untuk memiliki scrollbar elemen perlu ketinggian yang ditentukan (dan bukan sebagai%).

Caranya adalah dengan menumpuk satu set div lain di dalam setiap kolom, dan mengatur tampilan induk kolom untuk melentur dengan arah-fleksibel: kolom.

    html, body {
        height: 100%;
        margin: 0;
        padding: 0;
    }

    body {
        overflow-y: hidden;
        overflow-x: hidden;
        color: white;
    }

    .base-container {
        display: flex;
        flex: 1;
        flex-direction: column;
        width: 100%;
        height: 100%;
        overflow-y: hidden;
        align-items: stretch;
    }

    .title {
        flex: 0 0 50px;
        color: black;
    }

    .container {
        flex: 1 1 auto;
        display: flex;
        flex-direction: column;
    }

        .container .header {
            flex: 0 0 50px;
            background-color: red;
        }

        .container .body {
            flex: 1 1 auto;
            display: flex;
            flex-direction: row;
        }

            .container .body .left {
                display: flex;
                flex-direction: column;
                flex: 0 0 80px;
                background-color: blue;
            }
                .container .body .left .content,
                .container .body .main .content,
                .container .body .right .content {
                    flex: 1 1 auto;
                    overflow-y: auto;
                    height: 100px;
                }
                .container .body .main .content.noscrollbar {
                    overflow-y: hidden;
                }

            .container .body .main {
                display: flex;
                flex-direction: column;
                flex: 1 1 auto;
                background-color: green;
            }

            .container .body .right {
                display: flex;
                flex-direction: column;
                flex: 0 0 300px;
                background-color: yellow;
                color: black;
            }

    .test {
        margin: 5px 5px;
        border: 1px solid white;
        height: calc(100% - 10px);
    }
</style>

Dan inilah htmlnya:

<div class="base-container">
    <div class="title">
        Title
    </div>
    <div class="container">
        <div class="header">
            Header
        </div>
        <div class="body">
            <div class="left">
                <div class="content">
                    <ul>
                        <li>1</li>
                        <li>2</li>
                        <li>3</li>
                        <li>4</li>
                        <li>5</li>
                        <li>6</li>
                        <li>7</li>
                        <li>8</li>
                        <li>9</li>
                        <li>10</li>
                        <li>12</li>
                        <li>13</li>
                        <li>14</li>
                        <li>15</li>
                        <li>16</li>
                        <li>17</li>
                        <li>18</li>
                        <li>19</li>
                        <li>20</li>
                        <li>21</li>
                        <li>22</li>
                        <li>23</li>
                        <li>24</li>
                    </ul>
                </div>
            </div>
            <div class="main">
                <div class="content noscrollbar">
                    <div class="test">Test</div>
                </div>
            </div>
            <div class="right">
                <div class="content">
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>Right</div>
                    <div>End</div>
                </div>
            </div>
        </div>
    </div>
</div>

https://jsfiddle.net/LiamFlavelle/czpjdfr4/

Liam
sumber
0

Solusi untuk masalah ini adalah dengan menambahkan overflow: auto;.content untuk membuat pembungkus konten dapat digulir.

Selain itu, ada keadaan yang terjadi bersama dengan pembungkus Flexbox dan overflowedkonten yang dapat digulir seperti codepen ini .

Solusinya adalah menambahkan overflow: hidden (or auto);induk dari pembungkus (diatur dengan overflow: otomatis;) di sekitar konten besar.

Kenali
sumber