Расширение проблемы вертикального пространства с плавающими элементами - PullRequest
5 голосов
/ 11 ноября 2011

У меня есть макет, который требует, чтобы список элементов был организован в два вертикальных столбца. Элементы находятся в одном списке <div> с, разметка также переназначается для мобильных устройств, поэтому я не хочу изменять структуру.

Проблема, с которой я столкнулся, заключается в том, что у каждого элемента есть расширяющаяся область контента, которую пользователь может переключать, и когда этот контент расширяется, вертикальное пространство для этого столбца должно расширяться вниз, а другой столбец остается фиксированным.

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

Вот ссылка на пример функциональности, как у меня сейчас, а ниже скриншот того, каким должно быть желаемое поведение.

[screenshot]

Можно ли стилизовать это для поддержки требуемого поведения? Или мне придется изменить структуру предметов, чтобы заставить это работать? Заранее спасибо за помощь!

Ответы [ 6 ]

3 голосов
/ 15 ноября 2011

Ваша предпосылка ошибочна. Структура документа течет слева направо, сверху вниз. Вам нужно будет внести некоторые изменения в структуру ... Проще всего было бы добавить два контейнера для левого столбца и правого столбца. В противном случае вас ждет некоторая хитрая разметка абсолютного позиционирования и немного прикольный jquery, который я могу предложить, только добавив несколько уникальных идентификаторов для каждой из панелей.

Я бы лично добавил идентификаторы, такие как panel1 - panel4 для вашего примера, а затем использовал бы этот javascript (или аналогичный) в качестве отправной точки:

for(var i=1; i<=4; i++) {
        $('#panel'+i).css('left', function(index) {
           if(i%2 == 0) return "120px";
           else return "0px"; 
        });
}

$('.more').click(function(e) {
    e.preventDefault();
    $(this).parent().children('p').toggle();
    var id = $(this).parent().attr("id");
    switch( id ) {
        case 'panel1':
          console.log("panel1 found");
          $('#panel3').css('top', function(index) {
            var buffer = $('#'+id).height() + 20 + "px";
            return buffer;
          });
          break;
        case 'panel2':
          $('#panel4').css('top', function(index) {
            var buffer = $('#'+id).height() + 20 + "px";
            return buffer;
          });
          break;
        default: break;
    }
});

Со значениями по умолчанию в CSS для этих панелей:

#panel1 { top:0px; }
#panel2 { top:0px; }
#panel3 { top:56px; }
#panel4 { top:56px; }

Чем меньше вы настраиваете html, тем больше работы вы будете создавать в javascript.

редактировать

Предлагаемый альтернативный Javascript для устранения необходимости изменять HTML, предполагая два элемента в строке. Поскольку мы знаем, что проблема в ряду ...

var ct = 1
$('#container > div').each(function(index, domEle) {
  $(domEle).attr('id', 'panel'+ct);
  $('#panel'+ct).css({
     'position': 'absolute',
     'left' : function(index, value) {
        if(ct%2 == 0) return "120px";
        else return "0px"; 
     },
     'top' : function(index, value) {
        return (56 * Math.floor(ct/3)) + "px";
     }
  });
  ct++;
});

$('.more').click(function(e) {
    e.preventDefault();
    $(this).parent().children('p').toggle();
    var id = $(this).parent().attr("id");

    switch( id ) {
        case 'panel1':
          $('#panel3').css('top', function(index) {
            var buffer = $('#'+id).height() + 20 + "px";
            return buffer;
          });
          break;
        case 'panel2':
          $('#panel4').css('top', function(index) {
            var buffer = $('#'+id).height() + 20 + "px";
            return buffer;
          });
          break;
        default: break;
    }
});

Теперь в HTML не нужно вносить никаких изменений, хотя вы захотите повторить функцию щелчка, чтобы обработать изменение расположения элементов после щелчка. Я бы упростил жизнь и скрыл все элементы .more, прежде чем развернуть новую коробку, поскольку это означало бы необходимость расчета высот всех вышеперечисленных элементов, но сколько работы вы хотите выполнить, это ваш бизнес.

2 голосов
/ 16 ноября 2011

Вот PURE CSS SOLUTION для четырех панелей (я не знаю, планировали ли вы иметь больше, и у меня пока нет шести [2 широких 3 высоких] работающих - и подозреваю, что это невозможно). Работает в FF и IE8 / 9. Смотрите скрипку: http://jsfiddle.net/bEgwB/203/

