CSS: две колонки - PullRequest
       52

CSS: две колонки

3 голосов
/ 13 декабря 2008

Я не могу понять, как добиться следующего макета с помощью CSS (возможно, потому что я на самом деле не знаю CSS).

У меня есть такая куча дивов:

<div class="right"> <p>1</p> </div>
<div class="left">  <p>2</p> </div>
<div class="left">  <p>3</p> </div>
<div class="left">  <p>4</p> </div>
<div class="right"> <p>5</p> </div>
<div class="right"> <p>6</p> </div>

(не реальное содержание)

Теперь я хочу, чтобы макет выглядел как два одинаковых столбца div, с «правыми» справа и «левыми» слева, таким образом:

2 1
3 5
4 6

[ Редактировать: в предыдущей версии этого вопроса у меня были текстовые области внутри div, и у всех div были разные имена, такие как «one» и «xyz». ] Я пробовал что-то вроде

div.right { width:50%; float:right; clear:right; }
div.left { width:50%; float:left; clear:left;}

но это не совсем работает: выдает что-то вроде:

2 1
3 
4 5
  6

(без "clear" s он беспечно выдает

2 1
3 4
6 5

что не то, что нужно).

Очевидно, что его можно заставить работать, если элементы div упорядочены по-разному, но я бы не хотел этого делать (поскольку эти элементы div генерируются динамически, если в браузере есть Javascript, и я не хочу менять фактический порядок, который отображается в отсутствие Javascript по семантическим причинам). Можно ли добиться желаемого макета?

[Во всяком случае, я хочу, чтобы он не работал в IE или более старых версиях других браузеров, поэтому, если есть решение, которое работает только в браузерах, соответствующих стандартам, ничего страшного: -)]

Ответы [ 11 ]

3 голосов
/ 13 декабря 2008

В Firefox 3 у меня работает следующее:

div {
  width: 198px;
  border: 1px solid black;
}
div.onediv, div.tendiv, div.xyzdiv { float: right; }
div.twodiv, div.abcdiv, div.pqrdiv { float: left; }
<div style="width: 400px;">
  <div class="onediv"><p>One name</p> <textarea id="one"></textarea></div>
  <div class="twodiv"><p>Two name</p> <textarea id="two"></textarea></div>
  <div class="tendiv"><p>Ten name</p> <textarea id="ten"></textarea></div>
  <div class="abcdiv"><p>Abc name</p> <textarea id="abc"></textarea></div>
  <div class="xyzdiv"><p>Xyz name</p> <textarea id="xyz"></textarea></div>
  <div class="pqrdiv"><p>Pqr name</p> <textarea id="pqr"></textarea></div>
</div>

Просто короткое замечание: ввод div внутри имени вашего класса (то есть abcdiv) немного избыточен и странен. Не вдаваясь в большую диатрибу о правильном использовании класса, я бы оставил это без внимания.

Вы действительно можете упростить свой код, если просто скажете «col1» и «col2». Таким образом, вы можете даже поменять столбцы позже, если хотите:

div {
  width: 198px;
  border: 1px solid black;
}
div.col1 { float: right; }
div.col2 { float: left; }
<div style="width: 400px;">
  <div class="col1"><p>One name</p> <textarea id="one"></textarea></div>
  <div class="col2"><p>Two name</p> <textarea id="two"></textarea></div>
  <div class="col1"><p>Ten name</p> <textarea id="ten"></textarea></div>
  <div class="col2"><p>Abc name</p> <textarea id="abc"></textarea></div>
  <div class="col1"><p>Xyz name</p> <textarea id="xyz"></textarea></div>
  <div class="col2"><p>Pqr name</p> <textarea id="pqr"></textarea></div>
</div>
2 голосов
/ 10 июня 2009

Раствор 1

Если вы можете позволить себе дублировать HTML:

.left-column .right, .right-column .left {
    display: none;
}

Раствор 2

Подождите немного, пока браузеры не поддержат CSS3 :

.right {
    position: flow(side); 
}

Решение 3

Если ваши дивы имеют одинаковую высоту, используйте косвенный соседний комбинатор соседей или сестер . Несмотря на то, что он относится к уровню CSS 3, он уже хорошо поддерживается :

.container {
    position: relative;
}

.left, .right {
    position: absolute;
    top : 0;
    width: 50%;
} 

.left {
    left: 0;
}

.right {
    left: 50%;
}

.left ~ .left, .right ~ .right {
    top : 100px;
}

.left ~ .left ~ .left, .right ~ .right ~ .right {
    top : 200px;
}

.left ~ .left ~ .left ~ .left, .right ~ .right ~ .right ~ .right {
    top : 300px;
}

... /* you need to include as many rules as the maximum possible height */
2 голосов
/ 16 декабря 2008

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

Я думаю, что это ваше решение (не проверено).

.left { width: 51%; float: left; }
.right { width: 49%; }

51% мешает им плавать рядом друг с другом, а затем просто позволяет всему контенту .right обернуться вокруг этих плавающих блоков.

Меньшее мышление дает вам больше с HTML / CSS, и опять же - НЕТ использованию таблиц для разметки.

=== [править] ===

Я выполнил тест по этому вопросу, и он работает с парой твиков И если вы знаете, что первый элемент перемещается влево (или вправо, чтобы изменить поведение).

<style>
  div div { text-align: center; padding: 20px 0; overflow: hidden; }
  .left { width: 251px; float: left; background: red; }
  .right { width: 249px; background: green; }
