Como alinhar o conteúdo de uma div ao final

1164

Digamos que eu tenha o seguinte código CSS e HTML:

#header {
  height: 150px;
}
<div id="header">
  <h1>Header title</h1>
  Header content (one or multiple lines)
</div>

A seção do cabeçalho tem altura fixa, mas o conteúdo do cabeçalho pode mudar.

Eu gostaria que o conteúdo do cabeçalho estivesse alinhado verticalmente na parte inferior da seção do cabeçalho, para que a última linha do texto "grude" na parte inferior da seção do cabeçalho.

Portanto, se houver apenas uma linha de texto, seria como:

-----------------------------
| Título do cabeçalho
|
|
|
| conteúdo do cabeçalho (resultando em uma linha)
-----------------------------

E se houvesse três linhas:

-----------------------------
| Título do cabeçalho
|
| conteúdo do cabeçalho (que é tão
| muita coisa que perfeitamente
| se estende por três linhas)
-----------------------------

Como isso pode ser feito em CSS?

Kristof
fonte

Respostas:

1323

O posicionamento relativo + absoluto é sua melhor aposta:

#header {
  position: relative;
  min-height: 150px;
}

#header-content {
  position: absolute;
  bottom: 0;
  left: 0;
}

#header, #header * {
  background: rgba(40, 40, 100, 0.25);
}
<div id="header">
  <h1>Title</h1>
  <div id="header-content">Some content</div>
</div>

Mas você pode ter problemas com isso. Quando tentei, tive problemas com os menus suspensos que apareciam abaixo do conteúdo. Simplesmente não é bonito.

Honestamente, para problemas de centralização vertical e, bem, quaisquer problemas de alinhamento vertical com os itens não têm altura fixa, é mais fácil usar apenas tabelas.

Exemplo: você pode fazer esse layout HTML sem usar tabelas?

cleto
fonte
4
Na verdade, encontrei essa solução antes de perguntar aqui, mas de alguma forma esqueci de adicionar a posição: relativa; para o cabeçalho div e o conteúdo continuou sendo exibido na parte inferior da página. Obrigado
kristof 25/02/09
15
Você pode gerenciar sua posição suspensa com a propriedade z-index para trazê-la para frente. Lembre-se de que a propriedade z-index trabalha com elementos posicionados de forma relativamente ou absoluta. Além disso, não é correto falar semanticamente para usar uma tabela para obter resultados de layout.
Alejandro García Iglesias
1
No caso de conteúdo de texto, conforme descrito no problema original, # header-content deve realmente ser um pelemento, ou pelo menos umspan
Josh Burgess
2
Não use tabelas para dados não tabulares! Em vez disso, use as propriedades de exibição CSS display: table-cell, ou table-row, ou table. Você nunca mais precisará usar tabelas para o layout puro.
Jeremy Moritz
1
A posição do cabeçalho é relativa a quê?
stack1
158

Use o posicionamento CSS:

/* Creates a new stacking context on the header */
#header {
  position: relative;
}

/* Positions header-content at the bottom of header's context */
#header-content {
  position: absolute;
  bottom: 0;
}

Como observou o cletus , você precisa identificar o conteúdo do cabeçalho para fazer isso funcionar.

<span id="header-content">some header content</span>

<div style="height:100%; position:relative;">
    <div style="height:10%; position:absolute; bottom:0px;">bottom</div>
</div>
Patrick McElhaney
fonte
4
fyi ... isso causou o meu cabeçalho conteúdo a entrar em colapso a sua largura, então eu tive que adicionar um width = '100%'no cabeçalho do conteúdo
dsdsdsdsd
2
@dsdsdsdsd Você também pode corrigir isso adicionando display: block em # header-content.
Patrick McElhaney
1
@dsdsdsdsd O motivo é que os <span>elementos possuem, display: inline;por padrão, o que não ocupa toda a largura do contêiner. A correção mais apropriada seria alterar a extensão para a <div>, que é um elemento de bloco por padrão.
21917 BadHorsie
1
Ou um dos <h1> - <h6>, que também é bloqueado por padrão e identifica o texto como um cabeçalho, útil para mecanismos de pesquisa, tecnologias de assistência e pessoas que lêem o código.
Patrick McElhaney
Não funciona quando o conteúdo na parte inferior tem altura variável, fazendo com que ele se estenda para fora dos limites do contêiner.
Mozfet 16/05/19
126

