计算列宽

时间:2011-03-03 23:14:34

标签: php css width

我正在研究一个小小的cms来提高我的PHP知识,现在我正处于一个我不知道如何继续的地步。

我可以将容器设置为总可用宽度的百分比,例如1/3(33%),3/4(75%)等,但我也想检查边距,填充和边界。

假设Container的宽度为600像素,内容元素的边距为20px,没有边框,没有填充。有2个元素:75%和25%宽,像素宽度应为435像素和145像素。

我无法想出一个正确的公式。

/编辑: 看起来比我想象的更难。 “新”问题是我想要启用那些列宽的所有可想象的组合。 如果下一列不适合行开始新行,则下一步是添加清算DIV。

为了让它更有趣: 我不知道计算宽度时连续排列的元素数量。我也不想迭代结果集只是为了确定在休息之后仍然适合开始的项目数量。

//我做到了。好极了。 这是jsfiddle版本:http://jsfiddle.net/UNvyd/ 我将使用PHP版本,但概念将保持不变。

有两件事我不满意:

  • 我需要计算每个元素(gi_elCount
  • 值0.8是硬编码的,因为最小的列是1/5。如果所有行元素的当前宽度超过4/5,我将需要clear div。

我希望将来可以帮助其他人。

///修复:http://jsfiddle.net/UNvyd/现在这应该适用于各种组合

3 个答案:

答案 0 :(得分:1)

获得正确的基础:

  

(容器宽度[600] - (margin-right [20] x(最小公倍数[4] -1)))/最小公倍数[4] =所需宽度为25%( 135

所以对于你的3/4 1/4案例:(600 - (20 x(4 - 1)))/ 4 = 135

对于2/3 1/3案例:(600 - (20 x(3 - 1)))/ 3 = 186.66

自由组合

这是一个数学问题,因为你需要有核心最小公倍数来通过上面的公式来计算正确的基础

示例:1/4& 1/3:4和3的最小公倍数:12,4/12 = 1/3和3/12 = 1/4。你仍然有5/12分裂。

示例2:1/3和2/5:5和3的最小公倍数:15,5 / 15 = 1/3 6/15 = 2/5你仍然有4/15分裂。

答案 1 :(得分:0)

单独使用CSS无法做到这一点。你可以使用jQuery来做到这一点。假设每个元素的右边距为20px,我们减去该边距并计算每个元素的25%和75%宽度。

var cw = $('#container').width();
$('#element1').css({'width':parseInt((cw * 0.25)-20)+"px"});
$('#element2').css({'width':parseInt((cw * 0.75)-20)+"px"});

检查http://jsfiddle.net/uV62M/

处的工作示例

答案 2 :(得分:0)

这是我的解决方案。 首先,我们需要找到具有给定分母的smalles列的宽度。那将是1 / 2,1 / 3之一。因此,我们需要从宽度中减去可能的边距量(即:(分母减去1)乘以边距)并将其除以分母。

这会给我们:Width - Margin * (Denominator - 1)) / Denominator

现在我们有了更小的列宽。如果我们想要获得更大列的宽度,我们必须将此数量乘以Numerator。

(Width - Margin * (Denominator - 1)) / Denominator) * Numerator

剩下的问题是:如果你有3/4列,它必须是计算的宽度加上边距的两倍。要实现这一点,我们将添加边距乘以(分子减1)

(Numerator - 1) * Margin

结果公式:

((Width - Margin * (Denominator - 1)) / Denominator) * Numerator + ((Numerator - 1) * Margin)

计算宽度后,如果当前行的总宽度超过可用宽度的80%(因为我们允许1/5的较小列)的清除元素,我们需要在当前列之后应用清除元素如果总宽度高于可用宽度,则在当前col之前。

您可以在此处找到一个有效的示例:http://jsfiddle.net/UNvyd/

HTML:

<div id="wrapper" data-smallesColumn="5">
    <div class="column" data-width="1/2"></div>
    <div class="column" data-width="1/2"></div>
    <div class="column" data-width="1/3"></div>
    <div class="column" data-width="1/3"></div>
    <div class="column" data-width="1/3"></div>
    <div class="column" data-width="1/4"></div>
    <div class="column" data-width="1/4"></div>
    <div class="column" data-width="2/4"></div>
    <div class="column" data-width="1/4"></div>
    <div class="column" data-width="1/5"></div>
    <div class="column" data-width="1/5"></div>
    <div class="column" data-width="1/5"></div>
    <div class="column" data-width="1/5"></div>
    <div class="column" data-width="1/5"></div>
    <div class="column" data-width="1/2"></div>
    <div class="column" data-width="1/4"></div>
    <div class="column" data-width="1/4"></div>
    <div class="column" data-width="1/3"></div>
    <div class="column" data-width="2/3"></div>
    <div class="column" data-width="3/4"></div>
    <div class="column" data-width="1/4"></div>
    <div class="column" data-width="2/5"></div>
    <div class="column" data-width="3/5"></div>
    <div class="column" data-width="2/5"></div>
    <div class="column" data-width="1/5"></div>
    <div class="column" data-width="2/5"></div>
    <div class="column" data-width="1/2"></div>
    <div class="column" data-width="1/3"></div>
    <div class="column" data-width="1/4"></div>
    <div class="column" data-width="4/5"></div>
    <div class="clear"></div>
</div>

CSS:

#wrapper {
    width:423px;
    background-color:red;
}
.column {
    height:20px;
    float:left;
    margin-right:18px;
    background-color:yellow;
    overflow-x:hidden;
}
.clear {
    clear:both;
    height:2px;
    background-color:green;
}

使用Javascript:

$(document).ready(function() {
    var gi_wrapperWidth = $('#wrapper').innerWidth();
    var gi_columnMargin = parseInt($('.column').css('margin-right'));
    var gi_maxWidth = (gi_wrapperWidth - 4 * gi_columnMargin) * 0.8 + gi_columnMargin;
    var gi_elCount = 0;
    var gi_widthCount = 0;

    $('.column').each(function(){
       gi_elCount++;
       var lo_that = $(this);

       //Get the intended width
       var ls_dataWidth = lo_that.data('width');

       //Split x/y into x and y
       var la_widthArray = ls_dataWidth.split('/');
       var li_numerator = la_widthArray[0];
       var li_denominator = la_widthArray[1];

       //Do some math!
       //((Width - Margin * (Denominator - 1)) / Denominator) * Numerator + ((Numerator - 1) * Margin)
       var li_elWidth = ((gi_wrapperWidth - gi_columnMargin * (li_denominator - 1)) / li_denominator) * li_numerator + ((li_numerator - 1) * gi_columnMargin);

        li_elWidth = parseFloat(li_elWidth.toFixed(2));

       //Set the width and show it inside the element
       lo_that.css('width', li_elWidth+'px').html(li_elWidth+'px');

       gi_widthCount += li_elWidth;
       if (Math.floor(gi_widthCount) > (gi_wrapperWidth - ((gi_elCount-1) * gi_columnMargin))) {
           gi_widthCount = li_elWidth;
           gi_elCount = 1;
           lo_that.before('<div class="clear"></div>');
       }

       else if (Math.floor(gi_widthCount) > gi_maxWidth) {
           lo_that.css('margin-right', '0px');
           gi_widthCount = 0;
           gi_elCount = 0;
           lo_that.after('<div class="clear"></div>');
       }

    });
});

公式可能需要改进,但我对结果很满意,所以我会坚持这一点。

我建议不要将它用作js而是php /服务器端解决方案。