У меня проблема, которую я не понимаю, относительно масштабирования дочерних элементов внутри таблиц html.

Чтобы начать с самого начала, моя цель - создать таблицу и наложить ее тело на div, используя z-index. При правильном цвете это выглядит так, как будто таблица неактивна и по ней нельзя щелкнуть.

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

table {
  border: 1;
  border-color: blue;
}

#content {
  position: relative;
}

#content * {
  position: inherit;
}

#overlay {
  top: 0;
  left: 0;
  /*bottom: 0;
  right: 0;*/
  position: absolute !important;
  background: rgba(0, 0, 0, .4);
  z-index: 3;
  width: 100%;
  height: 100%
}
<div id="content">
  <div>
    Some stuff before
  </div>
  <br>
  <table>
    <thead>
      <tr>
        <th>Header 1</th>
        <th>Header 2</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>
          <div>
            Cell
          </div>
          <div id="overlay"></div>
        </td>
        <td>Cell</td>
      </tr>
      <tr>
        <td>Cell</td>
        <td>Cell</td>
      </tr>
      <tr>
        <td>Cell</td>
        <td>Cell</td>
      </tr>
    </tbody>
    <tfoot>
      <tr>
        <td>Footer 1</td>
        <td>Footer 2</td>
      </tr>
    </tfoot>
  </table>
  <br>
  <div>
    Some stuff after
  </div>
</div>

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

Ура

0
Alex 6 Ноя 2018 в 19:46

1 ответ

Лучший ответ

Ячейки вашей таблицы также должны быть установлены на position: relative. Вместо #content * установите их напрямую, используя td или хотя бы #content td.

td {
  position: relative;
}

#overlay {
  top: 0;
  left: 0;
  position: absolute;
  background: rgba(0, 0, 0, .4);
  z-index: 3;
  width: 100%;
  height: 100%
}
<div id="content">
  <table>
    <thead>
      <tr>
        <th>Header 1</th>
        <th>Header 2</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>
          <div>
            Cell
          </div>
          <div id="overlay"></div>
        </td>
        <td>Cell</td>
      </tr>
      <tr>
        <td>Cell</td>
        <td>Cell</td>
      </tr>
    </tbody>
    <tfoot>
      <tr>
        <td>Footer 1</td>
        <td>Footer 2</td>
      </tr>
    </tfoot>
  </table>
</div>

Так почему это работает?

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

Но это только половина правды. Все основные браузеры (протестированные с Chrome, Firefox и IE11) позволяют большинству (или, возможно, даже всем) свойствам наследовать от своих родительских. Когда вы протестируете свой фрагмент в Firefox или IE11, вы увидите, что он действительно работает. Так почему же тогда не в Chrome?

Оказывается, у Chrome есть проблемы с режимами отображения table-* и самими тегами таблиц. При наследовании он всегда использует значение по умолчанию position (то есть static). Даже если для ближайшего родителя установлено значение position: relative, это не будет работать, как показано в следующем фрагменте кода.

Итак, в заключение: лучше всегда явно устанавливать position: relative и в большинстве случаев избегать использования inherit вместе.

main {
  position: relative;
  border: 2px solid #000;
  width: 200px;
  margin-bottom: 20px;
}

table, .fake-table {
  min-height: 50px;
  margin: 10px;
}

table, tr, td, .fake-table div {
  position: inherit;
}

.relative {
  position: relative;
}

em {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  min-width: 100px;
  height: 100%;
  background: rgba(166, 199, 252, .9);
  text-shadow: 0 0 10px #fff;
}

.fake-table .table {
  display: block;
}

.fake-table .row {
  display: flex;
  justify-content: flex-start;
}

.fake-table .cell {
  display: inline-block;
  min-width: 40px;
}
<main>
  <table>
    <tr>
      <td>...</td>
      <td>
        cell
        <em>Starting point (inherited table)</em>
      </td>
    </tr>
  </table>
</main>

<main>
  <table>
    <tr class="relative">
      <td>...</td>
      <td>
        cell
        <em>Parent is set to relative</em>
      </td>
    </tr>
  </table>
</main>

<main class="fake-table">
  <table class="table">
    <tr class="row">
      <td class="cell">...</td>
      <td class="cell">
        cell
        <em>Table tags in different display mode</em>
      </td>
    </tr>
  </table>
</main>

<main class="fake-table">
  <div class="table">
    <div class="row">
      <div class="cell">...</div>
      <div class="cell">
        cell
        <em>Table using flex (behaves correctly)</em>
      </div>
    </div>
  </div>
</main>

<main>
  <table>
    <tr>
      <td>...</td>
      <td class="relative">
        cell
        <em>Expected rendering</em>
      </td>
    </tr>
  </table>
</main>
1
lumio 7 Ноя 2018 в 10:08