CSS Grid не будет обертывать дочерние элементы при установке grid-row

CODEPEN

Фон:

Я экспериментирую с Grid CSS и пытаюсь получить этот макет, который в настоящее время реализован для масштабирования.

Ожидаемый макет  введите описание изображения здесь

Проблема: на рабочем столе заголовок элемента должен иметь ширину 8 столбцов, и если я не добавлю строки сетки к element-header и element, то <div class="element">1</div> заполнит следующий за element-header. Теперь, если я добавлю grid-rows, мой element больше не будет переноситься.

Текущий макет (проблема)  введите описание изображения здесь  введите описание изображения здесь

Вопрос Как я могу исправить свою сетку, чтобы она соответствовала приведенному выше снимку экрана с "ожидаемым макетом"? т.е. .element будет переноситься и начинаться со второй строки сетки

Код:

HTML:

<section class="section">
  <div class="container">
    <div class="samba-grid">
      <div class="element-header"><h1>I am a lot of header text that only goes 8 columsn wide</h1></div>
      <div class="element">1</div>
      <div class="element">2</div>
      <div class="element">3</div>
      <div class="element">4</div>     
    </div>
  </div>
</section>

CSS:

.section {
  width: 100%;
  display: block;
  background: red;
  box-sizing: border-box;
  padding: 40px 24px;

  @media screen and (min-width: 600px) and (max-width: 1139px) {
    background: orange;
    padding: 56px 48px;
  }

  @media screen and (min-width: 1140px) {
    padding: 64px 48px;
    background: green;
  }
}

.container {
  margin: 0 auto;
  background: rgba(244,244,244, .25);
  max-width: 599px;

  @media screen and (min-width: 600px) and (max-width: 1139px) {
    max-width: 1039px;
    background: rgba(244,244,244, .25);
  }

  @media screen and (min-width: 1140px) {
    max-width: 1032px;
    background: rgba(244,244,244, .25);
  }
}

.samba-grid {
  display: grid;
  background: inherit;
  width: 100%;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: 'auto auto';
  grid-gap: 24px;

  @media screen and (min-width: 600px) and (max-width: 1139px) {
    grid-template-columns: repeat(6, 1fr);
    grid-gap: 48px;
  }

  @media screen and (min-width: 1140px) {
    grid-template-columns: repeat(12, 1fr);
    grid-gap: 48px;
  }
}

h1 {
  font-size: 52px;
}
.element-header {
  grid-row: 1;
  grid-column: span 8; // SET THIS TO "span 12" TO SEE EXPECTED BEHAVIOR
}

.element {
  display: grid; // important to do this.
  background: rgba(0,0,0,.3);
  grid-column: span 3;
  grid-row: 2; // REMOVE THIS TO SEE EXPECTED BEHAVIOR

  @media screen and (min-width: 600px) and (max-width: 1139px) {
    grid-column: span 3;
  }

  @media screen and (min-width: 1140px) {
    grid-column: span 4;
  }
}

person Armeen Harwood    schedule 13.03.2019    source источник
comment
Можете ли вы добавить изображения, вызывающие проблему, в пример CodePen?   -  person Andy Hoffman    schedule 14.03.2019
comment
@AndyHoffman готов @!   -  person Armeen Harwood    schedule 14.03.2019
comment
Я добавил span 12 там, где вы проинструктировали, а также закомментировал grid-row: 2, но не могу воспроизвести проблему, которую вы описываете. Изображения переходят вниз, но не вверх рядом с заголовком. Можете ли вы создать вилку Pen и предоставить ссылку на вилку с точной проблемой?   -  person Andy Hoffman    schedule 14.03.2019
comment
Да, извините, это сложная проблема для описания. Игнорируйте эти комментарии. Вот что я хочу: я хочу, чтобы изображения: начинались со второй строки и заканчивались, и я также хочу, чтобы заголовок был span 8   -  person Armeen Harwood    schedule 14.03.2019


Ответы (4)


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

