Эквивалент таблицы с использованием DIV - PullRequest
4 голосов
/ 06 марта 2009

Сегодня я работал над созданием макета, который выглядит следующим образом:

+----+ +----+ +----+ +----+
|    | |    | |    | |    |
+----+ +----+ +----+ +----+

Выглядит просто, но у меня есть некоторые дополнительные характеристики:

  1. Максимальное количество столбцов (n) должно быть динамическим (эта HTML-страница генерируется во время выполнения).
  2. Весь набор должен быть горизонтально плавным (они сжимаются настолько, насколько могут, когда окно сужено.
  3. Весь набор также должен быть центрирован на экране не более чем в n столбцах в одной строке за раз.
  4. В идеале крайние правые «прямоугольники» опускаются в строку ниже и при необходимости переупорядочиваются, т. Е. Когда окно сужается и n прямоугольников не помещаются на экране.
  5. Конечно, когда отображается более n элементов, они просто создают дополнительные строки из них.
  6. Отдельные поля ограничены закругленными углами и могут быть активированы любым действием.

С некоторыми исследованиями (Google + адаптация к примерам, которые я нашел) я смог сделать # 6 так, как хотел, используя divs и css. Однако мне было очень тяжело делать 2-4. Я прошел почти весь путь, но я, по жизни, не мог заставить 2 и 3 работать. 2 было не таким уж большим делом, но 3 было решающим. Я использовал плавающие div для позиционирования и нашел пример сайта , в котором упоминалось использование относительного позиционирования и сдвига влево и т. Д., Чтобы получить его в центре, но в моем случае это просто не работало (хотя пример работает нормально). В моем случае вместо центрирования они начнут в центре и пойдут вправо, делая его комичным, поэтому я не знаю, что я пропустил.

Поработав с этим пару часов, я сделал это с помощью следующего кода примерно за 5 минут:

<simplified code>
max_columns = 3; /* whatever */
html = "<table>";
for i = 1 to num_elements
  if i % max_columns eq 1 then
    html += "<tr>";
  endif
  html += "<td>";
  html += "<div>my element</div>"; /* This is a complex multi-leveled div */
                                   /* that makes boxes with rounded corners */
  html += "</td>";
  if i % max_columns eq 0 or i eq num_elements then
    html += "</tr>";
  endif
endfor
html += "</table>";
</simplified code>

Это удовлетворяет всем моим требованиям, кроме # 4, которое приятно иметь, но не обязательно.

Вопрос: [Как бы вы] / [Есть ли способ] сделать это без использования таблиц?

РЕДАКТИРОВАТЬ : У меня не было возможности внедрить / протестировать любое из возможных решений ниже, так как мне нужно закончить другие аспекты (в течение следующих 5 дней), прежде чем я вернусь к этой проблеме , Мое текущее решение lame (?), Кажется, работает нормально, за исключением требования № 4, поэтому эта проблема сейчас не находится на моем критическом пути. Но я протестирую и скоро отправлю отзыв об этом. Так что я собираюсь оставить этот вопрос открытым до тех пор. Я ценю ответы. Спасибо.

EDIT # 2 : Итак, я попробовал некоторые из приведенных ниже решений, и вот что я придумал:

<html>
    <head>
    <style>
  .box {
          width: 19%;
          height: 150px;
          border: 1px solid black;
          display: inline-block;
          margin: 3 0 0 0;
  }
  #center {
          text-align: center;
          border: 1px solid green;
          width: 80%;
          height: 85%;
          padding: 0 0 0 0;
          vertical-align: middle;
          margin: 0;
  }
  .footr{
          text-align: center;
          border: 1px solid green;
          width: 80%;
          height: 38px;
          padding: 0 0 0 0;
          vertical-align: middle;
          margin: 0;
  }
  </style>
    </head>
    <body style="margin-left:0; margin-top:0; margin-right:3;" >
    <div style="background-image: url(x); height: 60; width:131; float:left;"></div>
    <div style="background-image: url(x); background-repeat:repeat-x; height:60;"></div>
    <div class="clearer"></div>
    <center>
    <div id="center">
          <span class="box" style="float:left;">Blah</span>
          <span class="box">Blah</span>
          <span class="box">Blah</span>
          <span class="box">Blah</span>
          <span class="box" style="float:right;">Blah</span><br>
          <span class="box" style="float:left;">Blah</span>
          <span class="box">Blah</span>
          <span class="box">Blah</span>
          <span class="box">Blah</span>
          <span class="box" style="float:right;">Blah</span><br>
          <span class="box" style="float:left;">Blah</span>
          <span class="box">Blah</span>
          <span class="box">Blah</span>
    </div>
    <div class="footr">Footer</div>
    </center>
    </body
</html>

