Como alinhar os elementos da grade no layout do fluido de bootstrap

123

Eu tenho um layout fluido usando a inicialização do Twitter, em que tenho uma linha com duas colunas. A primeira coluna tem muito conteúdo, que eu quero preencher normalmente. A segunda coluna apenas possui um botão e algum texto, que eu quero alinhar na parte inferior em relação à célula na primeira coluna.

Aqui está o que eu tenho:

-row-fluid-------------------------------------
+-span6----------+ +-span6----------+
|                | |short content   |
| content        | +----------------+
| that           | 
| is tall        |    
|                |
+----------------+
-----------------------------------------------

Aqui está o que eu quero:

-row-fluid-------------------------------------
+-span6----------+
|                |
| content        |
| that           | 
| is tall        | +-span6----------+    
|                | |short content   |
+----------------+ +----------------+
-----------------------------------------------

Eu já vi soluções que tornam o primeiro período uma altura absoluta e posicionam o segundo período em relação a ele, mas seria preferível uma solução em que eu não tivesse que especificar a altura absoluta dos meus divs. Também estou aberto a um repensar completo de como obter o mesmo efeito. Não sou casada com esse uso do andaime, apenas parecia fazer mais sentido para mim.

Esse layout como um violino:

http://jsfiddle.net/ryansturmer/A7buv/3/

Ryan
fonte
você não pode adicionar uma margem superior de cerca de 200 pixels ao seu .rightspan?
Richlewis
Atalho para CSS única resposta para esta pergunta: stackoverflow.com/a/14223553/259725
Adam
bootply.com/125740# (Desculpe eu esqueço qual resposta ao qual SO questionar esta ligação é de.)
ToolmakerSteve

Respostas:

50

Atenção: para usuários do Bootstrap 4+, considere a solução da Christophe (o Bootstrap 4 introduziu o flexbox, que fornece uma solução somente CSS mais elegante). O seguinte funcionará para versões anteriores do Bootstrap ...


Consulte http://jsfiddle.net/jhfrench/bAHfj/ para obter uma solução funcional.

//for each element that is classed as 'pull-down', set its margin-top to the difference between its own height and the height of its parent
$('.pull-down').each(function() {
  var $this = $(this);
  $this.css('margin-top', $this.parent().height() - $this.height())
});

Do lado positivo:

  • no espírito das classes auxiliares existentes do Bootstrap, chamei a classepull-down .
  • somente o elemento que está sendo "puxado para baixo" precisa ser classificado, então ...
  • ... é reutilizável para diferentes tipos de elementos (div, span, seção, p, etc)
  • é razoavelmente bem suportado (todos os principais navegadores suportam margem superior)

Agora as más notícias:

  • requer jQuery
  • não é, como está escrito, responsivo (desculpe)
Jeromy French
fonte
3
para capacidade de resposta, talvez conecte a janela. redimensionar? stackoverflow.com/a/2969091/244811
Scott Weaver
22
Não use uma solução jQuery para algo que possa ser uma solução CSS. Existem muitas razões para evitar a manipulação do DOM para fins de estilo.
Archonic
1
@Archonic: o que é essa solução somente CSS? Eu também preferiria a uma solução dependente de JS. Basta ter em mente estipulação do OP: "uma solução onde eu não tinha para especificar a altura absoluta das minhas divs seria preferível"
Jeromy Francês
1
@cfx Publicou uma solução css only com um violino que não requer alturas absolutas.
Archonic
1
Por outro lado, minha solução permite ao usuário alinhar elementos individuais (dando comportamento semelhante ao do Bootstrap .pull-lefte .pull-right), sem afetar os irmãos. Isso pode ser feito com a solução somente CSS?
Jeromy French
68

Esta é uma solução atualizada para o Bootstrap 3 (embora deva funcionar para versões mais antigas) que usa apenas CSS / LESS:

http://jsfiddle.net/silb3r/0srp42pb/11/

Você define o tamanho da fonte como 0 na linha (caso contrário, você acaba com um espaço irritante entre as colunas), remove os flutuadores da coluna, define a exibição como inline-block, redefine o tamanho da fonte e, em seguida,vertical-align pode ser definido como qualquer coisa que você precise.

Não é necessário jQuery.

cfx
fonte
Eu quero mantê-lo no meio. No entanto, no seu jsfiddle quando tentei "vertical-allign: middle", não funcionou. Alguma ideia?
joy
Tente configurar os dois divpara vertical-align: middle;.
cfx
6
Esta é a única resposta aceitável! @ Lukas ignorará larguras em colunas que não preenchem uma linha. E manipulação DOM para estilizar ... SMH.
Archonic
Seu CSS é digitado fora da linha (especificamente .myrow) ... isso não significa que você não pode ter uma coluna alinhada no topo, uma coluna alinhada no fundo e uma terceira coluna alinhada no topo?
Jeromy French
Obrigado ! Funciona bem com o Bootstrap 4.
Elie Teyssedou
33

Você pode usar o flex:

@media (min-width: 768px) {
  .row-fluid {
    display: flex;
    align-items: flex-end;
  }
}
Christophe
fonte
Usar felx é muito agradável e direto na minha opinião e eu tinha mais uma vantagem usando "align-items: baseline", ótimo com fontes diferentes nos diferentes itens a serem alinhados.
Alessandro Dentella 12/03
Excelente sugestão para usar o flex. Simples, direto e usa o Bootstrap para resolver um problema do Bootstrap.
CheddarMonkey
1
Resposta brilhante e funciona perfeitamente com o bootstrap sem necessidade de javascript / jquery.
Filth
1
Sim, adicione isso a uma linha de inicialização regular e bam, ele funciona. Lindo. Como uma solução jquery não responsiva se tornou a principal resposta? Nunca saberemos.
Levi Fuller
@LeviFuller Meu palpite é porque esta solução suporta apenas um ponto de interrupção
clamchoda
27