Вот упрощенный пример:

.samba-grid {
  display: grid;
  background: inherit;
  width: 100%;
  grid-template-columns: repeat(12, 1fr);
  grid-gap: 24px;
  border:1px solid;
}

.element-header {
  grid-row: 1;
  grid-column: 1/-1;
}
.element-header > h1 {
  /*we take 8 colmuns (without gaps) + 7 gaps*/
  width:calc(8*(100% - 11*24px)/12 + 7*24px);
  background:red;
  margin:0;
}
.samba-grid > span {
  height:50px;
  grid-column: span 2;
  background:green;
}
<div class="samba-grid">
  <div class="element-header">
    <h1>I am a lot of header text that only goes 8 columsn wide</h1>
  </div>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
</div>

Чтобы сделать его более динамичным и простым в обращении, вы можете рассмотреть переменные CSS:

:root {
  --grid:12;
  --gap:24px;
}

.samba-grid {
  display: grid;
  background: inherit;
  width: 100%;
  grid-template-columns: repeat(var(--grid), 1fr);
  grid-gap: var(--gap);
  border:1px solid;
}

.element-header {
  grid-row: 1;
  grid-column: 1/-1;
  --grid-column:8; /*simply adjust this value to control the column*/
}
.element-header > h1 {
  width:calc(var(--grid-column)*(100% - (var(--grid) - 1)*var(--gap))/var(--grid) + calc(var(--grid-column) - 1)*var(--gap));
  background:red;
  margin:0;
}
.samba-grid > span {
  height:50px;
  grid-column: span 2;
  background:green;
}
<div class="samba-grid">
  <div class="element-header">
    <h1>I am a lot of header text that only goes 8 columsn wide</h1>
  </div>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
</div>

Другая идея - рассмотреть скрытый элемент, который займет оставшееся пространство первой строки:

.samba-grid {
  display: grid;
  background: inherit;
  width: 100%;
  grid-template-columns: repeat(12, 1fr);
  grid-gap: 24px;
  border:1px solid;
}

.element-header {
  grid-row: 1;
  grid-column: span 8;
  background:red;
  order:-2;
}

.samba-grid:before {
 content:"";
 order:-1;
 grid-column: span 4;
 background:blue;
 height:2px;
}

.samba-grid > span {
  height:50px;
  grid-column: span 2;
  background:green;
}
<div class="samba-grid">
  <div class="element-header">
    <h1>I am a lot of header text that only goes 8 columsn wide</h1>
  </div>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
</div>


Кстати, установка grid-row: 2 не означает начинать со второй строки, но означает, что находиться внутри второй строки, что создает проблему.

