Taşan içeriğe sahip bir flexbox'ı kaydırma


214

resim açıklamasını buraya girin

Yukarıdaki düzeni elde etmek için kullandığım kod İşte :

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

Stil için kullanılan kodu atladım. Bunların hepsini kalemde görebilirsiniz .


Yukarıdakiler işe yarar, ancak contentalanın içeriği taştığında tüm sayfayı kaydırır. Bu yüzden sadece, kaydırma içerik alanını kendisi istiyor diye ekledim overflow: autoiçin contentdiv .

Şimdi buradaki sorun, sütunların kendilerinin ebeveynlerinin yüksekliğinin ötesine uzanmamasıdır, bu nedenle sınırlar da orada kesilir.

İşte kaydırma sorununu gösteren kalem .

contentÇocukları contentkutunun yüksekliğinin ötesine uzanırken alanı bağımsız olarak kaydırmak için nasıl ayarlayabilirim ?

Yanıtlar:


264

Bu konuda Tab Atkins (flexbox spec yazarı) ile konuştum, ve biz bu ile geldi:

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 */
}

İşte kalemler:

  1. Kısa sütunlar uzatılıyor .
  2. Daha uzun sütun taşma ve kaydırma .

Bunun çalışmasının nedeni align-items: stretch, burada gerçekleşen içsel bir yüksekliğe sahipse öğelerini daraltmamasıdır min-content.


3
Ebeveynin boyu genellikle çocuklarına bağlı olmadığında çalışırlar, genellikle burada durum böyle. min-height:% 100 gerçekten de Firefox'ta (Chrome'da olmasa da) sütunlarda gerginlik olduğunda bile sorununuzu çözer. Bunun bir Chrome hatası mı yoksa bir Firefox hatası mı olduğu konusunda hazırlıklı değilsiniz.
dholbert

1
@dholbert - Tab Atkins bu konuda bana yardımcı oldu. Cevabımı güncelledim.
Joseph Silber

3
Firefox'un şu anda yükseklik değerleri için değil, genişlik değerleri için yalnızca "min-içerik" i desteklediğini unutmayın; bu, sizin için önemliyse bu Firefox'ta çalışmaz. (Bkz. Örneğin bugzilla.mozilla.org/show_bug.cgi?id=852367 )
dholbert

2
@dholbert - Bu kalemlerle ilgili sorun halka açık olmalarıdır, böylece herkes onları değiştirebilir. Onların sahipliğini aldım, işte gidiyorsunuz: codepen.io/JosephSilber/pen/pmyHh
Joseph Silber

5
Evet, bu IE11'de kırıldı
Steve

119

Çok fazla deneme yanılma sonrasında bu sorunu çok zarif bir şekilde çözdüm.

Blog gönderime göz atın: http://geon.github.io/programming/2016/02/24/flexbox-full-page-web-app-layout

Temel olarak, bir flexbox hücresini kaydırılabilir yapmak için, tüm ebeveynlerini yapmanız gerekir overflow: hidden;, yoksa taşma ayarlarınızı göz ardı eder ve bunun yerine ebeveyni büyütür .


11
Bu benim durumumda da işe yaradı, ama vay be, neden işe yaradığına dair bir açıklama görmek istiyorum . Çoğu zaman, CSS özelliklerinin bu tür şeyler için tamamen anlaşılmaz olduğunu düşünüyorum.
markrian

2
Blog gönderinizden: "Neden işe yaradığına dair hiçbir fikrim yok ve özellikler de hiçbir şey söylemiyor" . Bu yüzden, neden işe yaradığına dair bir açıklama arıyorum. Teknik özellikleri gözden kaçırdım, ama dediğin gibi, orada hiçbir şey atlamadı.
markrian

3
Biraz daha düşündükten sonra, mantıklı olduğunu düşünüyorum. Varsayılan davranış, her div'in tüm alt öğelerini içerecek şekilde genişlemesidir, bu nedenle yaprak düğümlerinde gizlenecek herhangi bir taşma olmaz. Taşmayı zorlamanız gerekir: DOM'un üst kısmından tamamen gizlendiğinden, taşmak ve kaydırmak istediğiniz düğüme gelene kadar hiçbir ebeveynin çocuklarını barındırma şansı yoktur.
geon

