Moja pozycja: element lepki nie przykleja się przy używaniu flexboksa

114

position: stickyUtknąłem na tym trochę i pomyślałem, że udostępnię to + flexbox mam:

Mój sticky div działał dobrze, dopóki nie przełączyłem widoku na pojemnik flexbox i nagle element div nie był lepki, gdy był zapakowany w element nadrzędny flexbox.

.flexbox-wrapper {
  display: flex;
  height: 600px;
}
.regular {
  background-color: blue;
}
.sticky {
  position: -webkit-sticky;
  position: sticky;
  top: 0;
  background-color: red;
}
<div class="flexbox-wrapper">
  <div class="regular">
    This is the regular box
  </div>
  <div class="sticky">
    This is the sticky box
  </div>
</div>

JSFiddle pokazujący problem

BHOLT
źródło
Czy to zachowanie utrzymuje się we wszystkich przeglądarkach, które obsługują, position: stickyczy tylko w jednej / kilku?
TylerH,
1
@TylerH Wierzę, że to wszystkie przeglądarki. To działało w ten sposób zarówno w Chrome, jak i Safari.
BHOLT,
Dzięki. Mogę potwierdzić, że problem i rozwiązanie występują również w przeglądarce Firefox.
TylerH,

Odpowiedzi:

220

Ponieważ elementy Flex Box są domyślnie stretchustawione, wszystkie elementy mają tę samą wysokość, której nie można przewijać.

Dodanie align-self: flex-startdo elementu sticky ustawia wysokość na auto, co pozwala na przewijanie i naprawia to.

Obecnie jest to obsługiwane we wszystkich głównych przeglądarkach, ale Safari nadal ma -webkit-prefiks, a inne przeglądarki, z wyjątkiem Firefoksa, mają pewne problemy z position: stickytabelami.

.flexbox-wrapper {
  display: flex;
  overflow: auto;
  height: 200px;          /* Not necessary -- for example only */
}
.regular {
  background-color: blue; /* Not necessary -- for example only */
  height: 600px;          /* Not necessary -- for example only */
}
.sticky {
  position: -webkit-sticky; /* for Safari */
  position: sticky;
  top: 0;
  align-self: flex-start; /* <-- this is the fix */
  background-color: red;  /* Not necessary -- for example only */
}
<div class="flexbox-wrapper">
  <div class="regular">
    This is the regular box
  </div>
  <div class="sticky">
    This is the sticky box
  </div>
</div>

JSFiddle pokazujący rozwiązanie

BHOLT
źródło
26
działa to tylko podczas przewijania w obrębie zawierającego element flex - podczas przewijania całego okna NIE przykleja się (przynajmniej w Firefoksie) - więc dla tych, którzy doświadczają sprzecznego zachowania, jest bardziej prawdopodobne, że doświadczasz sprzecznych oczekiwań (jak i was)
aequalsb
@aequalsb Czy znasz sposób, aby przyklejać się podczas przewijania całej strony?
Douglas Gaskell
@Douglas, pytanie jest mylące, ponieważ sugeruje, że problem dotyczy, flexboxale problem ma więcej wspólnego z zawartością stickyelementu. spójrz na to skrzypce: jsfiddle.net/9y87zL5c, gdzie DRUGIE czerwone pudełko działa zgodnie z oczekiwaniami, ale PIERWSZE czerwone pudełko nie przykleja się - więc ... to nie jest związane z flexboksem (stąd sprzeczne oczekiwania) ... TAKŻE ... i dodano kilka jabberwocky, aby zobaczyć wyniki w dokładniejszy sposób.
aequalsb
29

W moim przypadku overflow-x: hidden;zastosowano do niego jeden z kontenerów nadrzędnych , co zepsuje position: stickyfunkcjonalność. Musisz usunąć tę regułę.

Żaden element nadrzędny nie powinien mieć zastosowania powyższej reguły CSS. Warunek ten dotyczy wszystkich rodziców aż do elementu „body” (ale z wyłączeniem).

