Как управлять вертикальным и горизонтальным интервалом во Flex с горизонтальным выравниванием по центру и упаковкой элементов? - PullRequest
0 голосов
/ 07 марта 2020

Упаковываемые элементы расположены горизонтально и выровнены по центру. Как бы вы управляли вертикальным и горизонтальным интервалом?

enter image description here

В этом примере мы хотели бы иметь горизонтальное пространство 16 пикселей между элементами и вертикальное пространство 8 пикселей .

Вот возможное решение:

/* Solution */

.flex-wrapper {
  padding-top: 1px;
}

.flex-wrapper:before {
  content: "";
  display: block;
  margin-top: -9px;
}

.flex {
  display: flex;
  flex-wrap: wrap;
  margin-left: -16px;
  justify-content: center;
}

.flex-item {
  padding-left: 16px;
  padding-top: 8px;
}


/* For demo purposes, not related to solution. */

body {
  margin: 50px;
}

.container {
  width: 600px;
  outline: 1px solid black;
}

button {
  width: 100px;
  height: 40px;
  background: none;
  border: 4px solid red;
  font-size: 16px;
}
<div class="container">
  <div class="flex-wrapper">
    <div class="flex">
      <div class="flex-item">
        <button>1</button>
      </div>
      <div class="flex-item">
        <button>2</button>
      </div>
      <div class="flex-item">
        <button>3</button>
      </div>
      <div class="flex-item">
        <button>4</button>
      </div>
      <div class="flex-item">
        <button>5</button>
      </div>
      <div class="flex-item">
        <button>6</button>
      </div>
      <div class="flex-item">
        <button>7</button>
      </div>
      <div class="flex-item">
        <button>8</button>
      </div>
      <div class="flex-item">
        <button>9</button>
      </div>
    </div>
  </div>
</div>

Это решение выглядит несколько странно, особенно часть .flex-wrapper.

Есть ли лучший способ?


Примечания:

  • Элементы могут иметь различную ширину.
  • Я ищу решение, которое работает независимо от того, обертывают элементы или нет. Элементы могут также занимать много строк, а не только две строки, как в этом примере.
  • На момент написания этого вопроса браузеры не имели большой поддержки gap в Flex.

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

Ответы [ 5 ]

0 голосов
/ 16 марта 2020

Вы не контролируете пространство между элементами в своем вопросе, так как вы используете свойство padding, элементы располагаются один за другим, но вы достигаете эффекта. Если вы поместите фон на каждый, вы заметите, что я пытаюсь объяснить.

Чтобы контролировать пространство между элементами в макете flexbox (или другом), вам нужно использовать поле для элементов, в этом случае, для элементов внутри элемента display: flex;.

Я использовал значения cal c из-за переменных S CSS, здесь я изменил имя переменной на 30px.

Есть фрагмент, который достигает того, что вы хотите.

.flexcontainer {
  padding: 0 15px;
  width: 100%;
  border:1px solid black;
}
.flexrow {
  display:flex;
  flex-flow: row wrap;
  /* only horizontal negative margin for beggining and end of the element, as you may not know which element is first on the left or right, it will compensate the padding of container */
  margin: 0px calc(30px/2 * -1);
  justify-content: space-around;
}

.flexrow.row-5-el > .element { 
  flex: 0 1 calc(100%/5  - 30px);
  max-width: calc(100%/5  - 30px); 
  /* sets 15px of margin on each side */
  margin: calc(30px/2); 
  /* for testing purposes */
  outline: 1px auto green;
}
<div class="flexcontainer">
  <div class="flexrow row-5-el">
    <div class="element"> Lorem ipsum </div>
    <div class="element"> Lorem ipsum </div>
    <div class="element"> Lorem ipsum </div>
    <div class="element"> Lorem ipsum </div>
    <div class="element"> Lorem ipsum </div>
    <div class="element"> Lorem ipsum </div>
    <div class="element"> Lorem ipsum </div>
    <div class="element"> Lorem ipsum </div>
    <div class="element"> Lorem ipsum </div>
  </div>
</div>

Если вы хотите, чтобы первый элемент начинался слева от 0, вам нужно только удалить отступы контейнера.

Вот живой пример, который я сделал некоторое время go: https://codepen.io/joelbonetr/pen/gOpPYbR

(без justify-content, так как желаемый эффект заключался в том, чтобы обернутые элементы были выровнены по левому краю)

0 голосов
/ 15 марта 2020

