Запретить содержимое от расширения элементов сетки

153

TL; DR: Есть ли что-то похожее table-layout: fixedна CSS-сетки?


Я попытался создать календарь на год с большой сеткой 4x3 для месяцев и вложенными сетками 7x6 для дней.

Календарь должен заполнить страницу, поэтому контейнер годовой сетки получает ширину и высоту 100% каждый.

.year-grid {
  width: 100%;
  height: 100%;

  display: grid;
  grid-template: repeat(3, 1fr) / repeat(4, 1fr);
}

.month-grid {
  display: grid;
  grid-template: repeat(6, 1fr) / repeat(7, 1fr);
}

Вот рабочий пример: https://codepen.io/loilo/full/ryXLpO/

Для простоты, каждый месяц в этой ручке имеет 31 день и начинается в понедельник.

Я также выбрал смехотворно маленький размер шрифта, чтобы продемонстрировать проблему:

Элементы сетки (= дневные ячейки) довольно сжаты, поскольку на странице их несколько сотен. И как только метки чисел дня станут слишком большими (не стесняйтесь поиграть с размером шрифта на ручке с помощью кнопок в левом верхнем углу), сетка просто увеличится в размере и превысит размер тела страницы.

Есть ли способ предотвратить такое поведение?

Сначала я объявил, что моя годовая сетка имеет ширину и высоту 100%, поэтому, возможно, с этого и стоит начать, но я не смог найти какие-либо свойства CSS, связанные с сеткой, которые бы соответствовали этой потребности.

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

LoiLo
источник
Что вы хотите, чтобы вместо этого произошло? Шрифт в каждой ячейке может быть любого размера, и это никогда не приводит к увеличению размера ячейки сетки?
Майкл Кокер
1
Именно. В основном это более удобный способ, если бы я установил размеры элементов сетки в соответствии с процентными значениями, а не дробями.
Лойло,
Я в основном ищу сетевую верстку макета таблицы: исправлено (см .: codepen.io/loilo/pen/dvxpvq?editors=1100 )
Loilo
7
Это самая большая боль во всей спецификации CSS Grid. Они должны быть установкой, где области сетки не могут выходить за пределы размеров любого из родительских контейнеров сетки! Это кошмар для глубоко вложенных сеточных структур.
Лонни Бест

Ответы:

263

По умолчанию элемент сетки не может быть меньше размера его содержимого.

Элементы сетки имеют начальный размер min-width: autoи min-height: auto.

Вы можете переопределить это поведение, устанавливая элементы сетки в min-width: 0, min-height: 0или overflowс любым значением, кроме visible.

Из спецификации:

6.6. Автоматический минимальный размер элементов сетки

Для того, чтобы обеспечить более разумный минимальный размер по умолчанию для элементов сетки, Данная спецификация определяет , что autoзначение min-width/ min-heightтакже относится автоматический размер минимальной в указанной оси элементов сетки , чьи overflowэто visible. (Эффект аналогичен автоматическому минимальному размеру наложенных элементов)

Вот более подробное объяснение, охватывающее гибкие элементы, но оно также применимо и к элементам сетки:

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


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

.month-grid {
  display: grid;
  grid-template: repeat(6, 1fr) / repeat(7, 1fr);
  background: #fff;
  grid-gap: 2px;
  min-height: 0;  /* NEW */
  min-width: 0;   /* NEW; needed for Firefox */
}

.day-item {
  padding: 10px;
  background: #DFE7E7;
  overflow: hidden;  /* NEW */
  min-width: 0;      /* NEW; needed for Firefox */
}

пересмотренный кодекс


1fr против minmax(0, 1fr)

Решение выше работает на уровне элемента сетки. Для решения на уровне контейнера, см. Этот пост:

