在BxSlider轮播中垂直居中对齐div

10

我正在使用bxslider脚本构建一个旋转木马。一切都很好,但我在尝试垂直居中幻灯片时遇到了问题,因为它们的高度不相同。我尝试过许多对齐技术,但所有方法似乎在bxslider运行时失败。这里是一个jsfiddle示例

目前在示例中,当旋转木马没有设置时,我已经设置了一个非常简单的CSS规则:

.bxslider-inner {
   vertical-align: middle;
    display: inline-block;
} 

但是,正如您在 jsfiddle 中看到的那样,当轮播图处于活动状态时,垂直对齐就不再起作用。

我开始怀疑我可能必须更改脚本的核心代码才能实现这一点。


尝试一下这个SO问题的答案:CSS-在浮动的div中垂直居中图像 - darthmaim
我已经添加了一个新答案,希望它能够满足您的需求。祝您好运! - user1467267
8个回答

16

按照以下方式更新您的CSS。关键在于不要将元素 float,因为您始终使其成为inline-block

.bxslider-inner {
    vertical-align: middle;
    display: inline-block;
    float: none !important;
}

还有一件事...为了与您的示例匹配,在完成float: none !important;后,请将slideMargin:20更改为slideMargin:10

Fiddle: http://jsfiddle.net/sSqAx/9/


