Как создать сетку с divs (или другими тегами, не относящимися к таблице), которая имеет свойства, аналогичные свойствам таблицы, и без использования JS?

#html #css

Вопрос:

Я хотел бы создать сетку (из divs?) где каждая строка динамически изменяется по высоте самого большого элемента, а столбцы динамически изменяются по ширине самого большого элемента (в каждой строке / колонке, поэтому каждая строка и колонка будут разной высоты / ширины в зависимости от содержимого). Кроме того, я хотел бы дополнительно по горизонтали и вертикали центрировать контент (независимо от того, что там находится: фотографии, текст и т. Д.).

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

введите описание изображения здесь

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

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

РЕДАКТИРОВАТЬ: изображение-несколько плохой пример. Представьте, что текст идет до конца и завершается.

Комментарии:

1. сетка или гибкий ящик, оба могут работать просто отлично. Для сетки я бы использовал table-cell или flexbox для центрирования содержимого по вертикали и горизонтали внутри карточек

Ответ №1:

Для этого вы можете использовать сетку. Определите grid-template-rows , что вы хотите, grid-template-columns что вы хотите, каждый из которых, используя дробную длину родительской ширины и/или высоты, auto сделает размер дочернего контейнера сетки соответствующим содержимому элементов.

Затем назначьте размещение элементов с помощью grid-template-areas . Затем для каждого элемента назначьте grid-area свойство его собственному селектору.

 * {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.container {
  display: grid;
  grid-auto-columns: 1fr;
  grid-template-columns: 0.7fr 1.3fr;
  grid-template-rows: repeat(3, auto);
  grid-template-areas: "star-1 one-line" "star-2 two-line" "arrow three-line";
  padding: 1rem;
}

.box {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 2rem;
  border-top: 3px solid black;
  border-left: 3px solid black;
  border-right: 3px solid black;
}

.box-text {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  padding: 2rem;
  border-top: 3px solid black;
  border-right: 3px solid black;
}

.star-1 {
  grid-area: star-1;
  background-color: lightblue;
}

.one-line {
  grid-area: one-line;
  background-color: lightblue;
}

.star-2 {
  grid-area: star-2;
  background-color: pink;
}

.two-line {
  grid-area: two-line;
  background-color: pink;
}

.arrow {
  grid-area: arrow;
  background-color: lightgreen;
  border-bottom: solid 3px black;
}

.three-line {
  grid-area: three-line;
  background-color: lightgreen;
  border-bottom: 3px solid black;
} 
 <div class="container">
  <div class="star-1 box">star1</div>
  <div class="one-line box-text">one line of content</div>
  <div class="star-2 box">star2</div>
  <div class="two-line box-text">
    <p>two lines of content</p>
    <p>two lines of content</p>
  </div>
  <div class="arrow box">arrow</div>
  <div class="three-line box-text">
    <p>three lines of content</p>
    <p>three lines of content</p>
    <p>three lines of content</p>
  </div>
</div> 

Редактировать

Следующий фрагмент кода будет поддерживать динамически созданный поток, элементы могут быть динамически добавлены в DOM по вашему выбору: obj, php, что угодно, CSS-сетка возьмет на себя управление потоком.

Вы можете удалить область сетки из дочерних элементов и только один класс, необходимый для оформления дочерних элементов. О смене контейнера: grid-template-columns: auto 1fr; . Затем добавьте grid-auto-flow: rows; , строки будут динамически стилизоваться по мере их добавления в DOM. Размер родительского элемента ЗНАЧКОВ будет соответствовать высоте/ширине содержимого его дочернего элемента, но высота строк будет определяться самым высоким значком элемента или содержимым, содержимое заполнит оставшуюся ширину строки.

Селектор детей, я использую класс box с flex-direction: column; реквизитами и добавляю justify-content align-items их в центр содержимого. При необходимости добавьте отступы. Если вы хотите, чтобы два элемента строк были оформлены по-разному, добавьте второй класс в раздел содержимого и стиль по своему усмотрению.

 * {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.container {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-auto-flow: rows;
  padding: 1rem; 
}

.box {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  border-left: 3px solid black;
  border-bottom: 3px solid black;
  background-color: lightgreen;
}

.box:nth-of-type(3n 2) {
  background-color: pink;
}
.box:nth-of-type(3n 3) {
  background-color: lightblue;
}

.box:first-of-type, .box:nth-of-type(2) {
  border-top: 3px solid black;
}

.box:nth-of-type(even) {
  border-right: 3px solid black;
} 
 <div class="container">
  <div class="box">
  <img src="http://simpleicon.com/wp-content/uploads/star-256x256.png" width="100" height="100">
  </div>
  <div class="box">one line of content</div>
  <div class="box">
  <img src="http://simpleicon.com/wp-content/uploads/star-256x256.png" width="50" height="50">
  </div>
  <div class="box">
    <p>two lines of content</p>
    <p>two lines of content</p>
  </div>
  <div class="box">
  <img src="https://static.thenounproject.com/png/11587-200.png" width="150" height="150">
  </div>
  <div class="box">
    <p>three lines of content</p>
    <p>three lines of content</p>
    <p>three lines of content</p>
  </div>
  <div class="box">
  <img src="https://www.shareicon.net/data/128x128/2016/11/14/852357_rocket_512x512.png">
  </div>
  <div class="box">
    <p>This content will wrap its parent element making its height taller than the proceeding icon row element to its left. Nemo enim ipsam voluptatem, quia voluptas sit, aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos, qui ratione voluptatem sequi nesciunt, neque porro quisquam est, qui dolorem ipsum, quia dolor sit amet consectetur adipisci[ng] velit, sed quia non numquam [do] eius modi tempora inci[di]dunt, ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit, qui in ea voluptate velit esse, quam nihil molestiae consequatur, vel illum, qui dolorem eum fugiat, quo voluptas nulla pariatur? At vero eos et accusamus et iusto odio dignissimos ducimus, qui blanditiis praesentium voluptatum deleniti atque corrupti, quos dolores et quas molestias excepturi sint, obcaecati cupiditate non provident, similique sunt in culpa, qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio, cumque nihil impedit, quo minus id, quod maxime placeat, facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet, ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat</p>
  </div>
  
</div> 

Комментарии:

1. Это отличное начало. Спасибо! Пример CSS, похоже, «знает», что есть 2 столбца и 3 строки. В качестве аргумента предположим, что количество столбцов фиксировано, но строки генерируются динамически, поэтому количество неизвестно на момент написания CSS. Как бы вы создали grid-template-areas и grid-template-rows свойства?

2. @user439299 я вижу, проверьте мою правку , grid-auto-flow: rows это поможет.