Майкл Бенджамин
источник
3
Вот это да. Это увлекательно и интересно одновременно, и я бы точно не придумал это, просто попробовав. Вы только что посмотрели спецификацию для этой информации? Потому что, не зная, что гуглить, это то, что я пробовал раньше, но в итоге я прочитал не тот раздел (после того, как решил неправильную причину проблемы).
Лойло
1
Я столкнулся с этой проблемой раньше с гибкими предметами . Учитывая, что между элементами flex и grid существует много общего, я решил, что поведение может быть таким же, и сосредоточился на этом разделе спецификации.
Майкл Бенджамин
1
Он фиксирует высоту, но продолжает расти в горизонтальном направлении, min-width: 0;не помогает. Я что-то упускаю?
пользователь
2
Для вложенных сеток мы должны применить это ко всем уровням. Но я действительно пришел сюда, чтобы выразить свою благодарность и поблагодарить вас.
Звоните
2
@PragyAgarwal .. stackoverflow.com/users/3597276/michael-b?tab=answers :-)
Майкл Бенджамин,
57

Предыдущий ответ довольно хорошо, но я также хотел бы отметить , что это фиксированный эквивалент макета для сетей, вам просто нужно написать minmax(0, 1fr)вместо того , чтобы 1frкак вашего размера трека.

FremyCompany
источник
6
Я рекомендую этот подход по сравнению с предыдущим, принятым ответом.
Тьерри Прост
Хотя это работает, я немного не понимаю ... Не могли бы вы объяснить, почему это работает? Что делает minmax (0, 1fr)? Должно ли это быть не всегда 0? Я в замешательстве :(
BAERUS
2
minmax(0, 1fr)работает, потому что 1frэто действительно сокращение minmax(auto,1fr), что не является правильным значением для исходного вопроса.
Микко Ранталайнен
Для получения дополнительной информации см. Github.com/w3c/csswg-drafts/issues/1777
Микко Ранталайнен,
1

Существующие ответы решают большинство случаев. Однако я натолкнулся на случай, когда мне нужно было содержимое ячейки сетки overflow: visible. Я решил это с помощью абсолютного позиционирования внутри оболочки (не идеальный, но лучший из известных мне), вот так:


.month-grid {
  display: grid;
  grid-template: repeat(6, 1fr) / repeat(7, 1fr);
  background: #fff;
  grid-gap: 2px;  
}

.day-item-wrapper {
  position: relative;
}

.day-item {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 10px;

  background: rgba(0,0,0,0.1);
}

https://codepen.io/bjnsn/pen/vYYVPZv

bjnsn
источник
0

проще будет установить максимальную ширину элемента сетки следующим образом:

//for the container
.gridContainer{
    display: grid;
    grids-templates-column: repeat (12, 1fr);
 }

 //for the grid item
 .gridItem{
       max-width: 100%;
       grid-column: span 4  //4 can be any number from1-12 as we specified in the grid template
  }
Педро JR
источник
Я немного сбит с толку, если честно. Ваш код совсем не похож на исходный вопрос, и применение max-width: 100% к элементам сетки (вместо min-width: 0 из принятого решения) не решит проблему ...
Лойло
max-width предотвратит перенастройку относительно его дочерней ширины
Pedro JR
Я попытался воспроизвести ваш код, и он действительно работает, но, похоже, это не из-за max-width: 100%, а из-за grid-столбца: span 4; без определения начального столбца. Определите начальный столбец (например, используя grid-column: 1 / span 4;), и он снова нарушит макет. (Это поведение довольно странно, но я уверен, что где-то в спецификации есть угол, где это определено.)
Лойло,
хорошо, звучит хорошо. но ты пока не считаешь меня нужным
Pedro JR
Откровенно говоря: 1. Это была решенная проблема в течение более трех лет. 2. ваш ответ не проверен должным образом (ваш CSS содержит несколько опечаток, которые необходимо исправить, прежде чем браузер даже распознает вашу сетку). И 3. Ваш ответ на самом деле не отвечал примеру в моем вопросе (иначе вы бы поняли, что ваше решение не работает с ним). - Так что нет, извините, но я не рассматриваю повышение голосов.
Лойло