Como posso combinar flexbox e rolagem vertical em um aplicativo de altura total?

101

Eu quero usar um aplicativo de altura total usando o flexbox. Eu encontrei o que eu queria usando o antigo módulo de layout flexbox ( display: box;e outras coisas) neste link: CSS3 Flexbox full-height app and overflow

Esta é uma solução correta para navegadores que suportam apenas a versão antiga das propriedades CSS do flexbox.

Se eu quiser tentar usar as propriedades mais recentes do flexbox, tentarei usar a segunda solução no mesmo link listado como um hack: usando um contêiner com height: 0px;. Faz mostrar um scroll vertical.

Eu não gosto muito porque introduz outros problemas e é mais uma solução alternativa do que uma solução.

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>

Eu preparei um JSFiddle também com um exemplo básico: http://jsfiddle.net/ch7n6/

É um site HTML de altura total e o rodapé está na parte inferior por causa das propriedades flexbox do elemento de conteúdo. Eu sugiro que você mova a barra entre o código CSS e o resultado para simular alturas diferentes.

José cabo
fonte
Este não é o comportamento que você está procurando? jsfiddle.net/ch7n6/2
cimmanon
2
jsfiddle.net/ch7n6/3 Sim! Isto é. : D Mas não consigo entender porque preciso indicar uma altura para obter o efeito. De qualquer forma, configuração: altura: 1px; obras
José Cabo
Agora mudei a altura para uma altura mínima. Muito melhor. Te agradece.
José Cabo
1
@ JoséCabo +1 - boa altura do truque: 0 para mostrar a rolagem vertical! Você poderia explicar por que isso funciona?
Danield
1
Você deve aplicar flex-shrink:0tanto ao cabeçalho quanto ao rodapé.
Saorikido de

Respostas:

202

Obrigado a https://stackoverflow.com/users/1652962/cimmanon que me deu a resposta.

A solução é definir uma altura para o elemento rolável vertical. Por exemplo:

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

O elemento terá altura porque o flexbox o recalcula, a menos que você queira uma altura mínima para que possa usá- height: 100px;la exatamente igual a:min-height: 100px;

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

Portanto, a melhor solução se você quiser uma min-heightrolagem vertical:

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

Se você deseja apenas a rolagem vertical completa, caso não haja espaço suficiente para ver o artigo:

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

O código final: http://jsfiddle.net/ch7n6/867/

José cabo
fonte
2
Usar min-heightno Chrome não funciona, de alguma forma afeta o tamanho do rodapé. Usar height, entretanto, dá o resultado desejado.
phant0m
1
Tente colocar essa altura onde está o "auto". Já estudei isso e acho que o lugar certo é esse imóvel. Portanto, em vez de usar min-height e height, use-o.
José Cabo
height: 0corrigiu alguns pulos de 2px quando o conteúdo estava transbordando versus quando não estava. Tão estranho. Obrigado mesmo assim.
ProblemsOfSumit
@Sumit, você pode fornecer uma imagem de qual problema você está enfrentando?
José Cabo
Abri o link do violino e não parece mais estar funcionando no Chrome (funciona no Firefox). A barra de rolagem desapareceu. Alguém tem uma ideia de como fazer isso funcionar de novo?
apostas em
61

Editor de especificações Flexbox aqui.

Este é um uso encorajado do flexbox, mas existem algumas coisas que você deve ajustar para melhor comportamento.

  • Não use prefixos. Flexbox sem prefixo é bem suportado na maioria dos navegadores. Sempre comece com não prefixado e só adicione prefixos se necessário para apoiá-lo.

  • Como o cabeçalho e o rodapé não devem ser flexíveis, os dois deveriam estar flex: none;definidos neles. No momento, você tem um comportamento semelhante devido a alguns efeitos sobrepostos, mas não deve confiar nisso, a menos que queira acidentalmente se confundir mais tarde. (O padrão é flex:0 1 auto, então eles começam em sua altura automática e podem encolher, mas não aumentar, mas eles também são overflow:visiblepor padrão, o que aciona seu padrão min-height:autopara evitar que encolham. Se você definir um overflowneles, o comportamento min-height:automudará (mudando para zero em vez de conteúdo mínimo) e de repente eles serão esmagados pelo <article>elemento extra alto .)

  • Você também pode simplificar <article> flex- basta configurar flex: 1;e você estará pronto para começar. Tente seguir os valores comuns em https://drafts.csswg.org/css-flexbox/#flex-common, a menos que você tenha um bom motivo para fazer algo mais complicado - eles são mais fáceis de ler e abordam a maioria dos comportamentos você deseja invocar.

Xanthir
fonte
21

A especificação atual diz o seguinte sobre flex: 1 1 auto:

Dimensiona o item com base nas propriedades width/ height, mas os torna totalmente flexíveis, de modo que absorvem qualquer espaço livre ao longo do eixo principal. Se todos os itens são ou flex: auto, flex: initialou flex: none, qualquer espaço livre positivo após os itens foram dimensionadas serão distribuídos uniformemente para os itens com flex: auto.

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

Parece-me que se você disser que um elemento tem 100 px de altura, ele é tratado mais como um tamanho "sugerido", não como absoluto. Como ele pode encolher e crescer, ele ocupa tanto espaço quanto é permitido. É por isso que adicionar esta linha ao seu elemento "principal" funciona: height: 0(ou qualquer outro número pequeno).

Cimmanon
fonte