如何在Bootstrap流式布局中将网格元素底部对齐

126

我有一个使用Twitter的Bootstrap的流体布局,其中有一行有两列。第一列有很多内容,我希望将其正常填充。第二列只有一个按钮和一些文本,我希望相对于第一列中的单元格底部对齐。

这是我的代码:

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

这是我想要的:

-row-fluid-------------------------------------
+-span6----------+
|                |
| content        |
| that           | 
| is tall        | +-span6----------+    
|                | |short content   |
+----------------+ +----------------+
-----------------------------------------------
我看过一些解决方案,它们使第一个“span”高度绝对,并将第二个“span”相对于它定位,但是我更希望不必指定我的div的绝对高度来实现效果。我也可以彻底重新考虑如何实现相同的效果。我并没有固守这种脚手架的使用,只是它对我来说似乎最有意义。 此布局示例的代码: http://jsfiddle.net/ryansturmer/A7buv/3/

你能不能不要给 .rightspan 添加大约 200px 的 margin-top? - Richlewis
这是一个 CSS-only 的快捷方式,用于回答以下问题:https://dev59.com/MmYr5IYBdhLWcg3wOX66#14223553 - Adam
请提供页面内容,以便我可以翻译它。 - ToolmakerSteve
10个回答

69

这是一个更新的Bootstrap 3解决方案(尽管适用于旧版本),仅使用CSS/LESS:

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

你可以在行上将字体大小设置为0(否则,您将在列之间留下麻烦的空格),然后移除列浮动,将显示设置为inline-block,重新设置它们的字体大小,然后vertical-align可以设置为任何您需要的值。

无需jQuery。


我想让它保持在中间。然而在你的jsfiddle中,当我尝试使用“vertical-allign:middle”时它不起作用。你有什么想法吗? - joy
尝试将两个 div 都设置为 vertical-align: middle; - cfx
6
这是唯一可接受的答案!@Lukas会忽略未填满行的列宽。DOM操作用于样式... 摇头。 - Archonic
你的CSS是基于行(具体来说是.myrow)的...这不意味着你不能让一列顶部对齐,另一列底部对齐,还有第三列顶部对齐吗? - Jeromy French
如果您想要将其中一列设置为vertical-align:middle,而另一列设置在顶部或底部,则此方法无法实现。 - MarcGuay
显示剩余4条评论

49
请注意:对于使用Bootstrap 4 +的用户,请考虑Christophe的解决方案(Bootstrap 4引入了弹性盒子,提供了更优雅的仅使用CSS的解决方案)。以下内容适用于Bootstrap的早期版本...
请参见http://jsfiddle.net/jhfrench/bAHfj/以获取可行的解决方案。
//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())
});

优点:

  • 为了与Bootstrap现有的辅助类相呼应,我将该类命名为pull-down
  • 只需对要“下拉”的元素进行分类即可,因此...
  • ...它可重复使用于不同的元素类型(div、span、section、p等)
  • 它受到支持程度相当高(所有主要浏览器都支持margin-top)

现在是坏消息:

  • 它需要jQuery
  • 按原样编写时,它不具备响应式布局(抱歉)

3
为了实现响应性,也许可以挂接到 window.resize 事件上?https://dev59.com/qHRB5IYBdhLWcg3wgXhV#2969091 - Scott Weaver
25
不要在可以用CSS解决的情况下使用jQuery解决方案。有很多理由避免使用DOM操作来进行样式设计。 - Archonic
1
@Archonic:那个只使用CSS的解决方案是什么?我更喜欢它而不是依赖JS的解决方案。只需记住OP的规定:“最好是一种不必指定div绝对高度的解决方案”。 - Jeromy French
1
@cfx发布了一种仅使用CSS的解决方案,并提供了一个示例,不需要绝对高度。 - Archonic
1
另一方面,我的解决方案允许用户底部对齐单独的元素(类似于Bootstrap的.pull-left.pull-right的行为),而不影响同级元素。是否可以使用仅限CSS的解决方案来实现这一点? - Jeromy French
1
感谢您提供的解决方案。将“margin-top”更改为“padding-top”,以使其适用于粘性页脚等。 - Sverrir Sigmundarson

36

您可以使用flex:

