Wie kann ich eine Position haben: fest; Verhalten für ein Element in Flexbox-Größe?

73

Ich habe eine Div namens .side-el, die ich gerne in einer Position hätte: fest; Verhalten, aber sobald ich die Position fest auftrage, wechselt die Breite von der rechten. Die richtige Breite wäre die von Flexbox festgelegte. Wie kann ich dieses Ziel erreichen?

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

Daniel Schmidt
quelle
4
Das kannst du nicht. Absolut positionierte Elemente werden aus dem normalen Fluss des Dokuments herausgenommen.
Oriol
Okay, kannst du das als Antwort posten?
Daniel Schmidt

Antworten:

64

Hier ist eine Möglichkeit, dies zu tun, inspiriert von Bootstrap:

.fixed-top {
  display: flex;
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
}

Dies gibt Ihrer Flex-Box Raum zum Atmen und für die Flex-Box. Wenn Ihre Flex-Richtung eine Spalte ist, können Sie top, left, bottomstattdessen verwenden.

Dies funktioniert, weil, wenn Sie einem Element eine feste Position und ein leftund rightvon 0 oder ein topund bottomvon 0 geben, das Element gestreckt wird, um den Raum von links nach rechts oder von oben nach unten zu füllen. Dies wiederum ermöglicht es einer Flex-Box, den Platz zu nutzen, den Sie ohne feste Position erwarten würden.

Wylliam Judd
quelle
6
In meiner Antwort wurde eine Erklärung hinzugefügt. Hoffentlich macht es für Sie Sinn.
Wylliam Judd
4
Diese Antwort hat den Trick für mich getan und sollte als Lösung angesehen werden.
Christof Kälin
Dies vermeidet vh-Probleme mit der Bildlaufleiste auf Mobilgeräten. Mit diesem CSS bleibt die Leiste einfach sichtbar.
GaryBishop
Schöne saubere Lösung für Flexbox
Klewis
45

@ Daniel, ich weiß, dass dies sehr spät ist, aber ... obwohl die akzeptierte Antwort korrekt ist, finde ich es nicht sehr hilfreich. Ich hatte die gleiche Frage (wie ich auf diesen Beitrag gestoßen bin), und die Lösung, mit der ich gehen werde, besteht darin, das positionsfeste Element in das flexible Element zu wickeln. Hier ist ein (sehr hässliches) Beispiel

Relevantes Markup

  <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">&gt;</span>
        <span ng-hide="collapsed">&lt;</span>
      </button>
      <ul class="Layout-aside-content">
        <li ng-repeat="i in items">{{i}}</li>
      </ul>
    </div>
  </aside>

Relevantes CSS

.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;
}
o4ohel
quelle
13

Sie können es mit einer CSS-Alternative erreichen position: sticky

Es funktioniert gut, aber das einzige Problem ist die Browserunterstützung (Juni 2018): https://caniuse.com/#feat=css-sticky

Hoffe es wird bald besser.

Juozas Rastenis
quelle
Das ist ordentlich. Ich mag es, wenn sich ECMA verbessert.
Wylliam Judd
Ja, das ist großartig und klar. Gut für hartnäckige Seitenleisten und so.
vintproykt
6

Eine weitaus einfachere Lösung wäre die Verwendung overflow-y:scrollund height: 100vham main-elBehälter. Dies gibt dem side-elBehälter das Aussehen einer festen Position, ohne auf die Position zurückzugreifen: fest.

Greg Beaver
quelle
3
Das einzige Problem ist, dass die Bildlaufleiste auf dem mittleren Inhaltselement absolut schrecklich aussieht. Sie möchte sie auf der Seite wie das Browserfenster haben
PirateApp
.es schlecht mit Position für Multi-Level-Div festgelegt, dies auf alles ordentlich auf meiner Website zu halten!
Jones G