Se você não está preocupado com navegadores herdados, use um flexbox.

O elemento pai precisa de seu tipo de exibição definido para flexionar

div.parent {
  display: flex;
  height: 100%;
}

Em seguida, você define o alinhamento do elemento filho como flex-end.

span.child {
  display: inline-block;
  align-self: flex-end;
}

Aqui está o recurso que eu usei para aprender: http://css-tricks.com/snippets/css/a-guide-to-flexbox/

Lee Irvine
fonte
@ bafromca, duas razões que não funcionam. 1: Use 'align-self' em vez de align-items (culpa minha, editei minha postagem original). 2: 100% de altura não funcionará, a menos que o pai tenha altura.
Lee Irvine
Não funcionou para mim, quero-o no fundo do contêiner, não no final dos itens no contêiner.
Mozfet 16/05/19
Em 2020, essa deve ser a resposta correta: caniuse.com/#feat=flexbox
tonygatta
119

Eu uso essas propriedades e funciona!

#header {
  display: table-cell;
  vertical-align: bottom;
}
johannchopin
fonte
42
Não é suportado no IE8 e versões anteriores. É suportado no IE9.
random_user_name
23
@cale_b Segundo caniuse.com ele FAZ trabalho no IE8.
Zach Lysobey
5
@ZachL Happenstance - Estou suportando um aplicativo herdado no IE8 para um cliente corporativo e isso realmente funciona.
Daniel Szabo
4
@fguillen: testado no Chrome (v31) agora também. Trabalha lá também.
precisa
5
table-cellquebra muitas coisas. Como o sistema de grade do Bootstrap. col-md-12não lhe dará mais um div de 100%.
Noah
65

Depois de lutar com esse mesmo problema por algum tempo, finalmente descobri uma solução que atende a todos os meus requisitos:

  • Não requer que eu saiba a altura do contêiner.
  • Diferente das soluções relativas + absolutas, o conteúdo não flutua em sua própria camada (ou seja, incorpora normalmente na div do contêiner).
  • Funciona em navegadores (IE8 +).
  • Simples de implementar.

A solução leva apenas um <div>, que eu chamo de "alinhador":

CSS

.bottom_aligner {
    display: inline-block;
    height: 100%;
    vertical-align: bottom;
    width: 0px;
}

html

<div class="bottom_aligner"></div>
... Your content here ...

Esse truque funciona criando uma div alta e fina, que empurra a linha de base do texto para a parte inferior do contêiner.

Aqui está um exemplo completo que alcança o que o OP estava pedindo. Fiz o "bottom_aligner" grosso e vermelho apenas para fins de demonstração.

CSS:

.outer-container {
  border: 2px solid black;
  height: 175px;
  width: 300px;
}

.top-section {
  background: lightgreen;
  height: 50%;
}

.bottom-section {
  background: lightblue;
  height: 50%;
  margin: 8px;
}

.bottom-aligner {
  display: inline-block;
  height: 100%;
  vertical-align: bottom;
  width: 3px;
  background: red;
}

.bottom-content {
  display: inline-block;
}

.top-content {
  padding: 8px;
}

HTML:

<body>
  <div class="outer-container">
    <div class="top-section">
      This text
      <br> is on top.
    </div>
    <div class="bottom-section">
      <div class="bottom-aligner"></div>
      <div class="bottom-content">
        I like it here
        <br> at the bottom.
      </div>
    </div>
  </div>
</body>

Alinhar o conteúdo inferior

