J'ai une div appelée .side-el que j'aimerais avoir dans une position: fixe; comportement, mais dès que j'applique position fixe la largeur alterne de la droite. La bonne largeur serait celle définie par flexbox. Comment puis-je atteindre cet objectif?
.container {
-webkit-align-content: flex-start;
align-content: flex-start;
-webkit-align-items: flex-start;
align-items: flex-start;
display: -webkit-flex;
display: flex;
-webkit-flex-direction: row;
flex-direction: row;
-webkit-flex-wrap: wrap;
flex-wrap: wrap;
-webkit-justify-content: flex-start;
justify-content: flex-start;
* {
box-sizing: border-box;
-webkit-flex-grow: 1;
flex-grow: 1;
-webkit-flex-shrink: 0;
flex-shrink: 0;
}
}
.main-el {
box-sizing: border-box;
padding:0 2em;
width: 70%;
}
.side-el {
box-sizing: border-box;
width: 30%;
}
<div class="container" style="background-color: blue; height: 100px;">
<div class="main-el">
<div style="background-color: red; height: 1000px;">content</div>
</div>
<div class="side-el" >
<div style="background-color: red; height: 100px;">content</div>
</div>
</div>
Tu ne peux pas.
Comme expliqué par le spécification CSS2.1 :
Les boîtes positionnées de manière absolue sont extraites du flux normal .
Et la spécification Flexible Box Layout confirme que:
Un enfant absolument positionné d'un conteneur flexible ne participe pas à la présentation flexible . Cependant, il participe à la étape de réorganisation (voir ordre ), ce qui a un effet sur leur ordre de peinture.
(Souligné par moi)
@ Daniel, je sais que c'est très tard, mais ... bien que la réponse acceptée soit correcte, je ne pense pas que cela soit très utile. J'avais la même question (comment je suis tombé sur ce message), et la solution que je vais utiliser consiste à envelopper l'élément de position fixe dans l'élément flex. Voici un (très moche) exemple
Balisage pertinent
<aside class="Layout-aside" ng-class="{'isCollapsed': collapsed}" ng-controller="AsideCtrl">
<div class="Layout-aside-inner">
<button ng-click="collapsed = !collapsed">
<span ng-show="collapsed">></span>
<span ng-hide="collapsed"><</span>
</button>
<ul class="Layout-aside-content">
<li ng-repeat="i in items">{{i}}</li>
</ul>
</div>
</aside>
CSS pertinentes
.Layout-aside {
order: 0;
min-width: 140px;
width: 140px;
background-color: rgba(0, 255, 0, .4);
transition: width .4s, min-width .4s;
}
.Layout-aside.isCollapsed {
min-width: 25px;
width: 25px;
}
.Layout-aside-inner {
position: fixed;
}
.Layout-aside.isCollapsed .Layout-aside-inner {
width: 25px;
}
.Layout-aside.isCollapsed .Layout-aside-content {
opacity: 0;
}
Voici un moyen de faire cela inspiré par bootstrap:
.fixed-top {
display: flex;
position: fixed;
top: 0;
left: 0;
right: 0;
}
Cela donne à votre flex-box un espace pour respirer et faire son truc. Si votre direction de flex est colonne, vous pouvez utiliser top, left, bottom
au lieu.
Cela fonctionne car lorsque vous attribuez à un élément une position fixe et un left
et right
de 0 ou un top
et bottom
de 0, l'élément est étiré. pour remplir l’espace de gauche à droite ou de haut en bas. Cela permet à un flex-box d’utiliser la quantité d’espace attendue sans position fixe.
Vous pouvez y parvenir avec une alternative css position: sticky
Cela fonctionne bien, mais le seul problème est le support du navigateur (juin 2018): https://caniuse.com/#feat=css-sticky
J'espère que ça ira mieux bientôt.
Une solution beaucoup plus simple serait d'utiliser overflow-y:scroll
et height: 100vh
sur le main-el
récipient. Cela donnera l'apparence d'une position fixe au side-el
conteneur sans recourir à la position: fixe.