Jak mogę połączyć Flexbox i Vertical Scroll w aplikacji o pełnej wysokości?

106

Chcę używać aplikacji o pełnej wysokości przy użyciu Flexbox. Znalazłem to, czego chcę, używając starego modułu układu flexbox ( display: box;i innych rzeczy) w tym linku: CSS3 Aplikacja Flexbox o pełnej wysokości i przepełnienie

Jest to poprawne rozwiązanie dla przeglądarek, które obsługują tylko starą wersję właściwości CSS flexbox.

Jeśli chcę spróbować użyć nowszych właściwości flexboksa, spróbuję użyć drugiego rozwiązania w tym samym linku wymienionym jako hack: użycie kontenera z rozszerzeniem height: 0px;. Powoduje pokazanie przewijania w pionie.

Bardzo mi się to nie podoba, ponieważ wprowadza inne problemy i jest bardziej obejściem niż rozwiązaniem.

html, body {
    height: 100%;    
}
#container {
	display: flex;
	flex-direction: column;
	height: 100%;
}
#container article {
	flex: 1 1 auto;
	overflow-y: scroll;
}
#container header {
    background-color: gray;
}
#container footer {
    background-color: gray;
}
<section id="container" >
    <header id="header" >This is a header</header>
    <article id="content" >
        This is the content that
        <br />
        With a lot of lines.
        <br />
        With a lot of lines.
        <br />
        This is the content that
        <br />
        With a lot of lines.
        <br />
        <br />
        This is the content that
        <br />
        With a lot of lines.
        <br />
        <br />
        This is the content that
        <br />
        With a lot of lines.
        <br />
    </article>
    <footer id="footer" >This is a footer</footer>
</section>

Przygotowałem również JSFiddle z podstawowym przykładem: http://jsfiddle.net/ch7n6/

Jest to witryna internetowa HTML o pełnej wysokości, a stopka znajduje się na dole ze względu na właściwości flexbox elementu content. Proponuję przesunąć pasek między kodem CSS a wynikiem, aby zasymulować różną wysokość.

José Cabo
źródło
1
To nie jest zachowanie, którego szukasz? jsfiddle.net/ch7n6/2
cimmanon
2
jsfiddle.net/ch7n6/3 Tak! To jest. : D Ale nie mogę zrozumieć, dlaczego muszę wskazać wysokość, aby uzyskać efekt. Tak czy inaczej ustawienie: wysokość: 1px; prace
José Cabo
Teraz zmieniłem wysokość na minimalną wysokość. Dużo lepiej. Dzięki Ci.
José Cabo
1
@ JoséCabo +1 - fajna sztuczka wysokość: 0, aby pokazać przewijanie w pionie! Czy możesz wyjaśnić, dlaczego to działa?
Danield,
1
Należy zastosować flex-shrink:0zarówno do nagłówka, jak i stopki.
Saorikido

Odpowiedzi:

210

Dzięki https://stackoverflow.com/users/1652962/cimmanon, który dał mi odpowiedź.

Rozwiązaniem jest ustawienie wysokości pionowego przewijalnego elementu. Na przykład:

#container article {
    flex: 1 1 auto;
    overflow-y: auto;
    height: 0px;
}

Element będzie miał wysokość, ponieważ flexbox przelicza go, chyba że chcesz mieć minimalną wysokość, więc możesz użyć height: 100px;tego, że jest dokładnie taka sama jak:min-height: 100px;

#container article {
    flex: 1 1 auto;
    overflow-y: auto;
    height: 100px; /* == min-height: 100px*/
}

Więc najlepsze rozwiązanie, jeśli chcesz, aby min-heightw przewijaniu pionowym:

#container article {
    flex: 1 1 auto;
    overflow-y: auto;
    min-height: 100px;
}

Jeśli chcesz po prostu przewijać w pionie na wypadek, gdyby nie było wystarczającej ilości miejsca, aby wyświetlić artykuł:

#container article {
    flex: 1 1 auto;
    overflow-y: auto;
    min-height: 0px;
}