Простым решением может быть использование размеров ящика, а затем управление вертикальным и горизонтальным интервалом с отступом.

.flex-item {
  box-sizing: border-box;
  padding: 4px 8px;
}

Или универсальное применение:

*, *:before, *:after {
  box-sizing: border-box;
}

https://developer.mozilla.org/en-US/docs/Web/CSS/box-sizing

0 голосов
/ 07 марта 2020

Начиная с ответа @ rx2347 CSS на основе сетки в качестве базовой линии, но приближаясь к макету, который вы на самом деле ищете ... Если у вас есть достаточное количество фиксированных элементов, которые вы хотите разместить, вы можете вручную установить положение ваших элементов туда, куда вы хотите, используя repeat(), чтобы создать гораздо более мелкую сетку, а затем разместите ваш элемент в указанных столбцах c с более высокой степенью детализации.

Возможно, есть другие способы достижения этого на основе смещения / отступа для каждой строки с помощью CSS -grid. Чтобы сделать его действительно автоматическим c, например, для обработки большого количества элементов и / или произвольного числа элементов, я бы соблазнился использовать сценарии jQuery, возможно, с сеткой CSS для итерации и установки позиций. , Могут быть чистые CSS и HTML способы размещения более произвольного числа элементов. Это действительно зависит от вашей заявки.

enter image description here

.container {
  display: grid;
  width: 800px;
  grid-template-columns: repeat(60, 10px);
  grid-column-gap: 16px;
  grid-row-gap: 8px;
}

#button1 {
  grid-column-start: 4;
}

#button2 {
  grid-column-start: 8;
}

#button3 {
  grid-column-start: 12;
}

#button4 {
  grid-column-start: 16;
}

#button5 {
  grid-column-start: 20;
}

#button6 {
  grid-column-start: 6;
  grid-row-start: 2;

}
#button7 {
  grid-column-start: 10;
  grid-row-start: 2;     
}

#button8 {
  grid-column-start: 14;
  grid-row-start: 2;     
}

#button9 {
  grid-column-start: 18;
  grid-row-start: 2;
}
 
button {
  width: 100px;
  height: 40px;
  background: none;
  border: 4px solid red;
  font-size: 16px;
}
  <div class='container'>
  <button id="button1">1</button>
  <button id="button2">2</button>
  <button id="button3">3</button>
  <button id="button4">4</button>
  <button id="button5">5</button>
  <button id="button6">6</button>
  <button id="button7">7</button>
  <button id="button8">8</button>
  <button id="button9">9</button>
</div>
0 голосов
/ 08 марта 2020

Вы можете использовать margin, чтобы установить интервал:

.container {
  width: 600px;
  border: 1px solid;
}

section {
  display: flex;
  flex-flow: row wrap;
  justify-content: center;
  margin: -8px -8px 0;
}

button {
  width: 100px;
  height: 40px;
  margin: 8px 8px 0;
  border: 4px solid red;
  background: none;
  font-size: 16px;
}
<div class="container">
  <section>
    <button>1</button>
    <button>2</button>
    <button>3</button>
    <button>4</button>
    <button>5</button>
    <button>6</button>
    <button>7</button>
    <button>8</button>
    <button>9</button>
  </section>
</div>
0 голосов
/ 07 марта 2020

Добро пожаловать в чудесный мир CSS -Grid, который идеально подходит для этого. Гораздо меньше кода и проще для понимания, как вы можете видеть ниже.

Управление пространством между столбцами и строками осуществляется с помощью grid-column-gap для разрыва между - как вы уже догадались - столбцами и grid-row- промежуток для промежутка между строками.

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

grid-template-columns: repeat(5, 100px);

Довольно удивительно.

Определенно выглядите в то, что еще вы можете сделать с CSS -Grid и забыть о Flexbox. Это будущее. Для начала проверьте: https://www.w3schools.com/css/css_grid.asp

.container {
  display: grid;
  width: 564px;
  grid-template-columns: auto auto auto auto auto;
  grid-column-gap: 16px;
  grid-row-gap: 8px;
  outline: 1px solid black;
}

button {
  width: 100px;
  height: 40px;
  background: none;
  border: 4px solid red;
  font-size: 16px;
}
<div class='container'>
  <button>1</button>
  <button>2</button>
  <button>3</button>
  <button>4</button>
  <button>5</button>
  <button>6</button>
  <button>7</button>
  <button>8</button>
</div>

Браузер-поддержка CSS -Сетка довольно solid кстати.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...