【问题标题】:Floating fill-width boxes浮动填充宽度框
【发布时间】:2013-09-04 11:34:36
【问题描述】:

我有一个包含子框的div(或section,或其他块级元素)。

<section>
    <div>Box 1</div>
    <div>Box 2</div>
    <div>Box 3</div>
    <div>Box 4</div>
    <div>Box 5</div>
    <div>Box 6</div>
    <div>Box 7</div>
    <div>Box 8</div>
    <div>Box 9</div>
    <div>Box 10</div>
</section>

每个子框都有一个最小宽度(例如 150 像素)并且它们都向左浮动。因此,如果父容器为 [450, 600) px 宽,则连续 3 个,类似地,如果父容器为 [600, 750) px 宽,则为 4 个,依此类推。

section {
    min-width: 150px;
    font-family: 'Segoe UI', Ubuntu, sans-serif;
}

div {
    min-width: 150px;
    height: 150px;
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;

    float: left;
    margin: 0 3px 3px 0;
    padding: 3px;
    background-color: lightblue;
    border: 1px solid #000;
}

jsFiddle

如果父框在子框宽度的倍数之间,我该如何做到这一点,子框填充父框的宽度。因此,例如,如果父框是 660px 宽,那么每个子框将是 660px/4 或 165px 宽。 我还要提一下,如果父框的宽度发生变化,子框也应该随之改变。

在我的具体情况下,我可以使用媒体查询来执行此操作,因为 幸运的是父框取决于视口宽度,但我正在寻找通用解决方案,因为可能还有其他地方父框是真正可变的。此外,必须将每个案例都放入带有 widthmax-width 的媒体查询中变得乏味。

我的兼容性要求是现代浏览器(IE 10+、Firefox、Chrome、Safari)。我不介意使用一点 JavaScript/jQuery,但它应该在 IE 9 中正常降级。不支持 IE 8,所以这不是问题。

我已经研究过使用 flexbox,但不幸的是 Firefox 目前只支持单行 flexbox,所以当我尝试它时,子 flex 项目会挤压并溢出 flex 容器。

编辑:

我根据 Siddhartha Gupta 在下面的回答开始使用 JavaScript,但是在某些地方似乎存在一个奇怪的错误,即行没有填满整个空间。 (如果没有足够的子元素,所有行都应该 100% 填充,最后一行除外。)

$(window).resize(function () {
    var sectionWidth = $('section').width(),
        childWidth = (sectionWidth / Math.floor(sectionWidth/150)) - 3;

    $('section').children().css({
        'width': childWidth + 'px'
    });
});

【问题讨论】:

    标签: css user-interface css-float fluid-layout


    【解决方案1】:

    试试这个fiddle

    var sectionWidth = $('section').width();
    
    //Lets calculate width of each child
    //Divided parent width with the no of childs you want to show
    //Then subtract 2px from it (fix for border px's)
    //Again subtract 2px from it (fix for padding px's)
    var childWidth = sectionWidth/8 - 2 - 2;
    
    //Lets apply the width to each child
    //Also need to remove min-width
    $('section').children().css({'min-width': 0, 'width': childWidth + 'px'})
    

    【讨论】:

    • 我试过你的小提琴,宽度没有改变。我还尝试将代码包装在 $(window).resize(function() { }); 周围,但它仍然不起作用。我不知道你为什么在整数上使用 parseInt,你能解释一下 4 的用途吗?
    • 嗨,我已经更新了答案并摆弄了 cmets。只需将父级宽度除以您要在一行中显示的子级数。
    • 这打破了我对min-width 的要求,而且我确实在子元素上设置了box-sizing8来自哪里?
    • Well 8 只是一个示例,不表明使用上面的代码您最多可以操纵 8 个孩子。您也可以将 8 替换为 3 以连续显示 3 个孩子。您也可以删除最小宽度并尝试调整小提琴窗口的大小。
    • 这有帮助吗?jsfiddle.net/sid2varun/2f7HP 对我来说,您似乎错过了文档准备就绪事件,就像调整窗口大小一样,您的小提琴效果很好。
    【解决方案2】:

    有一种更简单的方法(基于 S.Gupta 的回答)

    var a;
    function somefunc(){
    var sectionWidth = $('section').width();  
    var minChildWidth = 150; // specify min-width here  
    var k = Math.floor(sectionWidth/minChildWidth);
    if(k!=a){
    k = 100/k;  
    $('section').children().css({'width': k + '%'});
    }
    a=k;
    }
    

    我相信这是一种更好的方法,因为它不会每次都计算和应用宽度。这就是 %-widths 的用途。 如果你不能达到预期的结果,试着从最终的 k 中减去 0.1 或 0.5%。 如果您需要更精确的结果,请为 div 制作一个包装器,并将边框和边距应用于内部容器,为包装器设置宽度。使用适当的盒子尺寸,它应该可以做到这一点。

    那些宁愿不使用 jQuery 的人可以考虑以下:

    JS:

    var a;
    function foo(){
    var s = getElementById('section_id');
    var minW = 150; // desired min. width for inner divs
    var sWidth = s.offsetWidth;
    var k = Math.floor(); 
    k = (k>5)?5:k;
    if(a!=k)
    s.className="m"+k;
    a=k;
    }
    

    CSS:

    .m1 .inner_div {width:100%}
    .m2 .inner_div {width:50%}
    .m3 .inner_div {width:33.3%}
    .m4 .inner_div {width:25%}
    .m5 .inner_div {width:20%}
    ...
    .section {width:100%}
    

    这种方法的局限性是显而易见的(此示例中的最大行数为 5)。但是,它可以在某些情况下应用。想象一下,当用户决定调整窗口大小时,您在一个部分中有 100 多个 div。下面的答案会导致一个循环,尽管所有 div 在调整大小时以像素为单位硬编码元素的宽度数次。我敢打赌这样的动画不够流畅。

    --
    当列数有限时,可以应用没有 jQuery 的解决方案,当内部 div 具有更大的最小宽度时,例如如果您将最小宽度设置为 250 像素,并且所需的最大宽度为 500 像素,则列数不太可能达到 6 或更多(500x5=3000 像素)。

    欢迎评论。

    【讨论】:

      猜你喜欢
      • 2012-06-25
      • 1970-01-01
      • 2012-01-07
      • 1970-01-01
      • 2014-04-26
      • 2012-04-08
      • 1970-01-01
      • 2015-03-15
      相关资源
      最近更新 更多