Рассчитать ширину столбца - PullRequest
1 голос
/ 04 марта 2011

Я сейчас работаю над крошечным cms, чтобы улучшить свои знания php, и сейчас я нахожусь в точке, где я не знаю, как продолжить.

Я бы мог установить контейнер в процентах от общей доступной ширины, например, 1/3 (33%), 3/4 (75%) и т. Д., Но я также хочу проверить поля, прокладки и бордюры.

Допустим, контейнер имеет ширину 600 пикселей, элементы содержимого имеют правое поле 20 пикселей, без границ и отступов. Имеется 2 элемента: шириной 75% и 25%, ширина пикселя которых должна составлять 435 пикселей и 145 пикселей.

Я просто не могу придумать правильную формулу.

/ Edit: Похоже, это сложнее, чем я думал. «Новая» проблема заключается в том, что я хочу включить все мыслимые сочетания ширины столбцов. Следующим шагом будет добавление очищающего DIV, если следующий столбец не помещается в строке, чтобы начать новую строку.

И чтобы было немного веселее: Я не знаю количество элементов, которые поместятся в строке при расчете ширины. Я также не хочу перебирать набор результатов, просто чтобы определить, сколько элементов все еще поместится, чтобы начать все заново после перерыва.

// Я сделал это. Ура. Вот версия jsfiddle: http://jsfiddle.net/UNvyd/ Я буду использовать версию PHP, но концепция останется прежней.

Есть две вещи, которыми я не очень доволен:

  • Мне нужно подсчитать все элементы (gi_elCount)
  • Значение 0,8 жестко закодировано, поскольку наименьший столбец равен 1/5. Если текущая ширина всех элементов строки больше 4/5, мне понадобится чистый div.

Я надеюсь, что это может помочь кому-то еще в будущем.

/// Исправлено: http://jsfiddle.net/UNvyd/ теперь это действительно должно работать для всех видов комбинаций

Ответы [ 3 ]

1 голос
/ 04 марта 2011

Получение правильной основы:

(Ширина контейнера [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, чтобы разделиться.

0 голосов
/ 09 марта 2011

Вот мое решение.Сначала нам нужно найти ширину столбца наименьших с заданным знаменателем.Это будет 1/2, 1/3 и так один.Для этого нам необходимо вычесть количество возможных полей из ширины (которая равна: (знаменатель минус один), умноженной на маржу ) и разделить ее на знаменатель.

Это даст нам:Width - Margin * (Denominator - 1)) / Denominator.

Теперь у нас есть ширина столбца наименьшая.Если мы хотим получить ширину для большего столбца, мы должны умножить эту сумму на Числитель.

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

Остается проблема: если у вас есть столбец 3/4это должна быть расчетная ширина плюс два раза запас.Чтобы достичь этого, мы добавим поле, умноженное на (числитель минус один)

(Numerator - 1) * Margin

Результирующая формула:

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

После вычисления ширины нам необходимо применить очищающий элемент после текущего столбца, если общая ширина текущей строки превышает 80% доступной ширины (поскольку мы допускаем столбец наименьшего размера 1/5)очищающий элемент перед текущим столбцом, если общая ширина превышает доступную ширину.

Рабочий пример можно найти здесь: 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 / server.

0 голосов
/ 04 марта 2011

Этого нельзя сделать только с помощью 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/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...