web-dev-qa-db-fra.com

Empêcher un élément enfant de déborder son parent dans flexbox

Je travaille sur une application Web qui affiche une grande grille de cartes, dont la hauteur est intrinsèquement variable.

Dans un souci d'esthétique, nous utilisions la .matchHeight() de jQuery pour égaliser la hauteur des cartes dans chaque ligne.

Les performances de cela n'ont pas bien évolué, donc aujourd'hui j'ai migré vers une solution basée sur une boîte flexible qui est tellement plus rapide.

Cependant, j'ai perdu un comportement - le contenu de l'en-tête de la carte devrait être tronqué avec des points de suspension s'il ne convient pas.

Buts:

  1. 3 colonnes
  2. La largeur des colonnes varie pour remplir le parent
  3. Espacement constant entre les colonnes
  4. Hauteurs égalisées dans une rangée

Comment puis-je faire en sorte que la taille du conteneur soit respectée et que le text-overflow: Ellipsis; et white-space: nowrap; être honoré?

(Pas de balise jQuery car nous nous éloignons de cela)

Ma solution dans sa forme actuelle, qui atteint tous mes objectifs en dehors de la troncature:

https://codepen.io/anon/pen/QvqZYY

#container { 
                display: flex; 
                flex-direction: row; 
                flex-wrap: wrap; 
                
                justify-content: flex-start;    /* Bias cards to stack from left Edge       */ 
                align-items: stretch;           /* Within a row, all cards the same height  */ 
                
                border: thin solid gray; 
            } 
            .card-wrapper { 
                width: 33.33%; 
                display: flex; 
                background: #e0e0ff; 
            } 
            .card { 
                flex-grow: 1; 
                margin: 7px; 
                display: flex; 
                flex-direction: column; 
                border: thin solid gray; 
                background: #e0ffff; 
            } 
            .card div { 
                border: thin solid gray; 
            } 
            .card div:nth-child(1) { 
                white-space: nowrap; 
                text-overflow: Ellipsis; 
            } 
            .card div:nth-child(2) { 
                flex-grow: 2; 
            } 
<div id="container"> 
            <div class="card-wrapper"> 
                <div class="card"> 
                    <div>Title</div> 
                    <div>Multiline<br/>Body</div> 
                    <div>Footer</div> 
                </div> 
            </div> 
            <div class="card-wrapper"><div class="card"><div>Really long rambling title that pushes beyond the bounds of the container, unless your screen is really, really wide</div><div>Body</div><div>Footer</div></div></div> 
            <div class="card-wrapper"><div class="card"><div>Title</div><div>Body</div><div>Footer</div></div></div> 
            <div class="card-wrapper"><div class="card"><div>Title</div><div>Body</div><div>Footer</div></div></div> 
            <div class="card-wrapper"><div class="card"><div>Title</div><div>Body</div><div>Footer</div></div></div> 
        </div> 
23
Chris

Un paramètre initial sur les éléments flexibles est min-width: auto. Cela signifie qu'un élément flexible, par défaut, ne peut pas être plus petit que la taille de son contenu.

Donc, text-overflow: Ellipsis ne peut pas fonctionner car un élément flexible va simplement se développer, plutôt que de permettre un débordement. (Les barres de défilement ne s'afficheront pas non plus, pour la même raison.)

Pour remplacer ce comportement, utilisez min-width: 0 ou overflow: hidden. Plus de détails.

#container {
  display: flex;
  flex-wrap: wrap;
  border: thin solid gray;
}

.card-wrapper {
  width: 33.33%;
  display: flex;
  background: #e0e0ff;
}

.card {
  flex-grow: 1;
  margin: 7px;
  display: flex;
  flex-direction: column;
  border: thin solid gray;
  background: #e0ffff;
  overflow: hidden;        /* NEW */
}

.card div {
  border: thin solid gray;
}

.card div:nth-child(1) {
  white-space: nowrap;
  text-overflow: Ellipsis;
  overflow: hidden;        /* NEW */
}

.card div:nth-child(2) {
  flex-grow: 2;
}
<div id="container">
  <div class="card-wrapper">
    <div class="card">
      <div>Title</div>
      <div>Multiline<br/>Body</div>
      <div>Footer</div>
    </div>
  </div>
  <div class="card-wrapper">
    <div class="card">
      <div>Really long rambling title that pushes beyond the bounds of the container, unless your screen is really, really wide</div>
      <div>Body</div>
      <div>Footer</div>
    </div>
  </div>
  <div class="card-wrapper">
    <div class="card">
      <div>Title</div>
      <div>Body</div>
      <div>Footer</div>
    </div>
  </div>
  <div class="card-wrapper">
    <div class="card">
      <div>Title</div>
      <div>Body</div>
      <div>Footer</div>
    </div>
  </div>
  <div class="card-wrapper">
    <div class="card">
      <div>Title</div>
      <div>Body</div>
      <div>Footer</div>
    </div>
  </div>
</div>
60
Michael_B