Greg Prisament
fonte
Quase perfeito :) mas não permite quebras de linha automáticas.
Gaston Sanchez
Não funciona se o contêiner externo puder rolar (estouro-y: automático). :(
ecraig12345
eu acho que marin: 8px deve ser margin: 8px
Graham Perrin
2
Isso também funciona se for colocado em uma ::beforeregra, o que remove a necessidade de um elemento extra. Usamos flex no final, mas isso é útil quando você não pode.
Sheepy
Esta é uma solução muito boa. Funciona apenas se o heightda caixa / contêiner e seus pais estiverem definidos (para px ou% ou o que for).
BairDev
38

A maneira moderna de fazer isso seria usar flexbox . Veja o exemplo abaixo. Você nem precisa quebrarSome text...em nenhuma tag HTML, pois o texto diretamente contido em um contêiner flexível é envolvido em um item flexível anônimo.

header {
  border: 1px solid blue;
  height: 150px;
  display: flex;                   /* defines flexbox */
  flex-direction: column;          /* top to bottom */
  justify-content: space-between;  /* first item at start, last at end */
}
h1 {
  margin: 0;
}
<header>
  <h1>Header title</h1>
  Some text aligns to the bottom
</header>

Se houver apenas algum texto e você desejar alinhar verticalmente a parte inferior do contêiner.

section {
  border: 1px solid blue;
  height: 150px;
  display: flex;                   /* defines flexbox */
  align-items: flex-end;           /* bottom of the box */
}
<section>Some text aligns to the bottom</section>

Adesivos
fonte
2
Eu precisava que meu elemento alinhado por baixo ainda estivesse presente no fluxo de documentos, o que não é possível ao usar position:absolute;. Esta solução funcionou perfeitamente para o meu caso!
Swen
1
Dentro de reagir componentes, esta é a solução certa. A solução aceita falha.
Soleil - Mathieu Pré-
1
Esta é a única solução que realmente funcionou para mim. Talvez isso tenha a ver com o React, como o @Soleil mencionou ... Eu não sou um especialista em CSS, por isso não tenho certeza.
BK
Funciona perfeitamente no componente de reação
user1155773
25

Os elementos embutidos ou de bloco embutido podem ser alinhados à parte inferior dos elementos de nível de bloco se a altura da linha do elemento pai / bloco for maior que a do elemento embutido. *

marcação:

<h1 class="alignBtm"><span>I'm at the bottom</span></h1>

css:

h1.alignBtm {
  line-height: 3em;
}
h1.alignBtm span {
  line-height: 1.2em;
  vertical-align: bottom;
}

* verifique se você está no modo padrão

dougwig
fonte
25
display: flex;
align-items: flex-end;
user3053247
fonte
2
Observe que o flexbox não é bem suportado em navegadores antigos.
AnthonyB 2/17/17
11
@AnthonyB - define old? Temos que mudar esse registro como desenvolvedores. A tecnologia avança, e os antigos simplesmente não sobrevivem. O IE9 e o 10 têm problemas com o flex do que eu posso ver, mas eles foram lançados em 2011 e 2012, respectivamente ... é 2017. Temos que deixar de lado esses navegadores desatualizados e quebrados. Se não for por satisfação visual, mas por segurança e atualizações gerais de software.
Tisch
3
@ Tisch, você está absolutamente certo de que precisamos, como desenvolvedores, usar tecnologia decente e recente. Mas eu simplesmente avisei sobre esse problema de compatibilidade, para não ser surpreendido.
AnthonyB
se o conteúdo abaixo <h1>estiver dentro de um <p>ou <div>eu usaria justify-content: space-between.
Agapitocandemor
11

Você pode simplesmente obter flexibilidade

header {
  border: 1px solid blue;
  height: 150px;
  display: flex;                   /* defines flexbox */
  flex-direction: column;          /* top to bottom */
  justify-content: space-between;  /* first item at start, last at end */
}
h1 {
  margin: 0;
}
<header>
  <h1>Header title</h1>
  Some text aligns to the bottom
</header>

MK Vimalan
fonte
6

Se você tiver vários itens dinâmicos de altura, use os valores de exibição CSS da tabela e da célula da tabela:

HTML

<html>
<body>

  <div class="valign bottom">
    <div>

      <div>my bottom aligned div 1</div>
      <div>my bottom aligned div 2</div>
      <div>my bottom aligned div 3</div>

    </div>
  </div>

</body>
</html>

CSS

html,
body {
  width: 100%;
  height: 100%;
}
.valign {
  display: table;
  width: 100%;
  height: 100%;
}
.valign > div {
  display: table-cell;
  width: 100%;
  height: 100%;
}
.valign.bottom > div {
  vertical-align: bottom;
}

Criei uma demonstração do JSBin aqui: http://jsbin.com/INOnAkuF/2/edit

A demonstração também tem um exemplo de como centralizar verticalmente o alinhamento usando a mesma técnica.

Romiem
fonte
5

Aqui está outra solução usando o flexbox, mas sem o uso do flex-end para o alinhamento inferior. A idéia é definir margin-bottomem h1 a auto para empurrar o conteúdo restante para o fundo:

#header {
  height: 350px;
  display:flex;
  flex-direction:column;
  border:1px solid;
}