@media (min-width: 768px) {
  .row-fluid {
    display: flex;
    align-items: flex-end;
  }
}

在我看来,使用flex非常好用和直观。而且,使用"align-items: baseline"还有一个优点,可以很好地对齐不同项目中的不同字体。 - Alessandro Dentella
使用flex的建议非常好。简单、直接,并且使用Bootstrap解决了一个Bootstrap问题。 - CheddarMonkey
1
非常棒的答案,与Bootstrap完美配合,无需JavaScript / jQuery。 - Filth
1
是的,在常规的 Bootstrap 行中添加这个,完美运行。太棒了。一个非响应式的 jQuery 解决方案如何成为最佳回答?我们永远不会知道。 - Levi Fuller
@LeviFuller 我猜是因为这个解决方案只支持一个断点。 - clamchoda
除了使用 d-flex 外,我还在我的 col 中添加了 align-items-end,并且我的按钮与网格底部对齐。这很有用,因为我还有另外两列带标签。之前,按钮在顶部并且与输入框没有正确对齐。 - Robert Saylor

27

您需要为 span6 添加一些样式,例如:

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

这是你的 fiddle: http://jsfiddle.net/sgB3T/


4
我会创建一个特定的CSS类,而不是将其设置为span6,但“table-cell”策略也很有效!我还需要将包含div的"display"属性设置为"table-row",以获得正确的宽度。 - Meta-Knight
3
对于Bootstrap 3,我添加了以下规则:.row.align-bottom > [class^=col]{ display: table-cell; vertical-align: bottom; float: none; }将align-bottom应用于行 <div class="row align-bottom">。 - Martin
@Martin,当您设置.align-bottom { display: table-row;}时,您的规则可以正常工作,但是行对齐存在问题,因为表格行不遵循引导程序的margin-left和margin-right:-15px……您有什么想法? - Alex White
@AlexWhite - 在该行的所有列上放置 padding-left: 0padding-right: 0 - AnalogWeapon
1
当列不填充行宽度时,这将忽略列宽度。例如,在使用偏移量时。 - Archonic

14

这里还有一个AngularJS指令,可用于实现此功能。

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

7
只需要将父元素设置为display:flex;,子元素设置为margin-top:auto。这将使子元素内容位于父元素底部,假设父元素的高度大于子元素。
当父元素具有比子元素更大的高度或另一个元素时,没有必要尝试计算margin-top的值。

这应该是被接受的答案:它很简短、简单,并且适用于支持 flex 的任何浏览器。唯一的缺点是它会破坏响应性。 - tbm

5
这是基于cfx的解决方案,但是与其在父容器中将字体大小设置为零以消除由于display: inline-block而添加的列间距并且必须重置它们,我只需简单地添加。

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

将列div进行补偿。


4
基于其他回答,在这里提供更加响应式的版本。我对Ivan的版本进行了更改,以支持视口宽度小于768像素,并更好地支持缓慢的窗口调整大小。
!function ($) { //ensure $ always references jQuery
    $(function () { //when dom has finished loading
        //make top text appear aligned to bottom: https://dev59.com/MmYr5IYBdhLWcg3wOX66
        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);

谢谢您的改进,我刚刚在一个当前的项目中使用它,效果很好。 - sifriday
1
为什么要将 margin-top 设置为 0,然后再设置为新值?另外,为什么要在两个 each() 循环中执行这些操作? - Jeromy French

0

嗯,我不喜欢那些答案,我解决同样的问题的方法是添加这个:<div>&nbsp;</div>。所以在你的方案中,它看起来像这样(或多或少),在我的情况下不需要进行样式更改:

-row-fluid-------------------------------------
+-span6----------+ +----span6----------+
|                | | +---div---+       |
| content        | | | & nbsp; |       |
| that           | | +---------+       |
| is tall        | | +-----div--------+|   
|                | | |short content   ||
|                | | +----------------+|
+----------------+ +-------------------+
-----------------------------------------------

4
如果左侧单元格的长度未知,你如何确定要添加多少个 &nbsp; 呢? - Gqqnbig

-3
.align-bottom {
    position: absolute;
    bottom: 10px;
    right: 10px;
}

2
你应该尝试在回答中添加一些信息,解释为什么它回答了OP的问题。 - MLavoie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接