Как создать "рухнувшие" границы вокруг элементов гибкости и их контейнера?

У меня есть следующий макет:

#limited-width {
  width: 100%;
  max-width: 200px;
  margin: 0 auto;
  font-size: 18px;
}
ul {
  display: flex;
  flex-flow: row wrap;
  list-style: none;
  padding: 0;
  margin: 20px;
}
ul > li {
  display: block;
  text-align: center;
  flex: 1 0 auto;
  max-width: 100%;
  box-sizing: border-box;
  margin: 0;
  padding: 4px 7px;
  border: 2px solid rgba(0,0,0,.3);
  background-color: rgba(0,0,0,.03);
}
<div id="limited-width">
  <ul>
    <li>Apple</li>
    <li>Orange</li>
    <li>Pineapple</li>
    <li>Banana</li>
    <li>Tomato</li>
    <li>Pear</li>
    <li>Lemon</li>
  </ul>
</div>

Ответ 1

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

Ориентация границы родительского ребенка

Вам нужно определить границу следующим образом:

ul, ul > li {
  border-style: solid;
  border-color: rgba(0,0,0,.3);
}
ul      { border-width: 2px  0   0  2px }
ul > li { border-width:  0  2px 2px  0  }

Ключевым здесь является свойство border-width:

  • В контейнере значения для top и left устанавливаются в нужный размер, а для right и bottom установлены 0
  • В элементах значения для right и bottom установлены на нужный размер, а для top и left установлены 0

Таким образом, границы будут складываться таким образом, что они образуют красиво обрушившуюся, согласованную границу вокруг элементов и контейнера.

:hover { border-color: red }
#limited-width {
  width: 100%;
  max-width: 200px;
  margin: 0 auto;
  font-size: 18px;
}
ul, ul > li {
  border-style: solid;
  border-color: rgba(0,0,0,.3);
}
ul {
  display: flex;
  flex-flow: row wrap;
  list-style: none;
  padding: 0;
  margin: 20px;
  border-width: 2px 0 0 2px;
}
ul > li {
  display: block;
  text-align: center;
  flex: 1 0 auto;
  max-width: 100%;
  box-sizing: border-box;
  margin: 0;
  padding: 4px 7px;
  border-width: 0 2px 2px 0;
  background-color: rgba(0,0,0,.03);
}
<div id="limited-width">
  <ul>
    <li>Apple</li>
    <li>Orange</li>
    <li>Pineapple</li>
    <li>Banana</li>
    <li>Tomato</li>
    <li>Pear</li>
    <li>Lemon</li>
  </ul>
</div>

Ответ 2

У меня был такой же вопрос, но я сделал это (см. Демо ниже). Я добавляю к каждому блоку отрицательный "margin-left" и отрицательный "margin-top", равный ширине границы. Затем я добавляю в контейнер те же, но положительные "padding-left" и "padding-top", чтобы компенсировать смещение. Woo-а-ля! Теперь мы получаем "рушившиеся" границы вокруг элементов гибкости и их контейнера.

.catalog-list {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  padding-top: 1px;
  padding-left: 1px;
  box-sizing: border-box;
  max-width: 800px;
  margin: auto;
  box-shadow: inset 0 0 0 1px #8c8c8c;
}

.catalog-item {
  width: calc(25% + 1px);
  margin-top: -1px;
  margin-left: -1px;
  padding: 20px;
  border: 1px solid #8c8c8c;
  box-sizing: border-box;
  transition: all 0.2s;
  box-sizing: border-box;
}

.catalog-item:hover {
  border-color: transparent;
  box-shadow: 0 0 15px -2px #8c8c8c;
}
<div class="catalog-list">
  <div class="catalog-item"></div>
  <div class="catalog-item"></div>
  <div class="catalog-item"></div>
  <div class="catalog-item"></div>
  <div class="catalog-item"></div>
  <div class="catalog-item"></div>
</div>

Ответ 3

В моем случае границы должны быть 1px, что делает его более сложным. Я нашел решение на https://codepen.io/Hawkun/pen/rsIEp/, которое использует тени для имитации границ, что на самом деле работает хорошо.

Вот код в действии. Он не использует flexbox, но если вы применяете тень к своему гибкому контенту, вам хорошо идти.

body {
  font-family: sans-serif;
  background-color: #eee;
  padding: 20px;
}

.info {
  color: darkred;
  font-weight: bolder;
}

.container {
  background-color: white;
  float: left; /* Makes the container height the same as its children. */
  padding: 10px;
  margin-bottom: 40px;
}

.container div {
  padding: 20px;
  float: left;
  background-color: #def;
  
  
  /* And here comed the trick: */

  box-shadow: 
1px 0 0 0 #888, 
0 1px 0 0 #888, 
1px 1px 0 0 #888,   /* Just to fix the corner */
1px 0 0 0 #888 inset, 
0 1px 0 0 #888 inset;

}

#container1 {
  width: 100%;
}

#container2 {
  width: 50%;
}

#container2 div {
  width: 70%;
}
<p>The first container:</p>

<div id="container1" class="container">
  <div>Hello, this is the first floated div</div>
  <div>And this is the second</div>
  <div>And finally the third one</div>
</div>

<p>The second container:</p>

<div id="container2" class="container">
  <div>Hello, this is the first floated div</div>
  <div>And this is the second</div>
  <div>And finally the third one</div>
</div>

Ответ 4

Здесь другая идея, которую я имел, будет держать границы "рушится", когда гибкие коробки обертываются. Он использует цвет фона для верхнего и левого и границ для правой и нижней. Возможно, было бы сложно заставить его работать над фоновым изображением.

.container {
  display: flex;
  flex-flow: row wrap;
  border-style: solid;
  border-width: 0 2px 2px 0;
  border-color: black;
  background-color: black;
}

.container>div {
  flex: 1 0 auto;
  margin: 2px 0 0 2px;
  background-color: white;
}
<div class="container">
  <div>Eh?</div>
  <div>Bee.</div>
  <div>This div contains a whole bunch of stuff.</div>
  <div>This div contains a whole bunch of stuff.</div>
  <div>This div contains a whole bunch of stuff.</div>
  <div>Sea!</div>
  <div>This div contains a whole bunch of stuff.</div>
  <div>This div contains a whole bunch of stuff.</div>
  <div>This div contains a whole bunch of stuff.</div>
</div>

Ответ 5

С помощью :last-of-type вы можете "свернуть" последнюю границу. Возможно добавление box-sizing:border-box;