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?

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?


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>

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/


@ 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;
}

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


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>


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


25
display: flex;
align-items: flex-end;

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>


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.


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>


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.


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;
}

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


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


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;
}

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.


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.


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;

}

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>


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.


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;
}

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.


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.


Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.