web-dev-qa-db-fra.com

Faire défiler une flexbox avec un contenu en débordement

enter image description here

Voici le code J'utilise pour réaliser la présentation ci-dessus:

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

J'ai omis le code utilisé pour le style. Vous pouvez tout voir dans le stylo .


Ce qui précède fonctionne, mais lorsque le contenu de la zone content déborde, la page entière défile. Je veux seulement que la zone de contenu défile elle-même, donc j'ai ajouté overflow: auto à la content div .

Le problème avec ceci est que les colonnes elles-mêmes ne s'étendent pas au-delà de la hauteur de leurs parents, donc les frontières sont coupées là aussi.

Voici le stylo montrant le problème de défilement .

Comment puis-je configurer la zone content pour qu'elle défile indépendamment tout en laissant ses enfants s'étendre au-delà de la hauteur de la boîte content?

169
Joseph Silber

J'ai parlé à Tab Atkins (auteur de la spécification flexbox) à ce sujet, et voici ce que nous avons proposé:

HTML:

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

CSS:

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

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

Voici les stylos:

  1. Les colonnes courtes sont étirées .
  2. Des colonnes plus longues débordant et défilant .

Cela fonctionne parce que align-items: stretch ne réduit pas ses éléments s'ils ont une hauteur intrinsèque, ce qui est accompli ici par min-content.

221
Joseph Silber

Je viens de résoudre ce problème très élégamment après de nombreux essais et erreurs.

Découvrez mon blog: http://geon.github.io/programming/2016/02/24/flexbox-full-page-web-app-layout

Fondamentalement, pour faire défiler une cellule flexbox, vous devez définir tous ses parents overflow: hidden;, sinon ignorez vos paramètres de débordement et agrandissez plutôt le parent.

72
geon

Travailler avec position:absolute; avec flex:

Positionnez l'élément flex avec position: relative. Ensuite, à l'intérieur, ajoutez un autre élément <div> avec:

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

Cela étend l'élément aux limites de son parent positionné par rapport, mais ne permet pas de l'étendre. À l'intérieur, overflow: auto; fonctionnera comme prévu.

  • l'extrait de code inclus dans la réponse - Cliquez sur enter image description here puis cliquez sur Full Page après l'exécution de l'extrait de code OU
  • Cliquez ici pour le CODEPEN
  • Le résultat: enter image description here
.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>

Bonne chance...

28
Akash

Un peu tard mais cela pourrait aider: http://webdesign.tutsplus.com/tutorials/how-to-make-responsive-scrollable-panels-with-flexbox--cms-23269

En gros, vous devez placer html, body dans height: 100%; et envelopper tout votre contenu dans un <div class="wrap"> <!-- content --> </div>.

CSS:

html, body {
  height: 100%;
}

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

Travaillé pour moi J'espère que ça aide

8
Doua Beri

Ajoute ça:

align-items: flex-start;

à la règle pour .content {}. Cela le corrige dans votre stylo pour moi, au moins (sous Firefox et Chrome).

Par défaut, .content a align-items: stretch, ce qui lui permet de dimensionner tous ses enfants de taille automatique pour qu'ils correspondent à sa propre hauteur, par http://dev.w3.org/csswg/css -flexbox/# algo-stretch . En revanche, la valeur flex-start permet aux enfants de calculer leurs propres hauteurs et de s’aligner sur son bord de départ (débordement et déclenchement d’une barre de défilement).

5
dholbert