Ostateczny kod: http://jsfiddle.net/ch7n6/867/

José Cabo
źródło
2
Używanie min-heightw Chrome nie działa, wpływa to w jakiś sposób na rozmiar stopki. Użycie heightjednak daje pożądany efekt.
phant0m
1
Spróbuj umieścić tę wysokość w miejscu „auto”. Przestudiowałem to i myślę, że właściwym miejscem jest ta nieruchomość. Więc zamiast używać min-height i height, użyj ich.
José Cabo
height: 0naprawiono skoki o 2 piksele, gdy zawartość jest przepełniona, a gdy tak nie jest. Bardzo dziwne. Dzięki.
ProblemsOfSumit
@Sumit, czy możesz przedstawić obraz tego, z jakim problemem masz do czynienia?
José Cabo
Otworzyłem link do skrzypiec i wydaje się, że nie działa już w przeglądarce Chrome (działa w przeglądarce Firefox). Pasek przewijania zniknął. Czy ktoś ma pomysł, jak to znów zadziałać?
obstawia
62

Edytor specyfikacji Flexbox tutaj.

Jest to zalecane użycie flexboksa, ale jest kilka rzeczy, które powinieneś poprawić, aby uzyskać najlepsze zachowanie.

  • Nie używaj przedrostków. Nieprefixed flexbox jest dobrze obsługiwany przez większość przeglądarek. Zawsze zaczynaj od bez prefiksu i dodawaj przedrostki tylko wtedy, gdy jest to konieczne, aby go obsługiwać.

  • Ponieważ nagłówek i stopka nie są przeznaczone do zginania, oba powinny być flex: none;ustawione na nich. W tej chwili masz podobne zachowanie z powodu niektórych nakładających się efektów, ale nie powinieneś na tym polegać, chyba że chcesz przypadkowo się pomylić później. (Domyślnie flex:0 1 autotak jest , więc zaczynają się od ich automatycznej wysokości i mogą się kurczyć, ale nie rosną, ale są również overflow:visibledomyślnie, co uruchamia ich domyślne ustawienie, min-height:autoaby w ogóle zapobiec ich kurczeniu. Jeśli kiedykolwiek ustawisz overflowna nich, zachowanie min-height:autozmian (przełącza się na zero zamiast minimalnej zawartości) i nagle zostaną zmiażdżone przez bardzo wysoki <article>element.)

  • Możesz też uprościć <article> flex- po prostu ustaw flex: 1;i będziesz gotowy do pracy. Staraj się trzymać wspólnych wartości w https://drafts.csswg.org/css-flexbox/#flex-common, chyba że masz dobry powód, aby zrobić coś bardziej skomplikowanego - są one łatwiejsze do odczytania i obejmują większość zachowań będziesz chciał przywołać.

Xanthir
źródło
flex: brak; uratował mnie To pomogło mi mieć element elastyczny, który wziął całą wysokość swoich dzieci i zignorował wysokość 100% swojego rodzica (miał 100% na rodzicu, aby użyć przepełnienia)
CatalinBerta
21

Obecna specyfikacja mówi to w odniesieniu do flex: 1 1 auto:

Wymiaruje element w oparciu o width/ heightproperties, ale czyni je w pełni elastycznymi, dzięki czemu pochłaniają każdą wolną przestrzeń wzdłuż głównej osi. Jeśli wszystkie elementy mają wartość flex: auto, flex: initiallub flex: none, każde dodatnie wolne miejsce po zmianie rozmiaru elementów zostanie równo rozdzielone między elementy flex: auto.

http://www.w3.org/TR/2012/CR-css3-flexbox-20120918/#flex-common

Wydaje mi się, że jeśli powiesz, że element ma 100 pikseli wysokości, jest on traktowany bardziej jako rozmiar „sugerowany”, a nie absolutny. Ponieważ może się kurczyć i rosnąć, zajmuje tyle miejsca, ile mu wolno. Dlatego dodanie tej linii do "głównego" elementu działa: height: 0(lub jakakolwiek inna mała liczba).

cimmanon
źródło