Pracuję nad zagnieżdżonym układem flexbox, który powinien działać w następujący sposób:
Najbardziej zewnętrzny poziom ( ul#main
) to lista pozioma, która musi zostać rozszerzona w prawo, gdy zostanie do niej dodanych więcej elementów. Jeśli będzie zbyt duży, powinien pojawić się poziomy pasek przewijania.
#main {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
overflow-x: auto;
/* ...and more... */
}
Każda pozycja tej listy ( ul#main > li
) ma nagłówek ( ul#main > li > h2
) i wewnętrzną listę ( ul#main > li > ul.tasks
). Ta wewnętrzna lista jest pionowa i w razie potrzeby powinna być zawijana w kolumny. Przy zawijaniu w więcej kolumn jego szerokość powinna się zwiększyć, aby zrobić miejsce na więcej elementów. To zwiększenie szerokości powinno dotyczyć również pozycji zawierającej wykaz zewnętrzny.
.tasks {
flex-direction: column;
flex-wrap: wrap;
/* ...and more... */
}
Mój problem polega na tym, że wewnętrzne listy nie zawijają się, gdy wysokość okna jest zbyt mała. Próbowałem wielu zmian we wszystkich właściwościach flex, starając się skrupulatnie przestrzegać wytycznych CSS-Tricks , ale bez powodzenia.
Ten JSFiddle pokazuje, co mam do tej pory.
Oczekiwany wynik (czego chcę) :
Rzeczywisty wynik (co otrzymuję) :
Starszy wynik (jaki uzyskałem w 2015 roku) :
AKTUALIZACJA
Po pewnym dochodzeniu zaczyna wyglądać na większy problem. Wszystkie główne przeglądarki zachowują się w ten sam sposób i nie ma to nic wspólnego z zagnieżdżeniem mojego projektu flexbox. Jeszcze prostsze układy kolumn flexbox odmawiają zwiększenia szerokości listy, gdy elementy są zawijane.
Ten inny JSFiddle wyraźnie pokazuje problem. W aktualnych wersjach przeglądarek Chrome, Firefox i IE11 wszystkie elementy są poprawnie zawijane; wysokość listy wzrasta w row
trybie, ale jej szerokość nie zwiększa się w column
trybie. Ponadto nie ma żadnego natychmiastowego ponownego przepływu elementów podczas zmiany wysokości column
trybu, ale jest wrow
trybie.
Jednak oficjalne specyfikacje (spójrz konkretnie na przykład 5) wydają się wskazywać, że to, co chcę zrobić, powinno być możliwe.
Czy ktoś może wymyślić obejście tego problemu?
AKTUALIZACJA 2
Po wielu eksperymentach z wykorzystaniem JavaScript do aktualizowania wysokości i szerokości różnych elementów podczas zdarzeń zmiany rozmiaru, doszedłem do wniosku, że próba rozwiązania tego problemu w ten sposób jest zbyt złożona i zbyt trudna. Ponadto dodanie JavaScript zdecydowanie łamie model flexbox, który powinien być tak czysty, jak to tylko możliwe.
Na razie cofam się do overflow-y: auto
zamiast, aby w flex-wrap: wrap
razie potrzeby wewnętrzny pojemnik przewijał się pionowo. Nie jest ładna, ale jest to jedna z możliwości, która przynajmniej nie narusza zbytnio użyteczności.
column wrap
nie rozszerzał swojej szerokości podczas zawijania. Więcej informacji znajdziesz na code.google.com/p/chromium/issues/detail?id=247963 .Odpowiedzi:
Problem
Wygląda to na fundamentalną wadę układu flex.
Pojemnik elastyczny w kierunku kolumn nie rozszerzy się, aby pomieścić dodatkowe kolumny. (To nie jest problem
flex-direction: row
.)To pytanie było zadawane wiele razy (zobacz listę poniżej), bez wyraźnych odpowiedzi w CSS.
Trudno to uznać za błąd, ponieważ problem występuje we wszystkich głównych przeglądarkach. Ale rodzi pytanie:
Można by pomyśleć, że przynajmniej jeden z nich zrobi to dobrze. Mogę tylko spekulować na temat przyczyny. Może była to technicznie trudna implementacja i została odłożona na półkę na tę iterację.
AKTUALIZACJA: Problem wydaje się być rozwiązany w Edge v16.
Ilustracja problemu
OP stworzył przydatne demo ilustrujące problem. Kopiuję to tutaj: http://jsfiddle.net/nwccdwLw/1/
Opcje obejścia
Hacky rozwiązania społeczności Stack Overflow:
„Wygląda na to, że tego problemu nie da się rozwiązać tylko za pomocą CSS, więc proponuję rozwiązanie JQuery”.
„Ciekawe, że większość przeglądarek nie zaimplementowała poprawnie kontenerów flex z kolumnami, ale obsługa trybów pisania jest dość dobra. Dlatego możesz użyć kontenera wierszowego z trybem pisania w pionie”.
Więcej analiz
Raport o błędzie Chromium
Odpowiedź Marka Amery
Inne posty opisujące ten sam problem
źródło
Spóźnił się na imprezę, ale LATA później napotkał ten problem. Skończyło się na znalezieniu rozwiązania za pomocą siatki. Na pojemniku możesz użyć
Mam przykład na CodePen, który przełącza się między problemem flexbox a poprawką siatki: https://codepen.io/MandeeD/pen/JVLdLd
źródło
grid-row-end: span X;
jeśli potrzebujesz niektórych elementów, aby zająć więcej wierszy.Szkoda, że tak wiele głównych przeglądarek po wielu latach cierpi z powodu tego błędu. Rozważ obejście JavaScript. Za każdym razem, gdy okno przeglądarki zmieni rozmiar lub zawartość zostanie dodana do elementu, wykonaj ten kod, aby zmienić rozmiar na odpowiednią szerokość. Możesz zdefiniować dyrektywę w swoim frameworku, aby zrobić to za Ciebie.
źródło
Właśnie znalazłem tutaj naprawdę świetne obejście PURE CSS.
https://jsfiddle.net/gcob492x/3/
Trudność: ustaw
writing-mode: vertical-lr
w liście divwriting-mode: horizontal-tb
w elemencie listy. Musiałem dostosować style w JSFiddle (usunąć wiele stylów wyrównania, które nie są konieczne do rozwiązania).Uwaga: komentarz mówi, że działa tylko w przeglądarkach opartych na Chromium, a nie Firefox. Osobiście testowałem tylko w Chrome. Możliwe, że istnieje sposób, aby to zmodyfikować, aby działał w innych przeglądarkach, albo zostały zaktualizowane przeglądarki, które to umożliwiają.
Wielki okrzyk na ten komentarz: Kiedy elementy flexbox zawijają się w trybie kolumnowym, kontener nie zwiększa swojej szerokości . Przeglądanie tego wątku doprowadziło mnie do https://bugs.chromium.org/p/chromium/issues/detail?id=507397#c39, który doprowadził mnie do tego JSFiddle.
źródło
Ponieważ nie zaproponowano jeszcze rozwiązania ani odpowiedniego obejścia, udało mi się uzyskać żądane zachowanie przy nieco innym podejściu. Zamiast rozdzielać układ na 3 różne elementy div, dodaję wszystkie elementy do jednego elementu div i utworzę separację z kilkoma elementami div pomiędzy nimi.
Proponowane rozwiązanie jest zakodowane na stałe, zakładając, że mamy 3 sekcje, ale można je rozszerzyć na ogólną. Głównym pomysłem jest wyjaśnienie, w jaki sposób możemy osiągnąć ten układ.
:before
z każdego pierwszego elementu, możemy zlokalizować tytuł każdej sekcji.space
tworzy lukę między sekcjamispace
nie obejmuje całej wysokości sekcji, dodaję również:after
do sekcji, ustawiając ją z pozycją bezwzględną i białym tłem.z-index: -1
.źródło
Możliwe rozwiązanie JS ..
źródło
columns
właściwości style może być punktem wyjścia do praktycznego rozwiązania. Może dostosowując ilość kolumn i szerokość ul.