person Temani Afif    schedule 13.03.2019
comment
Итак, на высоком уровне ваше решение: 1 - создать оболочку 2 - использовать calc для вычисления подсетки - person Armeen Harwood; 14.03.2019
comment
@MatthewHarwood да, в основном, так вы заблокируете первую строку для своего элемента и внутри вы уменьшите высоту, как хотите. другая идея - использовать скрытый элемент, я отредактирую, чтобы добавить его - person Temani Afif; 14.03.2019
comment
Должен ли я использовать grid-row с учетом этого макета? Я чувствую, что это приведет к той же ошибке. Скрытый блок становится немного громоздким еще и потому, что на планшете и мобильном телефоне заголовок полностью залит. - person Armeen Harwood; 14.03.2019
comment
@MatthewHarwood в этом случае вам больше не нужна строка сетки, и скрытый элемент не будет проблемой, но вы должны изменить его, как и с заголовком на небольшой осыпи, это как если бы вы имели дело с дополнительным элементом (я отредактирован, чтобы включить это) - person Temani Afif; 14.03.2019
comment
Ах, порядок и: после тоже супер умно! Мне до сих пор нравятся эти ответы, но я все еще не совсем понимаю, почему логика строки сетки нарушает предполагаемый макет. Я чувствую, что интуитивно сетка-row имеет наибольший смысл, но похоже, что она все еще не работает - person Armeen Harwood; 14.03.2019
comment
@MatthewHarwood проблема не в самой строке сетки, а в том, что у вас все еще есть место справа, которое может содержать элемент ... строка сетки может предотвратить это, но это также изменит поведение сетки, создавая некоторую проблему. В вашем случае вы заставляете их быть во втором ряду (все) - person Temani Afif; 14.03.2019
comment
@MatthewHarwood grid-row не делает то, что вы ожидаете (начиная со второй строки), но помещает их во вторую строку - person Temani Afif; 14.03.2019
comment
Хорошо, это имеет смысл, но почему, когда вы указываете строку без сетки, она естественным образом переносится? Создает новую строку? Можно ли установить начало строки сетки, но сделать так, чтобы конец строки сетки наследовал поведение автоматического переноса по умолчанию? - person Armeen Harwood; 14.03.2019
comment
@MatthewHarwood, это называется неявной сеткой, если ничего не указано, алгоритм сетки разместит элемент, используя определенную логику. но если вы укажете такие вещи, как grid-row, тогда он станет явной сеткой, и браузер должен следовать инструкциям. Мы можем контролировать перенос, но не уверены, сможем ли мы контролировать , когда он должен переноситься (попытаемся подумать об этом) - person Temani Afif; 14.03.2019
comment
Большое спасибо за это знание. Я оставлю эту тему открытой, чтобы получить еще несколько ответов. Но я узнал больше в этой ветке, чем прочитал все статьи за последние несколько месяцев. Кроме того, я знаю, что это натянуто, но мне бы очень понравился метод явной установки неявной сетки;) да? - person Armeen Harwood; 14.03.2019
comment
@MatthewHarwood Я сделал еще одно изменение, включив переменную CSS для первого примера. - person Temani Afif; 14.03.2019
comment
Пометить это правильно, но было бы здорово, если бы у вас когда-нибудь были другие интересные идеи о том, как сбросить implict grid - person Armeen Harwood; 14.03.2019
comment
@MatthewHarwood Да, я имею это в виду;) вернусь, если найду классное решение ... На самом деле вся идея так или иначе связана с хаками - person Temani Afif; 14.03.2019
comment
Если у тебя есть минутка, я нанесу тебе еще один удар. stackoverflow.com/questions/55175808/ Изучение CSS Grid намного сложнее, чем float и Flex - person Armeen Harwood; 15.03.2019

Выньте жатку из контейнера решетки. Сделайте его отдельным элементом уровня блока.

Ниже разместите сетку-контейнер только с изображениями.

person Michael Benjamin    schedule 13.03.2019
comment
Учитывая ваше решение, я по сути заставляю строки на основе DOM вместо CSS? Я доверяю твоему суждению, основанному на твоих 154 тысячах баллов, так что я определенно использую / понимаю Grid CSS неправильно, а? У вас есть что еще добавить, почему я не должен / не могу использовать grid-row? - person Armeen Harwood; 14.03.2019
comment
Я ценю ваше доверие ко мне, но мне нужно будет вернуться к этому позже, так как я не могу много тестировать с мобильного устройства. - person Michael Benjamin; 14.03.2019
comment
Вернись скорее, пожалуйста! - person Armeen Harwood; 14.03.2019
comment
Здесь также есть другие отличные эксперты по сетке / гибкости. Надеюсь, теперь они могут вам помочь. - person Michael Benjamin; 14.03.2019

Я приказываю .element-header всегда охватывать максимальное количество доступных столбцов. Для h1 я добавил правило в более крупный запрос @media, которое поддерживает его правильное масштабирование (8 из 12 столбцов). Кроме того, я закомментировал .grid-row: 2.

.element-header {
  grid-column-start: 1;
  grid-column-end: -1;
}

