Flexbox пространство между линией между рядами

Это вопрос, который у меня уже есть решение, но мне интересно, есть ли лучший способ. То, что я хочу, это использовать flexbox, чтобы строки элементов имели ровное пространство между ними и линию между строками. Первый и второй пример во фрагменте ниже достигают этого с помощью :after, но я должен использовать значительное количество CSS, чтобы скрыть его в последнем ряду.

.item:nth-child(4n + 1):nth-last-child(4):after,
.item:nth-child(4n + 1):nth-last-child(4):after,
.item:nth-child(4n + 1):nth-last-child(2):after,
.item:nth-child(4n + 1):nth-last-child(1):after{
  display: none;  
}

Конечно, есть лучший способ (с помощью flexbox) Кто-нибудь знает?

Я пытался использовать границу для каждого элемента, но, очевидно, между ними есть пространство, которое не работает, и тогда мне все равно нужно было бы скрыть его, используя :nth-last-child,

.outer{
  background-color: #ccc;
  margin-bottom: 15px;
}

.wrap{
  overflow: hidden;
  flex: 4;
  justify-content: space-between;
  flex-flow: row wrap;
  width: 80%;
  margin: 0 auto;
  background-color: #cdcdcd;
  display: flex;
}

.item{
  width: 23%;
  padding-bottom: 30px;
  margin-bottom: 30px;
  position: relative;
}
.item2{
  width: 23%;
  padding-bottom: 30px;
  margin-bottom: 30px;
  position: relative;
  border-bottom: 1px solid red;
}
.item:nth-child(4n + 1):after{
  content: "";
  position: absolute;
  left: 0;
  width: 500%;
  bottom: 0;
  border-bottom: 1px solid red;
}
@media (max-width: 768px) {
  .item:nth-child(2n + 1):nth-last-child(2):after,
  .item:nth-child(2n + 1):nth-last-child(1):after{
    display: none;  
  }
  .item{
    width: 43%;
  }
}
@media (min-width: 768px) {
  .item:nth-child(4n + 1):nth-last-child(4):after,
  .item:nth-child(4n + 1):nth-last-child(4):after,
  .item:nth-child(4n + 1):nth-last-child(2):after,
  .item:nth-child(4n + 1):nth-last-child(1):after{
    display: none;  
  }
}
<div class="outer">
  <h3>Working example - 8 Items</h3>
  <div class="wrap">
      <div class="item">Item 1</div>
      <div class="item">Item 2</div>
      <div class="item">Item 3</div>
      <div class="item">Item 4</div>
      <div class="item">Item 5</div>
      <div class="item">Item 6</div>
      <div class="item">Item 7</div>
      <div class="item">Item 8</div>
  </div>
</div>
<div class="outer">
  <h3>Working example - 5 Items</h3>
  <div class="wrap">
      <div class="item">Item 1</div>
      <div class="item">Item 2</div>
      <div class="item">Item 3</div>
      <div class="item">Item 4</div>
      <div class="item">Item 5</div>
  </div>
</div>
<div class="outer">
  <h3>Using normal border</h3>
  <div class="wrap">
      <div class="item2">Item 1</div>
      <div class="item2">Item 2</div>
      <div class="item2">Item 3</div>
      <div class="item2">Item 4</div>
      <div class="item2">Item 5</div>
  </div>
</div>

3 ответа

Решение

Вы могли бы использовать :before и избегать display:none правила:

.outer{
  background-color: #ccc;
  margin-bottom: 15px;
}

.wrap{
  overflow: hidden;/* will hide first row of item:before */
  /* flex: 4; i do not see the use here */
  justify-content: space-between;
  flex-flow: row wrap;
  width: 80%;
  margin: 0 auto;
  background-color: #cdcdcd;
  display: flex;
}

.item{
  width: 23%;
  padding-bottom: 30px;
  margin-bottom: 30px;
  position: relative;
}
.item2{/* just to do it different , don ' t mind that part */
  width: 23%;
  padding : 30px 0;
  margin-bottom: -10px;
  position: relative;
  border-bottom: 1px solid red;
}
.item:nth-child(4n + 1):before{
  content: "";
  position: absolute;
  left: 0;
  width: 500%;
  top: -30px;
  border-bottom: 1px solid red;
}
<div class="outer">
  <h3>Working example - 8 Items</h3>
  <div class="wrap">
      <div class="item">Item 1</div>
      <div class="item">Item 2</div>
      <div class="item">Item 3</div>
      <div class="item">Item 4</div>
      <div class="item">Item 5</div>
      <div class="item">Item 6</div>
      <div class="item">Item 7</div>
      <div class="item">Item 8</div>
  </div>
</div>
<div class="outer">
  <h3>Working example - 5 Items</h3>
  <div class="wrap">
      <div class="item">Item 1</div>
      <div class="item">Item 2</div>
      <div class="item">Item 3</div>
      <div class="item">Item 4</div>
      <div class="item">Item 5</div>
  </div>
</div>
<div class="outer">
  <h3>Using normal border</h3>
  <div class="wrap">
      <div class="item2">Item 1</div>
      <div class="item2">Item 2</div>
      <div class="item2">Item 3</div>
      <div class="item2">Item 4</div>
      <div class="item2">Item 5</div>
  </div>