#header h1 {
 margin-bottom:auto;
}
<div id="header">
  <h1>Header title</h1>
  Header content (one or multiple lines) Header content (one or multiple lines)Header content (one or multiple lines) Header content (one or multiple lines)
</div>

Também podemos fazer o mesmo com margin-top:autoo texto, mas, neste caso, precisamos envolvê-lo dentro de um divou span:

#header {
  height: 350px;
  display:flex;
  flex-direction:column;
  border:1px solid;
}

#header span {
 margin-top:auto;
}
<div id="header">
  <h1>Header title</h1>
  <span>Header content (one or multiple lines)</span>
</div>

Temani Afif
fonte
Perfecto! Gracias
Grace Nikole
4

Você não precisa de absoluto + relativo para isso. É muito possível usar a posição relativa para o contêiner e os dados. É assim que se faz.

Suponha que a altura dos seus dados será x. Seu contêiner é relativo e o rodapé também é relativo. Tudo o que você precisa fazer é adicionar aos seus dados

bottom: -webkit-calc(-100% + x);

Seus dados sempre estarão na parte inferior do seu contêiner. Funciona mesmo se você tiver contêiner com altura dinâmica.

HTML será assim

<div class="container">
  <div class="data"></div>
</div>

CSS será assim

.container{
  height:400px;
  width:600px;
  border:1px solid red;
  margin-top:50px;
  margin-left:50px;
  display:block;
}
.data{
  width:100%;
  height:40px;
  position:relative;
   float:left;
  border:1px solid blue;
  bottom: -webkit-calc(-100% + 40px);
   bottom:calc(-100% + 40px);
}

Exemplo ao vivo aqui

Espero que isto ajude.

Aditya Ponkshe
fonte
Você pode explicar o que bottom: -webkit-calc(-100% + x);está fazendo?
Mhatch
@mhatch mantém o rodapé na parte inferior do contêiner.
Aditya Ponkshe
4

Aqui está a maneira flexível de fazer isso. Obviamente, ele não é suportado pelo IE8, como o usuário precisava há 7 anos. Dependendo do que você precisa oferecer suporte, algumas delas podem ser eliminadas.

Ainda assim, seria bom se houvesse uma maneira de fazer isso sem um contêiner externo, basta que o texto se alinhe dentro de si mesmo.

#header {
    -webkit-box-align: end;
    -webkit-align-items: flex-end;
    -ms-flex-align: end;
    align-items: flex-end;
    display: -webkit-box;
    display: -webkit-flex;
    display: -ms-flexbox;
    display: flex;
    height: 150px;
}
Absynthe Minded Smith Web
fonte
4

uma solução muito simples, de uma linha, é adicionar altura à div, tendo em mente que todo o texto da div ficará no fundo.

CSS:

#layer{width:198px;
       height:48px;
       line-height:72px;
       border:1px #000 solid}
#layer a{text-decoration:none;}

HTML:

