Вложенная сетка с использованием flexbox и до взлома - PullRequest
0 голосов
/ 21 октября 2019

Может кто-нибудь объяснить, как работает этот пример?

  1. Почему там используется .content::before?
  2. Почему, если я раскомментирую 19-ю строку (/* align-items: center; */), все только что оборвалось?

PS:тот же код в коде ручки

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

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

html, body {
  width: 100%;
  height: 100%;
  font: 1rem/1.5 sans-serif;
}

.container {
  display: flex;
/*  align-items: center; */
  justify-content: center;
  height: 100%;
  max-width: 960px;
  margin: auto;
}

.content {
  display: flex;
	flex-flow: column wrap;	
	align-content: space-between;
  position: relative;
  background-color: gold;
}

.content::before, .content::after {
  content: '';
  flex-basis: 100%;
  width: 0;
  order: 2;
  position: relative;
}

.content::after {
  display: none;
}

.content > * {
  flex-grow: 1;
  flex-shrink: 1;
  min-height: 0.0033rem;
}

.a {
  width: calc(100% / 3 * 2 + 0.0033rem);
  order: 1;
}

.b {
  width: calc(100%  / 3 * 1 + 0.0033rem);
  order: 2;
}

.c {
  width:  calc(100% / 3  * 1 + 0.0033rem); 
  order: 2;
}

.a { background: red;  }
.b { background: green;  }
.c { background: blue; }

.a, .b, .c {
  padding: 1rem;
  min-height: 120px;
}
<div class="container">
  <div class="content">
    <div class="a">Lorem ipsum dolor sit amet consectetur adipisicing elit. </div>
    <div class="b">Lorem ipsum dolor sit amet consectetur adipisicing elit.</div>
    <div class="c">Lorem ipsum dolor sit amet consectetur adipisicing elit. </div>
  </div>
</div>

1 Ответ

1 голос
/ 21 октября 2019

::before псевдоэлемент

Псевдоэлементы, примененные к гибкому контейнеру, считаются гибкими элементами ( MDN ).

Следовательно, элемент ::beforeявляется гибким элементом в флекс-контейнере .content. Если бы псевдо ::after не было установлено в display: none, оно также было бы гибким элементом .content.

Короче говоря, у гибкого контейнера .content есть четыре элемента, и псевдо установленодо order: 2. Таким образом, элементы упорядочены примерно так:

<div class="content">
    <div class="a">Lorem ipsum dolor sit amet consectetur adipisicing elit.</div>
    <css pseudo element></css pseudo element>
    <div class="b">Lorem ipsum dolor sit amet consectetur adipisicing elit.</div>
    <div class="c">Lorem ipsum dolor sit amet consectetur adipisicing elit.</div>
</div>

Псевдо установлен на flex-basis: 100%.

.content::before {
  content: '';
  flex-basis: 100%;
  width: 0;
  order: 2;
  position: relative;
}

В контейнере в направлении столбца (то есть, .content),это эквивалентно height: 100%.

Поскольку для контейнера также установлено значение wrap, элемент с height: 100% занимает полный столбец и переносит последующие элементы в новый столбец.

.container {
  display: flex;
  /* align-items: center; */
  justify-content: center;
  height: 100%;
  max-width: 960px;
  margin: auto;
}

.content {
  display: flex;
  flex-flow: column wrap;
  align-content: space-between;
  position: relative;
  background-color: gold;
}

.content::before,
.content::after {
  content: '';
  flex-basis: 100%;
  width: 0;
  order: 2;
  position: relative;
}

.content::after {
  display: none;
}

.content>* {
  flex-grow: 1;
  flex-shrink: 1;
  min-height: 0.0033rem;
}

.a {
  width: calc(100% / 3 * 2 + 0.0033rem);
  order: 1;
}

.b {
  width: calc(100% / 3 * 1 + 0.0033rem);
  order: 2;
}

.c {
  width: calc(100% / 3 * 1 + 0.0033rem);
  order: 2;
}

.a {
  background: red;
}

.b {
  background: green;
}

.c {
  background: blue;
}

.a,
.b,
.c {
  padding: 1rem;
  min-height: 120px;
}

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

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