</div>


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

Вы также можете установить точку останова и использовать каждый элемент, чтобы нарисовать линию

.outer{
  background-color: #ccc;
  margin-bottom: 15px;
}

.wrap{
  overflow: hidden;/* will hide first row of item:before */
  /* flex: 4; i do not see the use here */
  justify-content: space-between;
  flex-flow: row wrap;
  width: 80%;
  margin: 0 auto;
  background-color: #cdcdcd;
  display: flex;
}

.item{
  width: 23%;
  margin: 29px 1% 31px;
  position: relative;
}
.item2{/* just to do it different , don ' t mind that part */
  width: 23%;
  padding : 30px 0;
  margin-bottom: -10px;
  position: relative;
  border-bottom: 1px solid red;
}
.item:before{
  content: "";
  position: absolute;
  left: -20%;
  width: 800%;
  top: -30px;
  border-bottom: 1px solid red;
}
.brkpt .item  {
  min-width:60px;
  max-width:100px;
  background:gray
  }
<div class="outer">
  <h3>Working example - 8 Items</h3>
  <div class="wrap">
      <div class="item">Item 1</div>
      <div class="item">Item 2</div>
      <div class="item">Item 3</div>
      <div class="item">Item 4</div>
      <div class="item">Item 5</div>
      <div class="item">Item 6</div>
      <div class="item">Item 7</div>
      <div class="item">Item 8</div>
  </div>
</div>
<h3>Working example - 16 Items breaking points every 120px average</h3>
  <div class="wrap brkpt">
      <div class="item">Item 1</div>
      <div class="item">Item 2</div>
      <div class="item">Item 3</div>
      <div class="item">Item 4</div>
      <div class="item">Item 5</div>
      <div class="item">Item 6</div>
      <div class="item">Item 7</div>
      <div class="item">Item 8</div>
      <div class="item">Item 1</div>
      <div class="item">Item 2</div>
      <div class="item">Item 3</div>
      <div class="item">Item 4</div>
      <div class="item">Item 5</div>
      <div class="item">Item 6</div>
      <div class="item">Item 7</div>
      <div class="item">Item 8</div>
  </div>
</div>
<div class="outer">
  <h3>Working example - 5 Items</h3>
  <div class="wrap">
      <div class="item">Item 1</div>
      <div class="item">Item 2</div>
      <div class="item">Item 3</div>
      <div class="item">Item 4</div>
      <div class="item">Item 5</div>
  </div>
</div>
<div class="outer">
  <h3>Using normal border</h3>
  <div class="wrap">
      <div class="item2">Item 1</div>
      <div class="item2">Item 2</div>
      <div class="item2">Item 3</div>
      <div class="item2">Item 4</div>
      <div class="item2">Item 5</div>
  </div>
</div>

Я думал о другом пути. Это гибкое решение. Я думаю, что это лучший способ... Чтобы увидеть 4 столбца, вам нужно нажать на кнопку полной страницы

.outer{
  background-color: #ccc;
  margin-bottom: 15px;
}

.wrap{
  overflow: hidden;
  flex: 4;
  justify-content: space-between;
  flex-flow: row wrap;
  width: 80%;
  margin: 0 auto;
  background-color: #cdcdcd;
  display: flex;
}
.full{
  width: 100%;
  background-color: red;
  margin-bottom: 30px;
  height: 1px;
  display: none;
}
@media (max-width: 768px) {
  .visible-small{
    display: block;
  }
}
@media (min-width: 768px) {
  .visible-large{
    display: block;
  }
}
.item{
  width: 23%;
  margin-bottom: 30px;
  position: relative;
}
<div class="outer">
  <h3>Using extra div</h3>
  <div class="wrap">
      <div class="item">Item 1</div>
      <div class="item">Item 2</div>
      <div class="full visible-small"></div>
      <div class="item">Item 3</div>
      <div class="item">Item 4</div>
      <div class="full visible-large visible-small"></div>
      <div class="item">Item 5</div>
  </div>
</div>
<div class="outer">
  <h3>Using extra div</h3>
  <div class="wrap">
      <div class="item">Item 1</div>
      <div class="item">Item 2</div>
      <div class="full visible-small"></div>
      <div class="item">Item 3</div>
      <div class="item">Item 4</div>
      <div class="full visible-large visible-small"></div>
      <div class="item">Item 5</div>
      <div class="item">Item 6</div>
      <div class="full visible-small"></div>
      <div class="item">Item 7</div>
      <div class="item">Item 8</div>
      <div class="full visible-large visible-small"></div>
      <div class="item">Item 9</div>
  </div>
</div>

Как я уже говорил, в небольших устройствах у вас будут серьезные проблемы с этим методом. Я предлагаю вам использовать это изображение:

изображение на заднем плане

Как bcackground изображение всего меню (<div class="wrap"), Конечно, с некоторыми изменениями, связанными с высотой пунктов меню.

.wrap{
   background-image: url(IMAGE-URL);
   background-repeat: repeat;
 }
Другие вопросы по тегам