абсолютное позиционирование внутри стола - PullRequest
5 голосов
/ 23 июля 2011

Мне нужно что-то позиционировать с абсолютным позиционированием внутри тд. Чтобы обойти тот факт, что td не определено при установке его на относительный, я использую div, установленный на относительный внутри моего td, а затем внутри этого div у меня есть внутренний div, установленный на абсолютный. Это все прекрасно работает, когда у меня есть контент, заполняющий тд. Когда я устанавливаю содержимое td, чтобы отображать ничего, тогда абсолютное позиционирование облажалось.

Кто-нибудь знает, почему это так.

HTML:

<table>
    <tr>
        <td>
            <div class="relative">
                <div class='absolute'>
                    <p>A</p>
                </div>
            </div>
            <div class="slot"></div>
            <div class="slot"></div>
        </td>
        <td>
          <div class="relative">
             <div class='absolute'>
               <p>B</p>
           </div>
           </div>
           <div class="slot hidden"></div>
           <div class="slot"></div>
        </td>
    </tr>
</table>

И CSS:

td{
    border:1px solid red;
    width:100px;
    height:60px;
    vertical-align:bottom;
}

.slot{
  width:100px;
  height:29px;
  background-color:#999;
  border:1px dashed blue;
}

.relative{
    position:relative;
}

.absolute{
    position:absolute;
    top:5px;
    left:5px;
}
.hidden{
    display:none;
}

И живая версия: http://jsfiddle.net/HgEtQ/

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

1 Ответ

4 голосов
/ 23 июля 2011

Здесь происходит пара вещей.

У вас есть это:

td {
    /*...*/
    vertical-align:bottom;
}

Это подтолкнет содержимое ячеек ко дну.

Также, абсолютно позиционированный элемент удаляется из нормального потока , поэтому он не влияет на высоту своего родителя:

Он полностью удаляется из нормального потока (он не оказывает влиянияна поздних братьях и сестрах).Абсолютно позиционированный блок устанавливает новый содержащий блок для дочерних элементов нормального потока и абсолютно (но не фиксированных) позиционных потомков.

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

Тогда у вас есть <div class="slot hidden">, а hidden удаляет <div> из макета, так что вы фактически получаете только это:

<div class="relative"></div> <!-- Height zero -->
<div class="slot"></div>     <!-- Height 29px -->

Это в сочетании с vertical-align: bottom означает, что ваш второй div.absolute будет расположен на 5px от верха div.slot, а это на 25px от нижней части ячейки таблицы.

Первая ячейка работает нормально, потому что два видимых элемента div.slot выдвигают div.relative вправо к верху ячейки, затем div.absolute располагается на 5 пикселей сверху div.relative, а это на 5 пикселей сверхуячейки таблицы.

К сожалению, добавление position: relative к <td> немного утомительно, так как браузеры идут, поэтому вам понадобятся некоторые хакеры, чтобы получитьВаше правильное положение при сохранении vertical-align: bottom.Вы можете изменить структуру <td> следующим образом:

<td>
    <div class="relative">
        <div class='absolute'>
            <p>A</p>
        </div>
    </div>
    <div class="nonsense">
        <div class="slot"></div>
        <div class="slot"></div>
    </div>
</td>

И CSS следующим образом:

td{
    border:1px solid red;
    width:100px;
    height:60px;
    vertical-align: top;
}

.slot{
    width:100px;
    height:29px;
    background-color:#999;
    border:1px dashed blue;
}

.relative {
    position:relative;
}
.nonsense {
    height: 62px; /* td[height] + 2 for the borders */
    display: table-cell;
    vertical-align: bottom;
}

.absolute{
    position:absolute;
    top:5px;
    left:5px;
}
.hidden{
    display:none;
}

Пример в реальном времени: http://jsfiddle.net/ambiguous/aV4nT/

ИлиВы можете использовать visibility: hidden:

скрыто
Сгенерированное поле невидимо (полностью прозрачно, ничего не рисуется), но все равно влияет на макет,Кроме того, потомки элемента будут видны, если у них будет «visibility: visible».

вместо display: none для вашего .hidden класса:

.hidden {
    visibility: hidden;
}

Это будетоба элемента div.slot занимают место и влияют на макет, но будет виден только второй элемент.

Пример в реальном времени: http://jsfiddle.net/ambiguous/RcdNh/

...