Однако , IE8 испытывает ошибку перерисовки, из-за которой панель 3 не перемещается, поэтому ему нужна дополнительная помощь по javascript (добавлена ​​в скрипте выше), а IE7 нуждается в некоторых корректировках полей для правильного позиционирования панели 4 (но делает не иметь проблемы с перерисовкой даже без дополнительной помощи JavaScript). ОБНОВЛЕНИЕ (11-18-11): Вот скрипка для корректировки поля IE7: http://jsfiddle.net/bEgwB/286/

РЕДАКТИРОВАТЬ: предыдущая версия моего CSS имела display вызовов, которые были ненужными.

HTML

<div id="container">
    <div class="panel one">
        Panel 1<br />
        <a class="more" href="#">more</a>
        <p>More Info 1 with some additional content</p>
    </div>
    <div class="panel two">
        Panel 2<br />
        <a class="more" href="#">more</a>
        <p>More Info 2 with some additional content</p>
    </div>
    <div class="panel three">
        Panel 3<br />
        <a class="more" href="#">more</a>
        <p>More Info 3 with some additional content</p>
    </div>
    <div class="panel four">
        Panel 4<br />
        <a class="more" href="#">more</a>
        <p>More Info 4 with some additional content</p>
    </div>
</div>

CSS

a {color:yellow;}
#container {width:0 ; padding: 0 130px;}
.panel {
    background-color:green;
    padding:5px;
    color:#fff;
    width:100px;
}
.panel p {display:none;}

.panel.one {
    float: left;
    margin:10px 0 10px -120px;
}
.panel.two {
    float: right;
    margin: 10px -120px 20px 0;
}
.panel.three {
    float: left;
    clear: left;
    margin:10px 10px 10px -120px;
}
.panel.four {
    clear: right;
    margin: 10px;
}

JAVASCRIPT

$('.more').click(function(e) {
    e.preventDefault();
    $(this).parent().children('p').toggle();
    /* the following fix IE8 */
    $(this).parent().parent().hide();
    $(this).parent().parent().show();
});
1 голос
/ 16 ноября 2011

Может быть, вы можете сделать это column-count свойство, как это:

a {color:yellow;}
#container {
    width:300px;
    -moz-column-count: 2;
        -moz-column-gap: 50%;
        -webkit-column-count: 2;
        -webkit-column-gap: 50%;
        column-count: 2;
        column-gap: 50%;

}
.panel p {display:none;}
.panel {background-color:green;padding:5px;color:#fff;width:100px;margin:10px;}
.alt{
    margin-bottom:90px;
}

Проверить эту скрипку http://jsfiddle.net/bEgwB/87/

ОБНОВЛЕНО

Проверьте это:

http://jsfiddle.net/bEgwB/276/

1 голос
/ 11 ноября 2011

Вам нужно добавить еще два элемента div - левый и правый столбец и разделить элементы между этими двумя элементами.Это способ сделать их независимыми, вот для этого jsfiddle .

HTML

<div id="container">
    <div class="left">
        <div class="panel">
            Panel 1<br />
            <a class="more" href="#">more</a>
            <p>More Info 1 with some additional content</p>
        </div>
        <div class="panel alt">
            Panel 2<br />
            <a class="more" href="#">more</a>
            <p>More Info 2 with some additional content</p>
        </div>
    </div>
    <div class="right">
        <div class="panel">
            Panel 3<br />
            <a class="more" href="#">more</a>
            <p>More Info 3 with some additional content</p>
        </div>
        <div class="panel alt">
            Panel 4<br />
            <a class="more" href="#">more</a>
            <p>More Info 4 with some additional content</p>
        </div>
    </div>
</div>

CSS

a {color:yellow;}
#container {width:300px; position:relative;}
.panel {background-color:green;padding:5px;color:#fff;width:100px;margin:10px;}
.panel p {display:none;}
.left {
    width: 50%;
    float: left;
}
.right {
    width: 50%;
    float: right;
}
0 голосов
/ 17 ноября 2011

Если я правильно понимаю, что вы хотите, это что-то вроде этого http://jsfiddle.net/bEgwB/275/

Вам нужно использовать оба свойства CSS display: inline-block и float:оставил для реализации эффекта, как на вашем JPG.Если моя разметка верна и выглядит так, как ожидалось, я могу помочь вам с javascript, если сейчас все не в порядке

Удачи.

0 голосов
/ 14 ноября 2011

Есть решение для укладки волос. Чтобы связать два столбца вместе, им необходим дополнительный уровень привязки, вы можете сделать это, добавив атрибут стиля к «контейнеру», «отображению: таблице» и к панелям с «отображением: таблицы-ячейки».

Это будет поддерживать высоту в синхронизации. И класс «контейнер», и класс «панель» должны иметь объявленную ширину, иначе они действительно портят макет. IE слабо поддерживает эти атрибуты, поэтому могут возникнуть проблемы с решением.

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