Comment aligner les éléments de la grille par le bas dans une mise en page fluide bootstrap

123

J'ai une mise en page fluide utilisant le bootstrap de Twitter, dans lequel j'ai une ligne avec deux colonnes. La première colonne a beaucoup de contenu, que je veux remplir normalement. La deuxième colonne a juste un bouton et du texte, que je veux aligner en bas par rapport à la cellule de la première colonne.

Voici ce que j'ai:

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

Voici ce que je veux:

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

J'ai vu des solutions qui font de la première travée une hauteur absolue et positionnent la deuxième travée par rapport à elle, mais une solution où je n'ai pas besoin de spécifier la hauteur absolue de mes divs serait préférée. Je suis également ouvert à une réflexion complète sur la manière d'obtenir le même effet. Je ne suis pas marié à cette utilisation de l'échafaudage, cela me semblait le plus logique.

Cette disposition comme un violon:

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

Ryan
la source
ne pourriez-vous pas ajouter une marge supérieure d'environ 200px à votre .rightspan?
Richlewis
Raccourci vers CSS uniquement pour répondre à cette question: stackoverflow.com/a/14223553/259725
Adam
bootply.com/125740# (Désolé, j'oublie de quelle réponse la question SO provient ce lien.)
ToolmakerSteve

Réponses:

50

Remarque: pour les utilisateurs de Bootstrap 4+, veuillez considérer la solution de Christophe (Bootstrap 4 a introduit flexbox, qui fournit une solution plus élégante uniquement en CSS). Ce qui suit fonctionnera pour les versions antérieures de Bootstrap ...


Voir http://jsfiddle.net/jhfrench/bAHfj/ pour une solution fonctionnelle.

//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())
});

Du coté positif:

  • dans l'esprit des classes d'assistance existantes de Bootstrap , j'ai nommé la classe pull-down.
  • seul l'élément qui est «abattu» doit être classé, donc ...
  • ... il est réutilisable pour différents types d'éléments (div, span, section, p, etc.)
  • il est assez bien pris en charge (tous les principaux navigateurs prennent en charge margin-top)

Maintenant les mauvaises nouvelles:

  • il nécessite jQuery
  • ce n'est pas, tel qu'il est écrit, réactif (désolé)
Jeromy français
la source
3
pour la réactivité, peut-être accrocher la fenêtre. stackoverflow.com/a/2969091/244811
Scott Weaver
22
N'utilisez pas de solution jQuery pour quelque chose qui pourrait être une solution CSS. Il existe de nombreuses raisons d'éviter la manipulation du DOM à des fins de style.
Archonic
1
@Archonic: quelle est cette solution uniquement CSS? Je le préférerais également à une solution dépendante de JS. Gardez simplement à l'esprit la stipulation d'OP: "une solution où je n'aurais pas à spécifier la hauteur absolue de mes divs serait préférée"
Jeromy French
1
@cfx Publié une solution css uniquement avec un violon qui ne nécessite pas de hauteurs absolues.
Archonic
1
D'autre part, ma solution permet à l'utilisateur d'aligner en bas des éléments individuels (donnant un comportement similaire à Bootstrap .pull-leftet .pull-right), sans affecter les frères et sœurs. Cela peut-il être fait avec une solution CSS uniquement?
Jeromy French
68

Ceci est une solution mise à jour pour Bootstrap 3 (devrait fonctionner pour les anciennes versions) qui utilise uniquement CSS / LESS:

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

Vous définissez la taille de la police sur 0 sur la ligne (sinon vous vous retrouverez avec un espace embêtant entre les colonnes), puis supprimez les flottants de colonne, définissez l'affichage sur inline-block, redéfinissez leur taille de police, puis vertical-alignpouvez être défini sur tout ce dont tu as besoin.

Aucun jQuery requis.

cfx
la source
Je veux le garder au milieu. Cependant, dans votre jsfiddle, lorsque j'ai essayé "vertical-allign: middle", cela n'a pas fonctionné. Des pensées?
joy
Essayez de régler les deux divsur vertical-align: middle;.
cfx
6
C'est la seule réponse acceptable! @ Lukas ignorera les largeurs sur les colonnes qui ne remplissent pas une ligne. Et la manipulation DOM pour le style ... SMH.
Archonic
Votre CSS est séparé de la ligne (en particulier, .myrow) ... cela ne signifie-t-il pas que vous ne pouvez pas avoir une colonne alignée en haut, une colonne alignée en bas et une troisième colonne alignée en haut?
Jeromy French
Merci ! Fonctionne bien avec Bootstrap 4.
Elie Teyssedou
33

Vous pouvez utiliser flex:

