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

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. Однако этот вопрос больше касается общих знаний по теме, чем решения конкретного примера.


person Loilo    schedule 09.04.2017    source источник
comment
Что вы хотите вместо этого? Шрифт в каждой ячейке может быть любого размера, и он никогда не приводит к увеличению размера ячейки сетки?   -  person Michael Coker    schedule 10.04.2017
comment
Точно. По сути, это более удобный способ того, что произошло бы, если бы я установил размеры элементов сетки в соответствии с процентными значениями, а не дробями.   -  person Loilo    schedule 10.04.2017
comment
Я в основном ищу версию table-layout: fixed с сеткой (см .: codepen.io/loilo/pen/dvxpvq?editors=1100)   -  person Loilo    schedule 10.04.2017
comment
Это самая большая проблема во всей спецификации CSS Grid. Они должны быть настройкой, в которой области сетки не могут выходить за пределы размеров любого из их родительских контейнеров сетки! Как бы то ни было, это кошмар для глубоко вложенных грид-структур.   -  person Lonnie Best    schedule 05.09.2018


Ответы (3)


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

Элементы сетки имеют начальный размер 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 */
}

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


1fr vs minmax(0, 1fr)

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

person Michael Benjamin    schedule 09.04.2017
comment
Вот это да. Это увлекательно и интересно одновременно, и я бы точно не придумал это, просто попробовав. Вы только что просмотрели спецификации для получения этой информации? Потому что, не зная, для чего гуглить, я пробовал это раньше, но в итоге прочитал неправильный раздел (после определения неправильной причины проблемы). - person Loilo; 10.04.2017
comment
Я уже сталкивался с этой проблемой раньше с элементами гибкости. Поскольку между элементами гибкости и сетки много общего, я решил, что поведение может быть таким же, и сосредоточился на этом разделе спецификации. - person Michael Benjamin; 10.04.2017
comment
Фиксирует высоту, но продолжает расти в горизонтальном направлении, min-width: 0; не помогает. Я что-то упускаю? - person user; 15.04.2017
comment
@user, реализации Grid Layout явно различаются в Chrome и Firefox. Исходный код в моем ответе работает в Chrome. Но для работы в FF требуется дополнительная настройка. Добавьте min-width: 0 к .month-grid и .day-item. Ответ исправлен. - person Michael Benjamin; 15.04.2017
comment
вы также можете упомянуть, что max-width:100%; также может содержать элементы в своей ячейке сетки;) stackoverflow.com/questions/47168389/ - person G-Cyrillus; 09.11.2017
comment
Для вложенных сеток нам нужно применить это ко всем уровням. Но я действительно пришел сюда, чтобы проголосовать и поблагодарить вас .. - person Knack; 06.03.2018
comment
Мне всегда было интересно, почему указание высоты как x% не работает, если высота родительского элемента определена в% / vh / vw. Контент всегда заканчивался расширением div и разрывом родительского элемента. Эта минимальная высота волшебна! В этом тоже есть смысл. Почему эти причины не обсуждаются на обучающих веб-сайтах !? Есть ли место, где кто-нибудь мог найти больше таких объяснений, как заранее подготовленный список? - person Pragy Agarwal; 29.08.2018
comment
@PragyAgarwal .. stackoverflow.com/users/3597276/michael-b?tab=answers: -) - person Michael Benjamin; 29.08.2018
comment
css spec следует прекратить употреблять наркотики. Почему не новое ключевое слово? Зачем делать особенное поведение уже существующей собственности, которое даже не имеет смысла? ... Станет ли css простым и интуитивно понятным? - person Hugo Mallet; 17.01.2020
comment
Ты настоящий MVP! Спасибо за 'min-width: 0;' решение. Мне удалось исправить мой скользкий слайдер, переполняющий ячейку (kenwheeler). - person Peter; 26.02.2020
comment
minmax сделал рик просто идеальным! - person vovchisko; 08.02.2021
comment
сэкономил мне столько времени. но, черт возьми, положение вещей ужасное. абсолютно невозможно предсказать или решить эту проблему логически. - person Ben Steward; 16.06.2021

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

person FremyCompany    schedule 18.09.2018
comment
Я рекомендую этот подход по сравнению с предыдущим принятым ответом. - person Thierry Prost; 25.11.2018
comment
Хотя это работает, я немного не понимаю ... Не могли бы вы объяснить, почему это работает? Что делает minmax (0, 1fr)? Не должно ли это всегда быть 0? Я запутался :( - person BAERUS; 21.01.2019
comment
minmax(0, 1fr) работает, потому что 1fr на самом деле является сокращением для minmax(auto,1fr), которое не является правильным значением для исходного вопроса. - person Mikko Rantalainen; 07.02.2019
comment
Дополнительные сведения см. На странице github.com/w3c/csswg-drafts/issues/1777 - person Mikko Rantalainen; 07.02.2019
comment
все остальные ответы - это взломы, это должен быть принятый ответ - person shinzou; 30.07.2020

Существующие ответы решают большинство случаев. Однако я столкнулся с ситуацией, когда мне нужно, чтобы содержимое ячейки сетки было 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

person bjnsn    schedule 14.11.2019