Как сделать таблицу с гибкой раскладкой? - PullRequest
0 голосов
/ 07 марта 2020

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

Теперь я хочу гибкую высоту, поэтому я пытаюсь использовать flex:

/* SOME BASE CSS SETTINGS */

* {
  box-sizing: border-box;
}

body,
html {
  color: white;
  width: 100%;
  height: 100%;
  padding: 0px;
  margin: 0px;
}


/* A FLEX COLUMN CONTAINER */

.flexContainer {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: stretch;
}


/* FLEX ELEMENT THAT SHOULD GROW TO FIT THE AVAILABLE SPACE */

.flexGrow {
  flex-grow: 1;
}


/* SECTION ONE IS HIDDEN, BUT EXISTS IN REAL LIFE */

#S1 {
  display: none;
  visibility: hidden;
}

#S1>header {
  background-color: red;
  min-height: 450px;
}

#S1>main {
  background-color: green;
  overflow: auto;
  min-height: calc(100% - 550px);
  max-height: calc(100% - 550px);
}

#S1>footer {
  background-color: blue;
  min-height: 100px;
}


/* SECTION 2 IS VISIBLE */

#S2>header {
  background-color: red;
  min-height: 150px;
}

#S2>main {
  background-color: green;
  /* If I remove this, MAIN won't be displayed beside NAV */
  display: inline-block;
  /* If I remove this, the document body will scroll :( */
  min-height: calc(100% - 250px);
  max-height: calc(100% - 250px);
}

#S2>main>div {
  flex-direction: row;
}

#S2>main>div>nav {
  background-color: black;
  min-width: 450px;
}

#S2>main>div>section {
  background-color: teal;
  width: 100%;
  height: 100%;
  /* If I remove this, the body will scroll the big table of sub section 1! */
  overflow: auto;
}

#S2>footer {
  background-color: blue;
  min-height: 100px;
}


/* SUB SECTION 1 IS VISIBLE */

#SS1 {
  border: 5px solid green;
}

#SS1>div {
  background-color: turquoise;
  border: 5px solid turquoise;
}

#SS1>div>.table {
  /* Why does this overflow!? It should only fill the available space. */
  background-color: violet;
  border: 5px solid violet;
  width: 100%;
}

#SS1>div>.table>.container {
  background-color: wheat;
  border: 5px solid wheat;
}

#SS1>div>.table>.container>.header {
  background-color: silver;
  border: 5px solid silver;
  width: 100%;
  height: 40px;
}

#SS1>div>.table>.container>.data {
  background-color: yellowgreen;
  border: 5px solid yellowgreen;
  width: 100%;
}

#SS1>div>.table>.container>.data>.container {
  background-color: cadetblue;
  border: 5px solid cadetblue;
  width: 100%;
  height: 100%;
  /* This scrolling should be applied to have a fixed header and a scrolling body - but instead the sub section is scrolling :S */
  overflow-y: auto;
}

#SS1>div>.table>.container>.data>.container>.body {
  background-color: brown;
  border: 5px solid brown;
  width: 100%;
}

#SS1>div>.table>.container>.data>.container>.body tr {
  height: 200px;
  /* Ensure the table data will overflow */
}

#SS1>div>.table td {
  width: 150px;
}

#SS1>div>.table td:nth-child(2) {
  width: auto;
}


/* SUB SECTION 2 IS HIDDEN, BUT EXISTS IN REAL LIFE */

#SS2 {
  display: none;
  visibility: hidden;
}
<!DOCTYPE html>