Você precisa adicionar algum estilo para span6, smthg assim:

.row-fluid .span6 {
  display: table-cell;
  vertical-align: bottom;
  float: none;
}

e este é o seu violino: http://jsfiddle.net/sgB3T/

Lukas
fonte
4
Eu criaria uma classe css específica em vez de defini-la como span6, mas a estratégia de célula de tabela funciona bem! Eu também tive que definir "display: table-row" para a div que contém as larguras corretas.
Meta-Knight
3
Para o Bootstrap 3, adicionei esta regra: .row.align-bottom> [class ^ = col] {display: table-cell; alinhamento vertical: inferior; float: nenhum; } aplique o alinhamento inferior à linha & lt; div class = "row align-bottom" & gt;
Martin
@ Martin, sua regra funciona bem quando você também define .align-bottom {display: table-row;}, no entanto, o alinhamento da linha está desativado porque as linhas da tabela não respeitam o bootstrap de margem esquerda e margem direita: -15px ......pensamentos?
Alex White
@AlexWhite - Coloque padding-left: 0e coloque padding-right: 0todas as colunas nessa linha.
AnalogWeapon 27/01
1
Isso ignorará as larguras das colunas quando as colunas não preencherem a largura de uma linha. Ao usar deslocamentos, por exemplo.
Archonic
14

Aqui também está uma diretiva angularjs para implementar essa funcionalidade

    pullDown: function() {
      return {
        restrict: 'A',
        link: function ($scope, iElement, iAttrs) {
          var $parent = iElement.parent();
          var $parentHeight = $parent.height();
          var height = iElement.height();

          iElement.css('margin-top', $parentHeight - height);
        }
      };
    }
Ilya Schukin
fonte
7

Basta definir o pai display:flex;e o filho para margin-top:auto. Isso colocará o conteúdo filho na parte inferior do elemento pai, assumindo que o elemento pai tenha uma altura maior que o elemento filho.

Não há necessidade de tentar calcular um valor para margin-topquando você tem uma altura em seu elemento pai ou outro elemento maior que seu elemento filho de interesse no elemento pai.

sissypants
fonte
Essa deve ser a resposta aceita: é curta, simples e funciona em qualquer navegador que suporte flex. A única desvantagem é que quebra a capacidade de resposta.
tbm
4

Com base nas outras respostas, aqui está uma versão ainda mais responsiva. Fiz alterações na versão de Ivan para oferecer suporte a viewports com largura <768px e para melhor suporte ao redimensionamento lento da janela.

!function ($) { //ensure $ always references jQuery
    $(function () { //when dom has finished loading
        //make top text appear aligned to bottom: http://stackoverflow.com/questions/13841387/how-do-i-bottom-align-grid-elements-in-bootstrap-fluid-layout
        function fixHeader() {
            //for each element that is classed as 'pull-down'
            //reset margin-top for all pull down items
            $('.pull-down').each(function () {
                $(this).css('margin-top', 0);
            });

            //set its margin-top to the difference between its own height and the height of its parent
            $('.pull-down').each(function () {
                if ($(window).innerWidth() >= 768) {
                    $(this).css('margin-top', $(this).parent().height() - $(this).height());
                }
            });
        }

        $(window).resize(function () {
            fixHeader();
        });

        fixHeader();
    });
}(window.jQuery);
bbodenmiller
fonte
obrigado por esse refinamento, acabei de o aceitar em um projeto atual e está funcionando bem.
sifriday
1
Por que definir margin-topcomo 0 e defini-lo novamente para o novo valor? Além disso, por que essas coisas estão em dois each()"loops"?
Jeromy French
4

Isso é baseado na solução da cfx, mas em vez de definir o tamanho da fonte como zero no contêiner pai para remover os espaços entre colunas adicionados devido à exibição: bloco em linha e ter que redefini-los, eu simplesmente adicionei

.row.row-align-bottom > div {
    float: none;
    display: inline-block;
    vertical-align: bottom;
    margin-right: -0.25em;
}

para a coluna divs para compensar.

Kirtlander
fonte
0

Bem, eu não gostava de nenhuma dessas respostas, a minha solução do mesmo problema foi adicionar o seguinte: <div>&nbsp;</div>. Portanto, no seu esquema, ficaria assim (mais ou menos), nenhuma mudança de estilo foi necessária no meu caso:

-row-fluid-------------------------------------
+-span6----------+ +----span6----------+
|                | | +---div---+       |
| content        | | | & nbsp; |       |
| that           | | +---------+       |
| is tall        | | +-----div--------+|   
|                | | |short content   ||
|                | | +----------------+|
+----------------+ +-------------------+
-----------------------------------------------
jan b
fonte
4
Como você sabe o número de &nbsp;a adicionar se o comprimento da célula esquerda for desconhecido?
precisa saber é o seguinte
-2
.align-bottom {
    position: absolute;
    bottom: 10px;
    right: 10px;
}
Douglas Ribeiro
fonte
1
você deve tentar acrescentar outras informações para a sua resposta explicando por que responde à pergunta OP
MLavoie