h1 {
  …  
  @media screen and (min-width: 1140px) {
    width: calc(80% / 120 * 100); /* 8 of 12 columns */
 }

Демо (с использованием скомпилированного CSS)

.section {
  width: 100%;
  display: block;
  background: red;
  box-sizing: border-box;
  padding: 40px 24px;
}
@media screen and (min-width: 600px) and (max-width: 1139px) {
  .section {
    background: orange;
    padding: 56px 48px;
  }
}
@media screen and (min-width: 1140px) {
  .section {
    padding: 64px 48px;
    background: green;
  }
}

.container {
  margin: 0 auto;
  background: rgba(244, 244, 244, 0.25);
  max-width: 599px;
}
@media screen and (min-width: 600px) and (max-width: 1139px) {
  .container {
    max-width: 1039px;
    background: rgba(244, 244, 244, 0.25);
  }
}
@media screen and (min-width: 1140px) {
  .container {
    max-width: 1032px;
    background: rgba(244, 244, 244, 0.25);
  }
}

.samba-grid {
  display: grid;
  background: inherit;
  width: 100%;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: 'auto auto';
  grid-gap: 24px;
}
@media screen and (min-width: 600px) and (max-width: 1139px) {
  .samba-grid {
    grid-template-columns: repeat(6, 1fr);
    grid-gap: 48px;
  }
}
@media screen and (min-width: 1140px) {
  .samba-grid {
    grid-template-columns: repeat(12, 1fr);
    grid-gap: 48px;
  }
}

h1 {
  font-size: 52px;
}
@media screen and (min-width: 1140px) {
  h1 {
    width: calc(80% / 120 * 100);
  }
}

.element-header {
  grid-row: 1;
  grid-column-start: 1;
  grid-column-end: -1;
}

.element {
  display: grid;
  background: rgba(0, 0, 0, 0.3);
  grid-column: span 3;
}
@media screen and (min-width: 600px) and (max-width: 1139px) {
  .element {
    grid-column: span 3;
  }
}
@media screen and (min-width: 1140px) {
  .element {
    grid-column: span 4;
  }
}

.element img {
  width: 100%;
}
<section class="section">
  <div class="container">
    <div class="samba-grid">
      <div class="element-header"><h1>I am a lot of header text that only goes 8 columns wide</h1></div>
      <div class="element"><img src="https://placebear.com/160/90" alt=""></div>
      <div class="element"><img src="https://placebear.com/160/90" alt=""></div>
      <div class="element"><img src="https://placebear.com/160/90" alt=""></div>
      <div class="element"><img src="https://placebear.com/160/90" alt=""></div>     
    </div>
  </div>
</section>

демонстрация CodePen

person Andy Hoffman    schedule 13.03.2019
comment
Классный трюк! но я хочу, чтобы заголовок элемента перешел в 8-й столбец, а элементы начинались со второй строки и переносились! Мне нравится внимание, которое уделяется этому вопросу, я так много учусь! - person Armeen Harwood; 14.03.2019
comment
Привет, Энди, я, наверное, сделаю это временно. Тем не менее, посмотрите наш разговор со мной и Темани. Последняя явная строка сетки с неявным поведением сетки была бы круто, а? Любые идеи. - person Armeen Harwood; 14.03.2019
comment
@MatthewHarwood Ах, это было бы очень полезно. В CSS по-прежнему отсутствует множество функций. У нас даже нет способа получить предыдущий элемент. - person Andy Hoffman; 14.03.2019

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

HTML

<div class="element-header"><h1>I am a lot of header text that only goes 8 columsn wide</h1></div>
<div class='filler'></div>
<div class="element"><img src="https://placebear.com/160/90" alt=""></div>

CSS

.filler {
  display: none;

  @media screen and (min-width: 1140px) {
    grid-column: 9 / span 4;
    display: initial;
  }
}

Таким образом, у вас будет что разместить на этом пространстве, и алгоритм автоматического размещения не использует это.

Вы можете просто скрыть, если на меньшем разрешении.

person arieljuod    schedule 14.03.2019
comment
Извини, я этого не видел - person arieljuod; 14.03.2019