html,
body {
  width: 100%;
  height: 100%;
  font: 1rem/1.5 sans-serif;
}
<div class="container">
  <div class="content">
    <div class="a">Lorem ipsum dolor sit amet consectetur adipisicing elit. </div>
    <div class="b">Lorem ipsum dolor sit amet consectetur adipisicing elit.</div>
    <div class="c">Lorem ipsum dolor sit amet consectetur adipisicing elit. </div>
  </div>
</div>

Для элементов DOM установлено значение min-height: 120px ...

.a, .b, .c {
  min-height: 120px;
}

... но они потребляют всю высоту вконтейнер, потому что они также установлены на flex-grow: 1:

.content > * {
  flex-grow: 1;
}

Псевдостолбец полностью невидим, потому что он установлен на width: 0.

Если, скажем, вы добавили ширину илисодержимое, столбец, созданный псевдо, станет видимым:

.container {
  display: flex;
  /* align-items: center; */
  justify-content: center;
  height: 100%;
  max-width: 960px;
  margin: auto;
}

.content {
  display: flex;
  flex-flow: column wrap;
  align-content: space-between;
  position: relative;
  background-color: gold;
}

.content::before,
.content::after {
  content: 'X';
  flex-basis: 100%;
  /* width: 0; */
  order: 2;
  position: relative;
}

.content::after {
  display: none;
}

.content>* {
  flex-grow: 1;
  flex-shrink: 1;
  min-height: 0.0033rem;
}

.a {
  width: calc(100% / 3 * 2 + 0.0033rem);
  order: 1;
}

.b {
  width: calc(100% / 3 * 1 + 0.0033rem);
  order: 2;
}

.c {
  width: calc(100% / 3 * 1 + 0.0033rem);
  order: 2;
}

.a {
  background: red;
}

.b {
  background: green;
}

.c {
  background: blue;
}

.a,
.b,
.c {
  padding: 1rem;
  min-height: 120px;
}

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

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

html,
body {
  width: 100%;
  height: 100%;
  font: 1rem/1.5 sans-serif;
}
<div class="container">
  <div class="content">
    <div class="a">Lorem ipsum dolor sit amet consectetur adipisicing elit. </div>
    <div class="b">Lorem ipsum dolor sit amet consectetur adipisicing elit.</div>
    <div class="c">Lorem ipsum dolor sit amet consectetur adipisicing elit. </div>
  </div>
</div>

align-items: center

Компоновка, как описано выше, с отключенным align-items: center в основном гибком контейнере (.container), позволяет обернуть элементы .b & .c, поскольку псевдоэлемент ::before занимает все пространство в предыдущем столбце с flex-basis: 100%. В окне просмотра задается ограничение высоты и точка разрыва для переноса.

Когда вы включаете align-items: center, контейнер (.content) центрируется по вертикали через распределение свободного пространства. Больше нет ограничения по высоте. Там нет точки останова, говорящей предметы обернуть. Таким образом, все элементы (включая псевдо) остаются в одном столбце.

.container {
  display: flex;
  align-items: center;  /* enabled */
  justify-content: center;
  height: 100%;
  max-width: 960px;
  margin: auto;
}

.content {
  display: flex;
  flex-flow: column wrap;
  align-content: space-between;
  position: relative;
  background-color: gold;
}

.content::before,
.content::after {
  content: 'X';
  flex-basis: 100%;
  /* width: 0; */
  order: 2;
  position: relative;
}

.content::after {
  display: none;
}

.content>* {
  flex-grow: 1;
  flex-shrink: 1;
  min-height: 0.0033rem;
}

.a {
  width: calc(100% / 3 * 2 + 0.0033rem);
  order: 1;
}

.b {
  width: calc(100% / 3 * 1 + 0.0033rem);
  order: 2;
}

.c {
  width: calc(100% / 3 * 1 + 0.0033rem);
  order: 2;
}

.a {
  background: red;
}

.b {
  background: green;
}

.c {
  background: blue;
}

.a,
.b,
.c {
  padding: 1rem;
  min-height: 120px;
}

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

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

html,
body {
  width: 100%;
  height: 100%;
  font: 1rem/1.5 sans-serif;
}
<div class="container">
  <div class="content">
    <div class="a">Lorem ipsum dolor sit amet consectetur adipisicing elit. </div>
    <div class="b">Lorem ipsum dolor sit amet consectetur adipisicing elit.</div>
    <div class="c">Lorem ipsum dolor sit amet consectetur adipisicing elit. </div>
  </div>
</div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...