@media (min-width: 768px) {
  .row-fluid {
    display: flex;
    align-items: flex-end;
  }
}
Christophe
la source
L'utilisation de felx est très agréable et simple à mon avis et j'avais un autre avantage en utilisant "align-items: baseline" qui était super avec des polices différentes dans les différents éléments à aligner.
Alessandro Dentella
Excellente suggestion d'utiliser flex. Simple, direct et utilise Bootstrap pour résoudre un problème Bootstrap.
CheddarMonkey
1
Réponse brillante et fonctionne parfaitement avec bootstrap sans javascript / jquery nécessaire.
Filth
1
Ouais, ajoutez ceci à une ligne d'amorçage régulière et bam, cela fonctionne. Belle. Comment une solution jquery non réactive est devenue la meilleure réponse? Nous ne saurons jamais.
Levi Fuller
@LeviFuller Je suppose que cette solution ne prend en charge qu'un seul point d'arrêt
clamchoda
27

Vous devez ajouter du style pour span6, smthg comme ça:

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

et voici votre violon: http://jsfiddle.net/sgB3T/

Lukas
la source
4
Je créerais une classe css spécifique au lieu de la définir sur span6, mais la stratégie table-cellule fonctionne bien! J'ai également dû définir "display: table-row" sur le div contenant pour avoir des largeurs correctes.
Meta-Knight le
3
Pour Bootstrap 3, j'ai ajouté cette règle: .row.align-bottom> [class ^ = col] {display: table-cell; alignement vertical: bas; float: aucun; } appliquer align-bottom à la ligne & lt; div class = "row align-bottom" & gt;
Martin
@Martin, votre règle fonctionne très bien lorsque vous définissez également .align-bottom {display: table-row;}, cependant, l'alignement des lignes est désactivé car les lignes du tableau ne respectent pas les valeurs bootstrap margin-left et margin-right: -15px ......pensées?
Alex White
@AlexWhite - Mettez padding-left: 0et padding-right: 0sur tous les cols de cette ligne.
AnalogWeapon
1
Cela ignorera les largeurs de colonne lorsque les colonnes ne remplissent pas la largeur d'une ligne. Lors de l'utilisation de décalages par exemple.
Archonic
14

Voici également une directive angularjs pour implémenter cette fonctionnalité

    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
la source
7

Réglez simplement le parent sur display:flex;et l'enfant sur margin-top:auto. Cela placera le contenu enfant au bas de l'élément parent, en supposant que l'élément parent a une hauteur supérieure à l'élément enfant.

Il n'est pas nécessaire d'essayer de calculer une valeur margin-toplorsque vous avez une hauteur sur votre élément parent ou un autre élément supérieur à votre élément enfant d'intérêt dans votre élément parent.

sissypants
la source
Cela devrait être la réponse acceptée: c'est court, simple et fonctionne dans n'importe quel navigateur prenant en charge flex. Le seul inconvénient est qu'il rompt la réactivité.
tbm
4

Sur la base des autres réponses, voici une version encore plus réactive. J'ai apporté des modifications à la version d'Ivan pour prendre en charge les fenêtres <768px de large et pour mieux prendre en charge les redimensionnements de fenêtres lents.

!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
la source
merci pour ce raffinement, je viens de le prendre pour un projet en cours et ça marche bien.
vendredi
1
Pourquoi mettre margin-topà 0, puis le remettre à la nouvelle valeur? Aussi, pourquoi faire ces choses en deux each()«boucles»?
Jeromy French
4

Ceci est basé sur la solution de cfx, mais plutôt que de définir la taille de la police à zéro dans le conteneur parent pour supprimer les espaces inter-colonnes ajoutés à cause de l'affichage: bloc en ligne et devoir les réinitialiser, j'ai simplement ajouté

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

à la colonne divs pour compenser.

Kirtlander
la source
0

Eh bien, je ne l' ai pas comme l' une de ces réponses, ma solution du même problème était d'ajouter ceci: <div>&nbsp;</div>. Donc, dans votre schéma, cela ressemblerait à ceci (plus ou moins), aucun changement de style n'était nécessaire dans mon cas:

-row-fluid-------------------------------------
+-span6----------+ +----span6----------+
|                | | +---div---+       |
| content        | | | & nbsp; |       |
| that           | | +---------+       |
| is tall        | | +-----div--------+|   
|                | | |short content   ||
|                | | +----------------+|
+----------------+ +-------------------+
-----------------------------------------------
jan b
la source
4
Comment savoir le nombre de &nbsp;à ajouter si la longueur de la cellule de gauche est inconnue?
Gqqnbig
-2
.align-bottom {
    position: absolute;
    bottom: 10px;
    right: 10px;
}
Douglas Ribeiro
la source
1
vous devriez essayer d'ajouter des informations à votre réponse en expliquant pourquoi elle répond à la question OP
MLavoie