Как вы, вероятно, можете сказать, это решает почти все мои проблемы, за исключением 2/3 (не упоминалось в моем первоначальном вопросе:

  1. Вертикальное выравнивание всего блока так, чтобы его центр был вертикально
  2. В горизонтальном ряду я бы хотел, чтобы промежутки прилипали к внешним краям внешнего элемента div с равномерно расположенными между ними элементами div.
  3. В ряду с менее чем n промежутками, я бы соврал их, чтобы выстроиться под первые 3 пролета предыдущего ряда.

Я делаю это упражнение исключительно для моего личного "зуда, который просто должен поцарапать", и в свое собственное время. Что касается работы, я уже сделал большую часть этого (экономно), используя таблицы для правильного выравнивания материала.

P.S .: Прошу прощения за некоторые неправильно сформированные HTML, встроенные стили и т. Д. Как только я получу 100% -ное рабочее решение, я очистю его.

Ответы [ 6 ]

2 голосов
/ 09 марта 2009

Лучше всего, если вы используете таблицы для табличных данных. Помните о проблеме Divitis .

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

1 голос
/ 09 марта 2009

Вы можете попробовать display:inline-block;. Это удовлетворяло бы всем условиям, связанным с расширением-сокращением.

Учебное пособие здесь: display: inline-block; учебник

Пример использования здесь: display: inline-block; Пример

1 голос
/ 06 марта 2009

Вопрос: [Как бы вы] / [Есть ли любой способ сделать это без использования таблицы?

Просто дайте им фиксированную ширину и поместите их влево. (Если у них нет заданной ширины, этого будет недостаточно).

1 голос
/ 06 марта 2009

Попробуйте, если вам подходит:

<html>
    <head>
        <title>box test</title>
        <link rel="stylesheet" href="style.css">
    </head>
    <body>
        <div id="boxContainer">
            <span class="box">1</span>
            <span class="box">2</span>
            <span class="box">3</span>
            <span class="box">4</span>
            <span class="box">5</span>
            <span class="box">6</span>
            <span class="box">7</span>
            <span class="box">8</span>
            <span class="box">9</span>
            <span class="box">a longer block</span>
            <span class="box">a longer multi <br/> lined<br/> block</span>
            <span class="box">12</span>
            <span class="box">13</span>
            <span class="box">14</span>
            <span class="box">15</span>
            <span class="box">16</span>
            <span class="box">17</span>
            <span class="box">18</span>
            <span class="box">19</span>
            <span class="box">20</span>         
        </div>
    </body>
</html>

#boxContainer{
    text-align: center;

    background-color: #D0DC16;
    border: 1px solid black;
    height: 100%;
    padding: 1em 0 1em 0;
    width: 100%;
}
.box{
    /*width: 24%;*/
    display: inline-block;

    padding: 2em;
    margin: 0.5em 0 0.5em 0;
    background-color: #DC6216;
    border: 1px solid black;
}

Вы бы изменили .box widht на (100 / n) -1. Я точно не знаю, почему -1, но, вероятно, это как-то связано с полем и границей, не учитываемыми по ширине, и тем фактом, что один пиксель не может быть разделен на подпиксели.

- EDIT -
Пересмотрен код после комментариев. Линия ширины комментария / ширины блока для самостоятельной подгонки / фиксированное количество блоков в строке.
Добавлены две нерегулярные коробки.

0 голосов
/ 06 марта 2009

Ну, это то, что я придумал. Возможно, вам придется поиграть с шириной, чтобы скорректировать ошибки округления браузера / исправления пробелов, но в целом это должно работать. Также IE может понадобиться разумное использование переполнения: скрытый | авто.

<!DOCTYPE html>
<html><head><style type="text/css">

.container { width: 100%;text-align: center;}
.ib { min-width: 150px; display: -moz-inline-stack; display: inline-block; zoom: 1; *display: inline;}
.ib .styleMe { display: block; background: green; margin: 5px; text-align:left; border: 2px solid black; padding: 0 8px; }
.n1 .ib { width: 100%; } /* you could also use max-width here (if you can ignore IE6) and want jagged lines of items */
.n2 .ib { width: 50%; }
.n3 .ib { width: 33%; }
.n4 .ib { width: 25%; }
.n5 .ib { width: 20%; }
.n6 .ib { width: 16%; }
/*.nX .ib { max-width: 100/X; } may need to account for white-space/browser rounding errors too! */

</style></head>
<body>

<div class="container n4">
    <div class="ib"><div class="styleMe">
        <p>One</p>
        <p>Line 2</p>
    </div></div><!--
    kill whitespace (or adjusts widths above)
    --><div class="ib"><div class="styleMe">
        <p>Two</p>
        <p>Line 2</p>
    </div></div><!--
    kill whitespace (or adjusts widths above)
    --><div class="ib"><div class="styleMe">
        <p>Three</p>
        <p>Line 2</p>
    </div></div><!--
    kill whitespace (or adjusts widths above)
    --><div class="ib"><div class="styleMe">
        <p>Four</p>
        <p>Line 2</p>
    </div></div><!--
    kill whitespace (or adjusts widths above)
    --><div class="ib"><div class="styleMe">
        <p>Five</p>
        <p>Line 2</p>
    </div></div><!--
    kill whitespace (or adjusts widths above)
    --><div class="ib"><div class="styleMe">
        <p>Six</p>
        <p>Line 2</p>
    </div></div>
</div>
</body></html>
0 голосов
/ 06 марта 2009

Превратите элементы div в встроенные элементы и задайте им фиксированную ширину:

<html>
<head><title>Column test</title></head>
<style>
.box {
        width: 60px;
        height: 20px;
        border: 1px solid black;
        display: inline;
        margin: 3px;
}
.center {
        text-align: center;
        border: 1px solid green;
}
</style>
<body>
<div class="center">
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
</div>
</body>
</html>

Это будет перетекать их друг за другом, как обычный текст. Как только в текущей строке больше не будет элементов, они начнут новый.

Вам нужна фиксированная ширина, потому что ширина по умолчанию составляет 100%. Было бы неплохо, если бы можно было сказать «ширина, чтобы соответствовать содержимому», но это не сработало, поскольку для содержимого div требуется ширина элемента div для макета самого себя (проблема курицы и яйца).

...