<body>
  <section id="S1" class="flexContainer">
    <header>S1 HEADER</header>
    <main class="flexGrow">S1 MAIN</main>
    <footer>S1 FOOTER</footer>
  </section>
  <section id="S2" class="flexContainer">
    <header>S2 HEADER</header>
    <main class="flexGrow">
      <div class="flexContainer">
        <nav>S2 NAV</nav>
        <section id="SS1" class="flexGrow">
          <div class="flexContainer">
            <h1>S2 SECTION 2</h1>
            <div class="table flexGrow">
              <div class="container flexContainer">
                <table class="header">
                  <thead>
                    <tr>
                      <td>Column 1</td>
                      <td>Column 2</td>
                      <td>Column 3</td>
                      <td>Column 4</td>
                      <td>Column 5</td>
                    </tr>
                  </thead>
                </table>
                <div class="data flexGrow">
                  <div class="container">
                    <table class="body">
                      <tbody>
                        <tr>
                          <td>Cell 1</td>
                          <td>Cell 2</td>
                          <td>Cell 3</td>
                          <td>Cell 4</td>
                          <td>Cell 5</td>
                        </tr>
                        <tr>
                          <td>Cell 1</td>
                          <td>Cell 2</td>
                          <td>Cell 3</td>
                          <td>Cell 4</td>
                          <td>Cell 5</td>
                        </tr>
                        <tr>
                          <td>Cell 1</td>
                          <td>Cell 2</td>
                          <td>Cell 3</td>
                          <td>Cell 4</td>
                          <td>Cell 5</td>
                        </tr>
                        <tr>
                          <td>Cell 1</td>
                          <td>Cell 2</td>
                          <td>Cell 3</td>
                          <td>Cell 4</td>
                          <td>Cell 5</td>
                        </tr>
                        <tr>
                          <td>Cell 1</td>
                          <td>Cell 2</td>
                          <td>Cell 3</td>
                          <td>Cell 4</td>
                          <td>Cell 5</td>
                        </tr>
                        <tr>
                          <td>Cell 1</td>
                          <td>Cell 2</td>
                          <td>Cell 3</td>
                          <td>Cell 4</td>
                          <td>Cell 5</td>
                        </tr>
                      </tbody>
                    </table>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </section>
        <section id="SS2">S2 SECTION 2</section>
      </div>
    </main>
    <footer>S2 FOOTER</footer>
  </section>
</body>

Но есть несколько проблем с результатом:

  1. Фиолетовый контейнер должен занимать только доступное пространство, но не переполняться!
  2. То же самое с желто-зеленым контейнером
  3. Контейнер кадетского синего цвета содержит таблицу и должен прокручиваться, потому что таблица переполняется, но не прокручивается

И есть еще кое-что, что мне не очень нравится / не понятно:

  • Почему #S2>main должно быть inline-block, которое должно отображаться рядом с #S2>nav?
  • Почему я должен дать #S2>main высоту? Я предполагал, что высота будет соответствовать доступной высоте, но если я не укажу высоту, документ будет прокручиваться

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

Редактировать : Спасибо "Дэвид говорит восстановить Монику" за переформатирование HTML & CSS :) Благодаря G-Cyrillus Мне удалось получить то, что я хочу, просто добавив min-height:0px; к классу flexGrow CSS. И, конечно, я переутомлюсь, чтобы мое решение с фиксированными заголовками таблиц стало липким ...

1 Ответ

1 голос
/ 07 марта 2020

Возможно, вы могли бы использовать меньше запутывания и начать с шаблона и нескольких повторно используемых class (проще добавить / удалить для тестирования минимальных правил), а затем заполнить шаблон.

body {margin:0}
.vh-100 {height:100vh}
.flex {display:flex;}
.flex-grow-1 {flex-grow:1;}
.column {flex-flow:column;}
.min-height-0 {min-height:0}
.overflow-A{overflow:auto; }
#test:hover {height:100vh;}

section {background:tomato}
header {background:gold}
aside {background:lightblue;}
footer {background:orange}
#test {background:lightgreen}
section section, header,aside,footer ,#test{padding:0.25em;}
<section class="vh-100 flex column">
  <header>Section HEADER</header>
  <main class="flex-grow-1 flex min-height-0">
    <aside>
      <nav>Section NAV</nav>
    </aside>
    <section class="flex column flex-grow-1">
      <h1 >main header</h1>
      <div class="overflow-A flex-grow-1"> content to scroll if  needed
      <div id="test">test div to hover</div>
      </div>
    </section>
  </main>
  <footer>Section FOOTER</footer>
</section>

Получив эффективный элемент макета и прокрутки, вы можете заполнить его и, возможно, подумать о min-height безопасном значении.

