web-dev-qa-db-fra.com

Comment utiliser Bootstrap 4 flexbox pour remplir le contenu disponible?

J'ai une application angulaire qui utilise bootstrap 4. J'ai une barre de navigation qui reste en haut et je veux ajouter du contenu qui remplit l'espace restant dans le navigateur. En plus de la barre de navigation en haut, j'ai une autre div qui contient elle-même le contenu de l'en-tête et du pied de page. Entre l'en-tête et le pied de page, j'ai une section de contenu principale et je souhaite que cette section (#two dans mon exemple ci-dessous) remplisse tout l'espace vide. 

Je pensais pouvoir utiliser css flexbox pour accomplir cela, mais mon exemple simple de flexbox sans bootstrap semblait ne rien faire lorsque je suis entré dans le monde du bootstrap. J'utilisais ces docs pour essayer de comprendre cela.

Je pensais que l’utilisation de align-self-stretch devrait aider à atteindre cet objectif, mais il semblerait que les éléments qui le contiennent se dimensionnent eux-mêmes suffisamment gros pour contenir mon contenu #outer; J'ai essayé naïvement d'ajouter simplement des styles height:100% aux divs contenantes simplement pour essayer d'obtenir des étirements, mais cela n'a pas semblé aider.

J'ai créé cet exemple plunker en fonction de la réponse de @ ZimSystem. Son exemple de code semblait fonctionner exactement comme je le voulais, mais lorsque j'ai essayé de décomposer les modifications dans mon code angulaire simple, l'étirement de la flexion n'a pas eu lieu. Je ne suis pas sûr de ce que je fais pour le casser dans la conversion.

enter image description here

Voici l'intégralité de la composante angulaire que je regarde en ce moment:

<div id="outer" class="d-flex flex-column flex-grow">
    <div id="one" class="">
        header content <br>
        another line <br>
        And another
    </div>
    <div id="two" class="bg-info h-100 flex-grow">
        main content that I want to expand to cover remaining available height
    </div>
    <div id="three" class="">
        footer content
    </div>
</div>

Et voici le conteneur d'application montrant la barre de navigation et le point d'injection:

<div class="d-flex flex-column h-100">
    <nav class="navbar navbar-toggleable-md sticky-top bg-faded">
        <a class="navbar-brand" href="#">
            <h1 class="navbar-brand mb-0">My App</h1>
        </a>
        <ul class="navbar-nav"> 
            <li class="nav-item"><a class="nav-link" routerLink="/flex">My flex view</a></li>
        </ul>
    </nav>
    <router-outlet></router-outlet>
</div>  

Comment puis-je obtenir l'extension #two div afin de remplir l'espace tout en faisant en sorte que mes div #one et #three agissent comme en-têtes et pieds de contenu ancrés au haut et au bas de la zone de contenu?

34
Chris Farmer

Update Bootstrap 4.1.0

Les classes flex-grow-1 et flex-fill sont incluses dans Bootstrap 4.1.0

Update Bootstrap 4.0.0

Ajoutez une classe flex-grow comme ceci:

.flex-grow {
    flex: 1 0 auto;
}

Ensuite, les classes d'utilitaires peuvent être utilisés pour le reste de la présentation:

 <div class="d-flex flex-column h-100">
    <nav class="navbar navbar-toggleable-md sticky-top bg-faded">
        <a class="navbar-brand" href="#">
            <h1 class="navbar-brand mb-0">My App</h1>
        </a>
        <ul class="navbar-nav">
            <li class="nav-item"><a class="nav-link">Item 1</a></li>
        </ul>
    </nav>
    <div id="outer" class="d-flex flex-column flex-grow">
        <div id="one" class="">
            header content
            <br> another line
            <br> And another
        </div>
        <div id="two" class="bg-info h-100 flex-grow">
            main content that I want to expand to cover remaining available height
        </div>
        <div id="three" class="">
            footer content 40px height
        </div>
    </div>
</div>