<div id="layer">
    <a href="#">text at div's bottom.</a>
</div>

lembre-se de que esta é uma solução prática e rápida quando você deseja que o texto dentro de div seja reduzido; se você precisar combinar imagens e outras coisas, precisará codificar um CSS um pouco mais complexo e responsivo

Pablo Contreras
fonte
3

se você pode definir a altura da divisão de agrupamento do conteúdo (# cabeçalho-conteúdo, como mostrado na resposta de outras pessoas), em vez de todo o # cabeçalho, talvez você também possa tentar esta abordagem:

HTML

<div id="header">
    <h1>some title</h1>
    <div id="header-content">
        <span>
            first line of header text<br>
            second line of header text<br>
            third, last line of header text
        </span>
    </div>
</div>

CSS

#header-content{
    height:100px;
}

#header-content::before{
  display:inline-block;
  content:'';
  height:100%;
  vertical-align:bottom;
}

#header-content span{
    display:inline-block;
}

mostrar no codepen

codeboy
fonte
3

Parece estar funcionando:

HTML: estou na parte inferior

css:

h1.alignBtm {
  line-height: 3em;
}
h1.alignBtm span {
  line-height: 1.2em;
  vertical-align: bottom;
}
Arquivo de administrador3
fonte
3

Todas essas respostas e nenhuma funcionaram para mim ... Eu não sou especialista em flexbox, mas isso foi razoavelmente fácil de entender, é simples e fácil de entender e usar. Para separar algo do restante do conteúdo, insira uma div vazia e deixe crescer para preencher o espaço.

https://jsfiddle.net/8sfeLmgd/1/

.myContainer {
  display: flex;
  height: 250px;
  flex-flow: column;
}

.filler {
  flex: 1 1;
}
<div class="myContainer">
  <div>Top</div>
  <div class="filler"></div>
  <div>Bottom</div>
</div>

Isso reage como esperado quando o conteúdo inferior não é de tamanho fixo, também quando o contêiner não é de tamanho fixo.

Mozfet
fonte
3

Eu projetei uma maneira muito mais simples do que o que foi mencionado.

Defina a altura da div do cabeçalho. Depois, estilize sua H1tag da seguinte maneira:

float: left;
padding: 90px 10px 11px

Estou trabalhando em um site para um cliente, e o design exige que o texto esteja na parte inferior de uma determinada div. Consegui o resultado usando essas duas linhas e funciona bem. Além disso, se o texto for expandido, o preenchimento continuará o mesmo.

mickburkejnr
fonte
1
Faz com que o conteúdo flutue sobre outro ao redimensionar telas usando layouts responsivos.
Mozfet 16/05/19
2

Encontrei esta solução em baixo em um modelo inicial de inicialização

/* HTML */

<div class="content_wrapper">
  <div class="content_floating">
    <h2>HIS This is the header<br>
      In Two Rows</h2>
    <p>This is a description at the bottom too</p> 
  </div>
</div>

/* css */

.content_wrapper{
      display: table;
      width: 100%;
      height: 100%; /* For at least Firefox */
      min-height: 100%;
    }

.content_floating{
  display: table-cell;
  vertical-align: bottom;
  padding-bottom:80px;

}
XMaster
fonte
2
#header {
    height: 150px;
    display:flex;
    flex-direction:column;
}

.top{
    flex: 1;
}   

<div id="header">
    <h1 class="top">Header title</h1>
    Header content (one or multiple lines)
</div>

#header {
    height: 250px;
    display:flex;
    flex-direction:column;
    background-color:yellow;
}

.top{
    flex: 1;
}
<div id="header">
    <h1 class="top">Header title</h1>
    Header content (one or multiple lines)
</div>

user841657
fonte
1
Isso causa o redimensionamento da div superior. O que funciona para layouts básicos de texto, mas não funciona quando as coisas têm planos de fundo, cores e tamanhos a serem respeitados.
Mozfet 16/05/19
0

tente com:

div.myclass { margin-top: 100%; }

