2017-05-24 1 views
1

Je me bats pour obtenir une mise en page flexbox fonctionnant avec des marges et overflow: hidden.Flexbox empêchant les marges d'être respectées

Le composant de type carrousel J'intégration utilise cette méthode pour être réactif, mais dès qu'un display:flex est appliqué à la société mère, les propriétés margin et overflow: hidden sont ignorées comme le montre l'exemple ci-dessous.

La version supérieure n'est pas imbriquée dans une flexbox où, comme celle qui la suit, elle ne respecte pas les marges du parent.

flexbox issue with margins

La question est démontrée dans le code ci-dessous et dans ce Plunker. http://plnkr.co/edit/qU1oq1Vq1X3FQMWLJiQk?p=preview

body { 
 
    margin: 400px; 
 
} 
 

 
.overflowHidden { 
 
    overflow: hidden; 
 
} 
 

 
.flex { 
 
    display: flex; 
 
}
<div> 
 
    <div class="overflowHidden"> 
 
    <img src="http://lorempixel.com/600/400" /> 
 
    </div> 
 
</div> 
 

 
<div class="flex"> 
 
    <div> 
 
    <div class="overflowHidden"> 
 
     <img src="http://lorempixel.com/600/400" /> 
 
    </div> 
 
    </div> 
 
</div>

Je sais qu'il ya beaucoup de questions similaires sur ce sujet, mais je ne pouvais pas trouver tout ce qui concerne mon cas particulier d'utilisation.

Répondre

1

est ici la solution:

.flex > div { overflow: hidden } 

revised demo


La première chose à noter est que les marges ont rien à voir avec ce problème. Les marges sont, en fait, respectées. Ils voyagent simplement avec l'élément, qui développe un conteneur.


Les conteneurs div non-flex ont display: block par défaut.

Dans une block formatting context, lorsqu'une image devient trop grande pour tenir dans un conteneur avec overflow: hidden, elle disparaît simplement, comme prévu.

Les divs parents et leurs marges restent stables et non perturbés.

Cependant, dans un flex formatting context le comportement est différent. D'abord, vous avez trois niveaux de div dans l'exemple flexible. Vous n'en avez que deux dans l'exemple de bloc. Mais ce n'est pas vraiment important.

La pièce maîtresse de l'information ici est la suivante:

Lorsque vous appliquez display: flex ou display: inline-flex à un élément, il devient un conteneur flexible et ses enfants deviennent des éléments flexibles.Par défaut, les éléments flex ne peuvent pas être inférieurs à la taille de leur contenu. Ils ont un paramètre par défaut de min-width: auto.

Ainsi, lorsqu'une image devient trop grand pour son parent, le parent (si elle est un élément flexible) doit se développer. Mais dans votre exemple, le parent de l'image (div.overflowHidden) n'est pas un élément flexible, c'est un élément de bloc standard. Donc, overflow: hidden fonctionne bien (tout comme dans l'exemple de bloc).

Mais le parent du parent est un élément flexible. Et son paramètre par défaut est min-width: auto. Et il ne peut pas rétrécir en dessous de la taille de son contenu (l'image). Donc, alors que l'exemple de bloc peut rester sur l'écran à tout moment, la version flexible débordera le body/viewport, en prenant la bonne marge avec elle.

La solution consiste à remplacer la valeur par défaut min-width: auto sur l'élément flexible. Vous pouvez utiliser:

  • min-width: 0

OU

  • overflow: hidden

Plus de détails ici: Why doesn't flex item shrink past content size?

+1

Merci pour la réponse claire et détaillée Michael. Très appréciée. – CountZero

1

Vous ne savez pas exactement pourquoi cela se produit exactement, mais semble fonctionner si vous appliquez .overflowHidden à un élément qui enveloppe le parent flex, ou l'appliquez simplement au parent Flex à la place.

body { 
 
    margin: 400px; 
 
    overflow-x: hidden; 
 
} 
 

 
.overflowHidden { 
 
    overflow: hidden; 
 
} 
 

 
.flex { 
 
    display: flex; 
 
    z-index: -1; 
 
    position: relative; 
 
}
<div> 
 
    <div class="overflowHidden"> 
 
    <img src="http://lorempixel.com/600/400" /> 
 
    </div> 
 
</div> 
 
<div class="flex overflowHidden"> 
 
    <div> 
 
    <img src="http://lorempixel.com/600/400" /> 
 
    </div> 
 
</div> 
 
<div class="overflowHidden"> 
 
    <div class="flex"> 
 
    <img src="http://lorempixel.com/600/400" /> 
 
    </div> 
 
</div>