_ { https://www.codeply.com/go/3ZDkRAghGU } _

30
Zim

Votre composant est encapsulé dans un élément <flex> qui requiert le même style de flexbox pour s’étirer verticalement, ce qui permet à son contenu de s’étirer avec. Donc, ajouter class="d-flex flex-column flex-grow" au <flex> fonctionnera. Voici un fork de votre exemple de plongeur .

4
Tigran Petrossian

Le problème, lorsque vous utilisez le balisage de ZimSystem dans votre lecteur angulaire, est que le composant est inséré dans le code HTML rendu en tant que conteneur supplémentaire avec la balise flex:

<div class="d-flex flex-column h-100">
    <nav class="navbar navbar-toggleable-md sticky-top bg-faded">
        ...
    </nav>
    <router-outlet></router-outlet>
    <flex>
        <div id="outer" class="d-flex flex-column flex-grow">
            ...
        </div>
    </flex>
</div>

Afin de le faire fonctionner comme prévu, vous pouvez supprimer la division externe du composant et définir les classes flex sur le conteneur Host du composant, comme indiqué dans this plunker modifié .

import {Component, NgModule, HostBinding, VERSION} from '@angular/core'
import { RouterOutlet, RouterModule } from '@angular/router' 
import {BrowserModule} from '@angular/platform-browser'

@Component({
    selector: 'flex',
    template: `
        <div id="one" class="">
            header content
            <br> another line
            <br> And another
        </div>
        <div id="two" class="bg-info h-100 flex-grow">
            main content that I want to expand to cover remaining available height
        </div>
        <div id="three" class="">
            footer content
        </div>
    `
})
export class FlexComponent {
    @HostBinding('class') classes = 'd-flex flex-column flex-grow';  
    ...
}
3
ConnorsFan

Si vous ne pouvez pas contrôler le comportement de la classe que vous utilisez. Il suffit de tout enlever et d'utiliser ce css uniquement.

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

.outer {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.two {
  background-color: #123;
  flex-grow: 1;
  color: #FFF;
}
<flex>
  <div class="outer">
    <div class="one">
      Hey. This is header. <br> Hey. This is header. <br> Hey. This is header. <br> Hey. This is header. <br>
    </div>
    <div class="two">
      Hey. This is body
    </div>
    <div class="three">
      Hey. This is footer <br> Hey. This is footer <br>
    </div>
  </div>
</flex>

2
Duannx
.wrapper {
  display: flex;
  flex-direction: column;
  height: 100vh;
}

.flex-grow {
  flex: 1;
}

Ajoutez un composant wrapper qui contient vos blocs de contenu et appliquez la classe flex-grow à celle que vous souhaitez remplir.

1
Sara

Vous pouvez faire en sorte que le composant s'agrandisse de manière à remplir son conteneur, puis en tant que colonne flexible afin que le contenu se développe également. Pour ce faire, utilisez :Host pour cibler l'élément de composant.

flex.component.ts

  @Component({
    selector: 'flex',
    template: `

  <div id="outer" class="d-flex flex-column flex-grow">
    <div id="one" class="">
      header content
      <br> another line
      <br> And another
    </div>
    <div id="two" class="bg-info h-100 flex-grow">
      main content that I want to expand to cover remaining available height
    </div>
    <div id="three" class="">
      footer content
    </div>
  </div>        

    `,
    styles: [':Host {flex: 1 0 auto; display: flex; flex-direction: column }']
  })

J'ai mis à jour le plunk .

0
JayChase

CSS

html, body {
  height: 100%;
}

.flex-grow {
  flex: 1;
}

flex.components.ts

//our root app component
import {Component, NgModule, VERSION} from '@angular/core'
import { RouterOutlet, RouterModule } from '@angular/router' 
import {BrowserModule} from '@angular/platform-browser'

@Component({
  selector: 'flex',
  Host: {'class': 'flex-grow'},
  template: `

<div id="outer" class="d-flex flex-column h-100 flex-grow">
  <div id="one" class="">
    header content
    <br> another line
    <br> And another
  </div>
  <div id="two" class="bg-info flex-grow">
    main content that I want to expand to cover remaining available height
  </div>
  <div id="three" class="">
    footer content
  </div>
</div>        

  ` 
})
export class FlexComponent {
  constructor() {}
}

Résultat - https://plnkr.co/edit/vQS7Jw58zmlVshz9YmQ8?p=preview Merci :)

0
grinmax