Кроме того, вместо того, чтобы разбить table на 2 таблицы, ломая table-layout, удерживающие вместе thead и tbody, вы можете попробовать position:sticky; для thead

пример

body {margin:0}
.vh-100 {height:100vh}
.w-100 {width:100%;}
.minH-300 {min-height:300px;}/* make sure content don't get over squizzed */
.flex {display:flex;}
.flex-grow-1 {flex-grow:1;}
.column {flex-flow:column;}
.min-height-0 {min-height:0}
.overflow-A{overflow:auto; }
#test:hover {height:100vh;}

section {background:tomato}
header {background:gold}
aside {background:lightblue;}
footer {background:orange}
table,td {border:solid;}

.sticky-top {position:sticky;top:0;background:white}


section section, header,aside,footer{padding:0.25em;}
<section class="vh-100 flex column minH-300">
  <header>Section HEADER</header>
  <main class="flex-grow-1 flex min-height-0">
    <aside>
      <nav>Section NAV</nav>
    </aside>
    <section class="flex column flex-grow-1">
      <h1 >main header</h1>
      <div class="overflow-A flex-grow-1">
      
      <table class="header w-100">
        <thead class="sticky-top w-100">
          <tr>
            <td>Column 1</td>
            <td>Column 2</td>
            <td>Column 3</td>
            <td>Column 4</td>
            <td>Column 5</td>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td>Cell 1</td>
            <td>Cell 2</td>
            <td>Cell 3</td>
            <td>Cell 4</td>
            <td>Cell 5</td>
          </tr>
          <tr>
            <td>Cell 1</td>
            <td>Cell 2</td>
            <td>Cell 3</td>
            <td>Cell 4</td>
            <td>Cell 5</td>
          </tr>
          <tr>
            <td>Cell 1</td>
            <td>Cell 2</td>
            <td>Cell 3</td>
            <td>Cell 4</td>
            <td>Cell 5</td>
          </tr>
          <tr>
            <td>Cell 1</td>
            <td>Cell 2</td>
            <td>Cell 3</td>
            <td>Cell 4</td>
            <td>Cell 5</td>
          </tr>
          <tr>
            <td>Cell 1</td>
            <td>Cell 2</td>
            <td>Cell 3</td>
            <td>Cell 4</td>
            <td>Cell 5</td>
          </tr>
          <tr>
            <td>Cell 1</td>
            <td>Cell 2</td>
            <td>Cell 3</td>
            <td>Cell 4</td>
            <td>Cell 5</td>
          </tr>
          <tr>
            <td>Cell 1</td>
            <td>Cell 2</td>
            <td>Cell 3</td>
            <td>Cell 4</td>
            <td>Cell 5</td>
          </tr>
          <tr>
            <td>Cell 1</td>
            <td>Cell 2</td>
            <td>Cell 3</td>
            <td>Cell 4</td>
            <td>Cell 5</td>
          </tr>
          <tr>
            <td>Cell 1</td>
            <td>Cell 2</td>
            <td>Cell 3</td>
            <td>Cell 4</td>
            <td>Cell 5</td>
          </tr>
          <tr>
            <td>Cell 1</td>
            <td>Cell 2</td>
            <td>Cell 3</td>
            <td>Cell 4</td>
            <td>Cell 5</td>
          </tr>
          <tr>
            <td>Cell 1</td>
            <td>Cell 2</td>
            <td>Cell 3</td>
            <td>Cell 4</td>
            <td>Cell 5</td>
          </tr>
          <tr>
            <td>Cell 1</td>
            <td>Cell 2</td>
            <td>Cell 3</td>
            <td>Cell 4</td>
            <td>Cell 5</td>
          </tr>
          <tr>
            <td>Cell 1</td>
            <td>Cell 2</td>
            <td>Cell 3</td>
            <td>Cell 4</td>
            <td>Cell 5</td>
          </tr>
          <tr>
            <td>Cell 1</td>
            <td>Cell 2</td>
            <td>Cell 3</td>
            <td>Cell 4</td>
            <td>Cell 5</td>
          </tr>
          <tr>
            <td>Cell 1</td>
            <td>Cell 2</td>
            <td>Cell 3</td>
            <td>Cell 4</td>
            <td>Cell 5</td>
          </tr>
          <tr>
            <td>Cell 1</td>
            <td>Cell 2</td>
            <td>Cell 3</td>
            <td>Cell 4</td>
            <td>Cell 5</td>
          </tr>
          <tr>
            <td>Cell 1</td>
            <td>Cell 2</td>
            <td>Cell 3</td>
            <td>Cell 4</td>
            <td>Cell 5</td>
          </tr>
          <tr>
            <td>Cell 1</td>
            <td>Cell 2</td>
            <td>Cell 3</td>
            <td>Cell 4</td>
            <td>Cell 5</td>
          </tr>
          <tr>
            <td>Cell 1</td>
            <td>Cell 2</td>
            <td>Cell 3</td>
            <td>Cell 4</td>
            <td>Cell 5</td>
          </tr>
          <tr>
            <td>Cell 1</td>
            <td>Cell 2</td>
            <td>Cell 3</td>
            <td>Cell 4</td>
            <td>Cell 5</td>
          </tr>
          <tr>
            <td>Cell 1</td>
            <td>Cell 2</td>
            <td>Cell 3</td>
            <td>Cell 4</td>
            <td>Cell 5</td>
          </tr>
          <tr>
            <td>Cell 1</td>
            <td>Cell 2</td>
            <td>Cell 3</td>
            <td>Cell 4</td>
            <td>Cell 5</td>
          </tr>
          <tr>
            <td>Cell 1</td>
            <td>Cell 2</td>
            <td>Cell 3</td>
            <td>Cell 4</td>
            <td>Cell 5</td>
          </tr>
          <tr>
            <td>Cell 1</td>
            <td>Cell 2</td>
            <td>Cell 3</td>
            <td>Cell 4</td>
            <td>Cell 5</td>
          </tr>
          <tr>
            <td>Cell 1</td>
            <td>Cell 2</td>
            <td>Cell 3</td>
            <td>Cell 4</td>
            <td>Cell 5</td>
          </tr>
          <tr>
            <td>Cell 1</td>
            <td>Cell 2</td>
            <td>Cell 3</td>
            <td>Cell 4</td>
            <td>Cell 5</td>
          </tr>
          <tr>
            <td>Cell 1</td>
            <td>Cell 2</td>
            <td>Cell 3</td>
            <td>Cell 4</td>
            <td>Cell 5</td>
          </tr>
          <tr>
            <td>Cell 1</td>
            <td>Cell 2</td>
            <td>Cell 3</td>
            <td>Cell 4</td>
            <td>Cell 5</td>
          </tr>
          <tr>
            <td>Cell 1</td>
            <td>Cell 2</td>
            <td>Cell 3</td>
            <td>Cell 4</td>
            <td>Cell 5</td>
          </tr>
          <tr>
            <td>Cell 1</td>
            <td>Cell 2</td>
            <td>Cell 3</td>
            <td>Cell 4</td>
            <td>Cell 5</td>
          </tr>
          <tr>
            <td>Cell 1</td>
            <td>Cell 2</td>
            <td>Cell 3</td>
            <td>Cell 4</td>
            <td>Cell 5</td>
          </tr>
          <tr>
            <td>Cell 1</td>
            <td>Cell 2</td>
            <td>Cell 3</td>
            <td>Cell 4</td>
            <td>Cell 5</td>
          </tr>
          <tr>
            <td>Cell 1</td>
            <td>Cell 2</td>
            <td>Cell 3</td>
            <td>Cell 4</td>
            <td>Cell 5</td>
          </tr>
          <tr>
            <td>Cell 1</td>
            <td>Cell 2</td>
            <td>Cell 3</td>
            <td>Cell 4</td>
            <td>Cell 5</td>
          </tr>
          <tr>
            <td>Cell 1</td>
            <td>Cell 2</td>
            <td>Cell 3</td>
            <td>Cell 4</td>
            <td>Cell 5</td>
          </tr>
        </tbody>
      </table>
      </div>
      <p>a paraph standing below scrolling div</p>
    </section>
  </main>
  <footer>Section FOOTER</footer>
</section>
...