</style>
<div style="width: 500px;" >
  <div class="left"> <p>1</p> </div>
  <div class="right">  <p>2</p> </div>
  <div class="left">  <p>3</p> </div>
  <div class="left">  <p>4</p> </div>
  <div class="right"> <p>5</p> </div>
  <div class="right"> <p>6</p> </div>
</div>
2 голосов
/ 13 декабря 2008

Вы пытаетесь разделить ваш входной поток на два независимых потока, и я не думаю, что CSS позволяет вам это делать. Использование левого и правого плавающих элементов - умная идея, но она не всегда будет работать. CSS spec говорит в 9.5.1 правило 5:

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

Итак, ваши поплавки могут прыгать влево, вправо и вниз, но не вверх.

Вы можете достичь всего с абсолютным позиционированием, но в этом нет ничего автоматического.

РЕДАКТИРОВАТЬ: я сказал в комментариях, что я не ожидаю, что CSS3 будет поддерживать такую ​​функцию, потому что она нарушает разделение содержимого и макета. Позже я вспомнил, что CSS3 планирует иметь сноски . Таким образом, если вы пометите некоторые из ваших div'ов с помощью «float: note», выбранные div-ы попадут в отдельную область «сноски» на странице. Я думаю, вы можете разместить их справа от остальной части макета.

1 голос
/ 15 декабря 2008

У вас есть Javascript - почему бы не использовать его?

Вы сказали это:

Эти div генерируются динамически, если в браузере есть Javascript, и я не хочу менять фактический порядок, который отображается при отсутствии Javascript по семантическим причинам ...

Вы отображаете эти <div> с, только если у пользователя есть Javascript - , почему бы не использовать Javascript для их перестановки? Если вы переместитесь # 4, чтобы быть после # 5, он будет хорошо смотреться с вашим текущим CSS.

Итак (с помощью jQuery):

$("div:eq(3)").remove().insertAfter("div:eq(4)");
1 голос
/ 13 декабря 2008

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

<table>
    <tr>
        <td>
            <p>One name</p> <textarea id="one"></textarea>
        </td>
       <td>
            <p>XYZ name</p> <textarea id="xyz"></textarea>
        </td>
    </tr>
   ....
 </table>

Alignement отлично работает со всеми браузерами.

0 голосов
/ 10 июня 2009

Проверьте 960 Grid System . Я использовал это в проектах в прошлом, и я должен сказать, что это работает довольно хорошо. Мало того, он прост в использовании и совместим во всех браузерах: D

Используя эту структуру:

<html>
    <head>
        <link rel="stylesheet" type="text/css" media="all" href="css/reset.css" />
        <link rel="stylesheet" type="text/css" media="all" href="css/text.css" />
        <link rel="stylesheet" type="text/css" media="all" href="css/960.css" />
     </head>
     <body>
     <div class="container_16">
         <div class="grid_1 alpha" style="text-align:center;">
            2
         </div>
         <div class="grid_1 omega" style="text-align:center;">
            1
         </div>
         <div class="clear"></div>
         <div class="grid_1 alpha" style="text-align:center;">
            4
         </div>
         <div class="grid_1 omega" style="text-align:center;">
            3
         </div>
         <div class="clear"></div>
         <div class="grid_1 alpha" style="text-align:center;">
            5
         </div>
         <div class="grid_1 omega" style="text-align:center;">
            4
         </div>
    </div>
</body>
</html>

альтернативный текст http://img40.imageshack.us/img40/6889/cd3cc920a04b80e06b8efef.png

Панель сверху текста взята из моего браузера, а не является частью CSS или макета.

0 голосов
/ 18 декабря 2008

Я чувствовал себя виноватым, что метод чистого CSS не сработал, но если вы не возражаете против использования JavaScript, чтобы получить то, что вам нужно, то вот несколько jQuery, которые будут работать (кто-то, вероятно, сможет очистить это для вас, если вам не нравится раздувать).

<style>
  #container { width: 500px; border: 1px grey solid; overflow: hidden; }
  #container .rightSide { width: 250px; float: right; }
  #container .left { width: 250px; background: red; padding: 20px 0; overflow: hidden; text-align: center; }
  #container .right { width: 250px; background: green; padding: 20px 0; overflow: hidden; text-align: center; }
</style>
<script type="text/javascript">
$(document).ready(function() {
  $('#container').prepend('<div class="rightSide"></div>');
  $('#container div.right').each(function() {
    var $rightContent = $(this).remove().html();
    $('.rightSide').append('<div class="right">' + $rightContent + '</div>');
  });
});
</script>
<div id="container" >
  <div class="right"> <p>1</p> </div>
  <div class="left">  <p>2</p> </div>
  <div class="left">  <p>3</p> </div>
  <div class="left">  <p>4</p> </div>
  <div class="right"> <p>5</p> </div>
  <div class="right"> <p>6</p> </div>
</div>
0 голосов
/ 14 декабря 2008

Может быть, вы можете пойти с абсолютным позиционированием? Конечно, это зависит от остальной структуры вашей страницы, но часто это вполне жизнеспособно.

0 голосов
/ 13 декабря 2008

Таблицы являются вполне приемлемым решением для этого ИМХО.

Обратная реакция на таблицы была направлена ​​на их использование для всего макета сайта. Но если вам нужно отобразить ваши данные в строках и столбцах ...... это то, для чего были созданы таблицы:)

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

http://www.blueprintcss.org/ это отличный фреймворк ИМХО.

...