不喜欢使用!important,但是这是一个很好的清洁修复。+1 - user1467267
当循环浏览走马灯时,我会看到某些元素之间的空间在某些时间内坍塌和重新出现。它在所有浏览器中都发生。这是由于inline-block元素之间存在大约4像素的隐式空格所致。此解决方案可能需要编辑HTML以删除.bxslider内元素标签之间的任何空格(如果可以),并重新调整slideMargin的值。【更新演示】(http://jsfiddle.net/Matt_Coughlin/z6Fmj/) - Matt Coughlin
实际上不是这样的...它正在正确地渲染,并且添加了比需要更多的空间,因为在JS之前,总宽度增加了100px,而在硬编码的HTML中,真实宽度为90px。因此,您需要调整JS中的宽度或边距,使其总共等于90px,而不是100px。 - doitlikejustin
哇,好棒的解决方案!非常容易实现,而且在我实际的代码实现中也起作用。我还需要更好地检查一下幻灯片边距,填充和其他一些内容,但垂直对齐效果良好!非常感谢这个! - CMoreira
1
"float: none" ... 哇,这个救了我的命。我为这个问题苦恼了整整一天... :-P。非常感谢! - user1688793
我将.bxslider-inner更改为.bxslider li后,它就可以工作了。 - Avatar

3

CSS表格

通常情况下,只要不需要支持IE7或更早期的版本,我建议添加 display: table-cell;(类似于@darthmaim在上面链接的问题):

.bxslider-inner {
    display: table-cell;
    vertical-align: middle;
}
...
<div class="bxslider-inner"><div>Content goes here</div></div>

然而,display: table-cell; 在浮动元素上不起作用(在IE8/9/10、Firefox、Safari、Chrome和Opera中测试过),如此JSFiddle Demo所示。在@darthmaim链接的问题中,元素的父级是浮动的;这样可以正常工作。但是,在这里子元素是浮动的,这是不起作用的。

解决方法

如果编辑HTML源代码是一种选择,你可以在每个.bxslider-inner内添加一个div包装器,以便将display: table-cell;的使用移动到非浮动元素上:更新后的演示

.bxslider-inner > div {
    display: table-cell;
    vertical-align: middle;
    height: 90px;
}
...
<div class="bxslider-inner"><div><div>Content goes here</div></div></div>

这里假设旋转木马容器的高度为90px。如果支持变量高度的容器(根据最高旋转木马元素的高度而变化),则需要进行额外的工作。 JavaScript 如果无法编辑HTML源代码,则可以使用JavaScript或jQuery的两个解决方案:
  1. 动态注入上面描述的div包装器,而不是将它们添加到静态HTML中:更新后的演示
  2. 根据计算出的每个元素的高度,动态添加适当数量的顶部间距。

你好,马特!非常感谢你的建议。在我的情况下,编辑HTML是一个选项。+1我正在尝试doitlikejustin的解决方案,因为它更容易实现,并且也很好用。但无论如何,还是感谢你的建议! - CMoreira

1
我们可以通过在CSS中添加"vertical-align:middle"并给外部div设置固定高度来使一个div垂直居中。或者,我们也可以使用"margin-top"或在CSS中使用"top"属性进行设置。

0
更新答案: 由于上面的回答使用了display: inline-block,我发现每个项目都会添加额外的4个像素,因此如果你的轮播中有4个项目,则会被推到右侧16个像素,因为.bx-wrapper的宽度是计算出来的。

要防止这种情况发生,可以在父级 div 上使用 flexbox:

.bxslider {
  display: flex;
  align-items: center;
}
.bxslider > div {
  float: none!important;
}

这样做不会为每个项目添加额外的4像素间距,而且会很好地适应。


0

只有使用flexbox才能实现,请查看下面的代码

  .bxslider-inner {
    vertical-align: middle;
    display: inline-block;
    height: auto;
  }
  .bxslider{
    display: flex;
    align-items: center;
  }

Here is the Snipper

jQuery(document).ready(function(){
    jQuery('.bxslider').bxSlider({
    mode: 'horizontal',
    speed: 500,
    slideMargin:10,
    infiniteLoop: true,
    pager: false,
    controls: true,
    slideWidth: 80,
    minSlides: 1,
    maxSlides: 5,
    moveSlides: 1       });
    });
.bxslider-inner {
   vertical-align: middle;
    display: inline-block;
    height: auto;
}
.bxslider{
  display: flex;
    align-items: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/bxslider/4.2.12/jquery.bxslider.min.js"></script>
<link href="https://cdn.jsdelivr.net/bxslider/4.2.12/jquery.bxslider.css" rel="stylesheet"/>
<b>Without BxSlider - How I want the slides to display</b>

<div class="bxslider-2">
  <div class="bxslider-inner"><div style="width:80px; height:80px; background:#CCC; padding:5px;"></div></div>
 <div class="bxslider-inner"><div style="width:80px; height:80px; background:#F5F5F5; padding:5px;"></div></div>
<div class="bxslider-inner"><div style="width:80px; height:10px; background:#6699cc; padding:5px;"></div></div>
    <div class="bxslider-inner"><div style="width:80px; height:80px; background:#F5F5F5; padding:5px;"></div></div>
</div>



<br />
<b>With BxSlider - Blue slider doesn't align in center (vertical)</b>
<br /><br />

<div class="bxslider">
  <div class="bxslider-inner"><div style="width:80px; height:80px; background:#CCC; padding:5px;"></div></div>
 <div class="bxslider-inner"><div style="width:80px; height:80px; background:#F5F5F5; padding:5px;"></div></div>
<div class="bxslider-inner"><div style="width:80px; height:10px; background:#6699cc; padding:5px;"></div></div>
    <div class="bxslider-inner"><div style="width:80px; height:80px; background:#F5F5F5; padding:5px;"></div></div>
</div>

请查看这个 JsFiddle


0

您可以通过添加top:30px来实现。

这里vertical-align无法起作用,因为在bxslider-inner div中它会添加额外的style,所以它不适用于此处的vertical-align。因此,在这种情况下,您可以使用top来调整该element

Fiddle http://jsfiddle.net/sSqAx/3/


你好Rohan!感谢你的输入!这个解决方案在这种情况下是有效的,但它不是最佳解决方案,因为它只适用于该元素。问题在于我将动态加载具有不同高度的图像,因此这个解决方案行不通。我猜我需要在核心文件中搜索脚本添加附加样式并在那里编辑脚本? - CMoreira

0

设置slideMargin:0和slideWidth:100的值

它有效。


你好!感谢您的输入。我尝试了这些值,但是没有任何变化。它所做的是将幻灯片之间的间距设置为相同,但它并没有解决较小div的垂直对齐问题。或者我漏掉了什么? - CMoreira

0

这应该可以解决你的问题:

JSfiddle

还有一个高度不同的链接:JSfiddle

HTML

<div class="bxslider">
    <div class="bxslider-inner"><div style="width:80px; height:80px; background:#CCC; padding:5px;"></div></div>
    <div class="bxslider-inner"><div style="width:80px; height:80px; background:#F5F5F5; padding:5px;"></div></div>
    <div class="bxslider-inner"><div style="width:80px; height:10px; background:#6699cc; padding:5px;"></div></div>
    <div class="bxslider-inner"><div style="width:80px; height:80px; background:#F5F5F5; padding:5px;"></div></div>
</div>

CSS

body {
    background: orange;
    margin-top: 50px;
}

.bxslider-inner {
   vertical-align: middle;
    display: inline-block;
    height: 80px;
}

JavaScript

'use strict';

jQuery(document).ready(function(){
    jQuery('.bxslider').bxSlider({
        mode: 'horizontal',
        speed: 500,
        slideMargin:20,
        infiniteLoop: true,
        pager: false,
        controls: true,
        slideWidth: 80,
        minSlides: 1,
        maxSlides: 5,
        moveSlides: 1
        }
    });

    // Initial
    $('.bxslider-inner').each(function(){
        var height_parent = $(this).css('height').replace('px', '') * 1;
        var height_child = $('div', $(this)).css('height').replace('px', '') * 1;
        var padding_top_child = $('div', $(this)).css('padding-top').replace('px', '') * 1;
        var padding_bottom_child = $('div', $(this)).css('padding-bottom').replace('px', '') * 1;
        var top_margin = (height_parent - (height_child + padding_top_child + padding_bottom_child)) / 2;

        $(this).html('<div style="height: ' + top_margin + 'px; width: 100%;"></div>' + $(this).html());
    });
});

请记住,计算出的中间值非常依赖于其他高度变量,如填充、边距和边框。如果您添加了这样的样式,请记住需要将其添加到计算中。另一个选项是使用box-sizing: border-box;,这样所有这些都会折叠到div的内部。

bxslider-inner必须有一个高度,否则您需要以某种方式获取计算出的DOM高度以避免它。如果您真的想要这样,请留言,我会研究一下。

祝你好运!

更新

  • JSfiddle已更新,现在不应该陷入循环中。
  • 测试了过高的高度,代码似乎不会崩溃,但可能会溢出到隐藏
  • 查看http://bxslider.com/options(>回调> onSlideAfter)。如果需要,在每个周期后可以进行修改。在这里,如果需要复杂化,您可以再次修改代码

谢谢您的输入!这个解决方案也可以。不过我会采用doitlikejustin的解决方案,因为它更简单易行。但还是感谢您!+1 - CMoreira

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