TheoPlatica
źródło
Nie możesz też mieć overflow-x:hiddenna elemencie html.
Samuel Liew
Wielkie dzięki. ZAWSZE walczę z lepką pozycją i nie wiedziałem o tym, dopóki nie przeczytałem Twojej odpowiedzi. :)
Raphael Aleixo
@SamuelLiew, tak, możesz mieć overflow-x: hidden;element HTML.
TheoPlatica
@RaphaelAleixo Cieszę się, że mogłem pomóc :)
TheoPlatica
To właśnie uniemożliwiało mi prawidłowe działanie kleju. Wielkie dzięki!
MoOx
7

Możesz także spróbować dodać podrzędny element DIV do elementu elastycznego z zawartością wewnątrz i przypisać go position: sticky; top: 0;do niego.

To zadziałało dla mnie w przypadku układu dwóch kolumn, w którym zawartość pierwszej kolumny musiała być lepka, a druga kolumna wydawała się przewijalna.

Simon_Weaver
źródło
Całkowicie się zgadzam, jest to najprostsza i najbardziej niezawodna opcja, jaką udało mi się znaleźć. W ten sposób będziesz mógł również kontrolować, kiedy przestać się przyklejać, kontrolując wysokość pojemnika.
Ibrahim ben Salah
0

Zrobiłem prowizoryczny stół flexbox i miałem ten problem. Aby go rozwiązać, po prostu umieszczam lepki rząd nagłówka poza flexboxem, tuż przed nim.

Andrzej
źródło
0

W mojej sytuacji align-self: flex-start(lub justify-self: flex-start) rozwiązanie nie działa. Muszę również zachować, overflow-x: hiddenponieważ niektóre pojemniki przesuwają się poziomo.

Moje rozwiązanie wymagało zagnieżdżenia display: flexz, overflow-y: autoaby uzyskać pożądane zachowania:

  • Header może dynamicznie regulować wysokość, co zapobiega graniu z position: absolutelubposition: fixed
  • zawartość jest przewijana w pionie, ograniczona w poziomie do szerokości widoku
  • lepki element może znajdować się w dowolnym miejscu w pionie, przyklejając się do dołu nagłówka
  • inne elementy mogą przesuwać się poziomo
    • wygląda na to, że narzędzie fragmentu SO nie może renderować widthelementów podrzędnych, aby prawidłowo zademonstrować poziomy slajd, a może jest jakieś inne ustawienie w moim rzeczywistym układzie, które sprawia, że ​​działa ...
    • zwróć uwagę, że element opakowujący, który nie robi nic więcej, jest wymagany, aby umożliwić overflow-x: autopoprawne działanie w elementach nadrzędnych zoverflow-x: hidden

body {
  height: 100vh;
  width: 100vw;
  display: flex;
  flex-direction: column;
}

body>header {
  background-color: red;
  color: white;
  padding: 1em;
}

.content {
  overflow-x: hidden;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
}

article {
  position: relative;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
}

.horizontal_slide {
  display: flex;
  overflow-x: auto;
  background-color: lightblue;
  padding: .5em;
}

.horizontal_slide>* {
  width: 1000px;
}

.toolbar {
  position: sticky;
  top: 0;
  z-index: 10;
  background-color: lightgray;
  padding: .5em;
  display: flex;
}
<header>Fancy header with height adjusting to variable content</header>
<div class="content">
  <article class="card">
    <h1>One of several cards that flips visibility</h1>
    <div class="overflow_x_wrapper">
      <div class="horizontal_slide">
        <div>Reason why `overflow-x: hidden` on the parent is required
        </div>
        <div>Reason why `overflow-x: hidden` on the parent is required
        </div>
        <div>Reason why `overflow-x: hidden` on the parent is required
        </div>
      </div>
      <div class="toolbar">Sticky toolbar part-way down the content</div>
      <p>Rest of vertically scrollable container with variable number of child containers and other elements</p>
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure
        dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
  </article>
  </div>

OXiGEN
źródło