Flexbox макет нескольких элементов, оборачивая вокруг одного - PullRequest
1 голос
/ 24 апреля 2020

Я хочу использовать макет, подобный следующему изображению, используя flexbox:

enter image description here

Я пробовал следующее, но пока не повезло:

.flex-container {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  width: 200px;
}

.flex-item:not(:first-child) {
  width: calc(100% - 50px);
  background-color: gray;
  border: 1px solid blue;
}

.flex-item:first-child {
  width: 50px;
  height: 100%;
  border: 1px solid blue;
  background-color: red;
}
<div class="flex-container">
  <div class="flex-item">item 1(long)</div>
  <div class="flex-item">item 2</div>
  <div class="flex-item">item 3</div>
  <div class="flex-item">item 4</div>  
</div>

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

Ответы [ 2 ]

1 голос
/ 24 апреля 2020

Возможно использовать вашу структуру DOM, но я сомневаюсь, что она будет особенно полезна, и, как уже говорили другие, вам лучше использовать Grid или даже просто встроенные элементы. Проблема в том, что вы пытаетесь смешать два контекста макета, а flexbox на самом деле не создан для этого.

Дайте контейнеру явную высоту, а более широким элементам свойство flex:1, которое заставит их расти и заполняться. оставшееся пространство. Я использовал nth-child, так как он более читабелен для меня, и ваш исходный код на самом деле не вел себя так, как вы предполагали, когда его помещали в codepen.

.flex-container {
  border: 1px solid green;
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
  width: 200px;
  height: 200px;
}

.flex-item {
  height: 100%;
  width: 50px;
  background-color: gray;
  border: 1px solid blue;
}

.flex-item:nth-child(n+2) {
  width: calc(100% - 50px);
  flex: 1;
  border: 1px solid blue;
  background-color: red;
}
<div class="flex-container">
  <div class="flex-item">item 1(long)</div>
  <div class="flex-item">item 2</div>
  <div class="flex-item">item 3</div>
  <div class="flex-item">item 4</div>  
</div>
1 голос
/ 24 апреля 2020

CSS Схема сетки будет более уместным.

body {
  background: white;
  color: #323232;
  font-weight: 300;
  height: 100vh;
  margin: 0;
  font-family: Helvetica neue, roboto;
}

.flex-container {
  display: grid;
  width: 90%;
  height: 50%;
  margin: 2rem auto;
  text-align: center;
  grid-template-columns: 25% 75%;
  grid-template-rows: 25% 25% 50%;
}

.flex-item1 {
  grid-column: 1 / 2;
  grid-row: 1 / 4;
  background: pink;
}

.flex-item2 {
  grid-column: 2 / 3;
  grid-row: 1 / 2;
  background: lightcoral;
}

.flex-item3 {
  grid-column: 2 / 3;
  grid-row: 2 / 3;
  background: lemonchiffon;
}

.flex-item4 {
  grid-column: 2 / 3;
  grid-row: 3 / 4;
  background: lightblue;
}
<div class="flex-container">
  <div class="flex-item1">item 1</div>
  <div class="flex-item2">item 2</div>
  <div class="flex-item3">item 3</div>
  <div class="flex-item4">item 4</div>
</div>

Хотя вы можете сделать это с Flexbox. Для меня имеет смысл внести небольшое изменение в структуру DOM. Ваши предметы 2, 3, 4 будут завернуты в другой контейнер Flex.

body {
  background: white;
  color: #323232;
  font-weight: 300;
  height: 100vh;
  margin: 0;
  display: flex;
  font-family: Helvetica neue, roboto;
}

.flex-container {
  display: flex;
  flex-wrap: wrap;
  width: 90%;
  height: 50%;
  margin: 1rem;
  text-align: center;
}

.flex-itemA {
  width: 25%;
  background: pink;
}

/* Flex-itemB and Flex container itself for the next 3 elements */

.flex-itemB {
  width: 75%;
  display: flex;
  flex-wrap: wrap;
  flex-direction: column;
  background: lightblue;
}

.flex-itemB1,
.flex-itemB2 {
  height: 25%;
}

.flex-itemB1 {
  background: lightcoral;
}

.flex-itemB2 {
  background: lemonchiffon;
}
<div class="flex-container">
  <div class="flex-itemA">item A</div>
  <div class="flex-itemB">
    <div class="flex-itemB1">item B1</div>
    <div class="flex-itemB2">item B2</div>
    <div class="flex-itemB3">item B3</div>
  </div>
</div>

РЕДАКТИРОВАТЬ на основе @ lawrence-witt answer

Или, если вы действительно хотите сохранить структуру DOM таким образом и используйте Flexbox, а не Grid. Тогда вы можете сделать это, как предложил @ lawrence-witt. Я сохранил селекторы: nth-child, хотя было бы легко добавить класс для каждого элемента и избежать увеличения специфичности .

body {
  background: white;
  color: #323232;
  font-weight: 300;
  height: 100vh;
  margin: 0;
  font-family: Helvetica neue, roboto;
}

.flex-container {
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
  width: 90%;
  height: 50%;
  margin: 2rem 5%;
  text-align: center;
}

.flex-item {
  height: 100%;
  width: 25%;
  background: pink;
}

.flex-item:nth-child(n + 2) {
  width: 75%;
  /* This will make the height = 25% since the last element will have flex-grow: 1 */
  flex: 0.5;
}

.flex-item:nth-child(2) {
  background: lightcoral;
}

.flex-item:nth-child(3) {
  background: lemonchiffon;
}

.flex-item:nth-child(4) {
  flex: 1;
  background: lightblue;
}
<div class="flex-container">
  <div class="flex-item">item 1</div>
  <div class="flex-item">item 2</div>
  <div class="flex-item">item 3</div>
  <div class="flex-item">item 4</div>
</div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...