3
Bunun gerçekten açıkladığından emin değilim. Bir öğede gizli olarak taşma ayarlanması, öğesinin tüm çocuklarını içerecek şekilde genişlemesini engellemez, AFAIK. MDN'ye göre: "Overflow özelliği, içeriğin kırpılmasını, kaydırma çubuklarının oluşturulmasını veya yalnızca blok düzeyi kapını taştığında içeriği görüntülemeyi belirtir." Ek olarak, görünür olmayandan başka bir şeye taşma ayarı yapmak yeni bir blok biçimlendirme bağlamı oluşturur - ancak bununla ilgili değildir, çünkü flex kapsayıcılar zaten kendi blok biçimlendirme bağlamını oluşturur: developer.mozilla.org/en-US/docs/Web/Guide / CSS /… .
markrian

1
Açıklamanızın sezgisel mantıklı olduğunu kabul ettiğimi eklemeliyim , ancak bunun doğru bir teknik açıklama olduğunu düşünmüyorum , bu da istediğim şey. Çözümü gelecekte sadece sebebini gerçekten anlayarak hatırlayabileceğim!
markrian

55

Çalışma position:absolute;ile birlikte flex:

Esnek öğeyi ile konumlandırın position: relative. Ardından içine başka bir <div>öğe ekleyin :

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

Bu, öğeyi göreceli konumlandırılmış üst öğesinin sınırlarına genişletir, ancak uzatmasına izin vermez. İçeride, overflow: auto;beklendiği gibi çalışacaktır.

  • cevaba dahil edilen kod snippet'i - Snippet'i çalıştırdıktan resim açıklamasını buraya girinsonra simgesini ve ardından simgesini tıklayın VEYATam sayfa
  • Click burada için CODEPEN
  • Sonuç: resim açıklamasını buraya girin

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

İyi şanslar...


2
Bu çözüm özellikle içerideki bileşende dolgu seti varsa kullanışlıdır, çünkü istediğiniz yerde güzel bir şekilde kilitler. Çok daha basit. (Evet, box-sizing: border-boxbunun yerine ayarlayabilirsiniz ancak bu bazı üçüncü taraf denetimleri için daha karmaşık olabilir).
Simon_Weaver

2
gecemi kurtardın!
Botea Florin

2
Teşekkür ederim. Her nasılsa bunun gerekli olduğunu hayal kırıklığına uğrattım, ama tavsiye için minnettarım!
Mathias

9

Biraz geç ama bu yardımcı olabilir: http://webdesign.tutsplus.com/tutorials/how-to-make-responsive-scrollable-panels-with-flexbox--cms-23269

Temel olarak koymak gerekir html, bodyiçin height: 100%; ve a tüm içeriği sarmak<div class="wrap"> <!-- content --> </div>

CSS:

html, body {
  height: 100%;
}

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

Benim için çalıştı. Umarım yardımcı olur


Android için iOS Safari'de farklı boyutlarda ölçüldüğü için "height: 100vh" kullanırken çok dikkatli olmalısınız. Biri URL çubuğunun yüksekliğini hesaba katar, diğeri yapmaz.
Sean Anderson

7

Bunu ekle:

align-items: flex-start;

kuralı .content {}. Bu en azından benim için kalemine sabitler (hem Firefox hem de Chrome'da).

Varsayılan olarak, .contentsahip align-items: stretch, bu başına, kendi yüksekliğiyle aynı olması onun otomatik yükseklik çocukların hepsi boyutu yapar http://dev.w3.org/csswg/css-flexbox/#algo-stretch . Buna karşılık, değer flex-startçocukların kendi yüksekliklerini hesaplamasına ve kendilerini başlangıç ​​kenarında hizalamasına izin verir (ve taşar ve bir kaydırma çubuğunu tetikler).



Ayrıca, sütunlar artık flexbox'ın ana cazibe merkezlerinden biri olan eşit yükseklikte olmayacak.
Joseph Silber

TAMAM. Bunun bir tasarım kısıtlaması olduğu açık değildi - üzgünüm.
dholbert

Büyük öneri
Vlad

1

Karşılaştığım bir sorun, bir kaydırma çubuğuna sahip olmak için bir öğenin belirtilmesi gereken bir yüksekliğe ihtiyaç duymasıdır (% olarak değil).

Hüner, her sütun içinde başka bir div kümesini yuvalamak ve sütun üst öğesinin ekranını esnek yön: sütunu ile esneyecek şekilde ayarlamaktır.

    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>

Ve işte html:

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


0

Bu sorunun çözümü, yalnızca overflow: auto;içerik sarmalayıcısını kaydırılabilir hale getirmek için .content'e eklemektir .

Ayrıca, Flexbox sarıcısı ve overflowedbu kod alanı gibi kaydırılabilir içerikle birlikte meydana gelen durumlar vardır .

Çözüm, overflow: hidden (or auto);büyük içeriklerin etrafına sargının üst kısmına (taşma ile ayarlanmış: otomatik;) eklemektir .

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.