tente alterar o% para corrigi-lo. Exemplo: 120% ou 90% ... etc.

felix
fonte
Funciona perfeitamente com 1 conjunto de conteúdo, mas precisará ser ajustado se o conteúdo for alterado. Se for um conteúdo dinâmico, não use isso!
Mike Graf
0

O site que acabei de criar para um cliente solicitou que o texto do rodapé fosse uma caixa alta, com o texto na parte inferior que eu consegui com preenchimento simples, deve funcionar para todos os navegadores.

<div id="footer">
  some text here
</div>
#footer {
  padding: 0 30px;
  padding-top: 60px;
  padding-bottom: 8px;
}
Nicki L. Hansen
fonte
1
Sua primeira declaração padding: 0 30pxé um pouco redundante, você pode também ter colocado padding: 30pxas outras 2 declarações.
Andrew
Absolutamente verdade, no entanto, estou seguindo as práticas do meu local de trabalho.
Nicki L. Hansen
6
Realmente ?, isso parece uma péssima prática. Basta usar a abreviação ou ser explícito em qualquer lugar. padding: 60px 30px 8px;, padding: 60px 30px 8px 30px;, Quatro explícitas padding-regras, ou mesmo @ sugestão de TheWaxMann são todos superiores - e estou disposto e capaz de argumentar que um ;-)
Zach Lysobey
-3

Um exemplo perfeito entre navegadores é provavelmente este aqui:

http://www.csszengarden.com/?cssfile=/213/213.css&page=0

A idéia é exibir o div na parte inferior e também fazê-lo ficar lá. Freqüentemente, a abordagem simples fará com que a div pegajosa role para cima com o conteúdo principal.

A seguir, é apresentado um exemplo mínimo totalmente funcional. Observe que não há truques de incorporação de div necessários. As muitas BRs são apenas para forçar a exibição de uma barra de rolagem:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        #floater {
            background: yellow;
            height: 200px;
            width: 100%;
            position: fixed;
            bottom: 0px;
            z-index: 5;
            border-top: 2px solid gold;
        }

    </style>
</head>


<body>
    <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
    <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
    <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
    <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>


    <div id="floater"></div>
</body>
</html>

Se você está pensando que seu código pode não estar funcionando no IE, lembre-se de adicionar a tag DOCTYPE na parte superior. É crucial que isso funcione no IE. Além disso, essa deve ser a primeira tag e nada deve aparecer acima dela.

Fakeer
fonte
28
Desde que você está declarando seu documento como XHTML estrito, você deve também auto-fechar os <br />tags de ...
Amos M. Carpenter
7
@ KarlKildén, se você estava se referindo ao comentário de aaamos, definitivamente não é um comentário bobo - exibir o documento acima com o cabeçalho corretocontent-type resultaria no navegador lançando um erro de análise de XML.
Razor
7
Esta é uma má prática! Use CSS em vez disso!
M93a 28/09/2013
-4

Parece estar funcionando:

#content {
    /* or just insert a number with "px" if you're fighting CSS without lesscss.org :) */
    vertical-align: -@header_height + @content_height;

    /* only need it if your content is <div>,
     * if it is inline (e.g., <a>) will work without it */
    display: inline-block;
}

Usar menos torna a solução de quebra-cabeças CSS muito mais como codificação do que como ... Eu simplesmente amo CSS. É um verdadeiro prazer quando você pode alterar todo o layout (sem quebrá-lo :) apenas alterando um parâmetro.

esp
fonte
-7

Solução 2015

<div style='width:200px; height:60px; border:1px solid red;'>

    <table width=100% height=100% cellspacing=0 cellpadding=0 border=0>
        <tr><td valign=bottom>{$This_text_at_bottom}</td></tr>
    </table>

</div>

http://codepen.io/anon/pen/qERMdx

não há de quê

waza123
fonte
3
O layout da tabela para isso pode ser problemático; CSS é recomendado. A propriedade valign também não é suportada em HTML5. (veja w3schools.com/tags/att_td_valign.asp )
undeniablyrob