Impedir que o conteúdo expanda itens de grade


153

TL; DR: Existe algo parecido table-layout: fixedcom grades CSS?


Tentei criar um calendário de exibição do ano com uma grande grade 4x3 durante os meses e aninhar grades 7x6 durante os dias.

O calendário deve preencher a página, para que o contêiner da grade do ano tenha uma largura e altura de 100% cada.

.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);
}

Aqui está um exemplo de trabalho: https://codepen.io/loilo/full/ryXLpO/

Por uma questão de simplicidade, todos os meses nessa caneta têm 31 dias e começam na segunda-feira.

Também escolhi um tamanho de fonte ridiculamente pequeno para demonstrar o problema:

Os itens de grade (= células do dia) são bastante condensados, pois existem várias centenas na página. E assim que os rótulos dos números do dia ficarem muito grandes (sinta-se à vontade para brincar com o tamanho da fonte na caneta usando os botões no canto superior esquerdo), a grade aumentará de tamanho e excederá o tamanho do corpo da página.

Existe alguma maneira de impedir esse comportamento?

Inicialmente, declarei que minha grade do ano tem 100% de largura e altura, então esse é provavelmente o ponto de partida, mas não consegui encontrar nenhuma propriedade CSS relacionada à grade que atendesse a essa necessidade.

Isenção de responsabilidade: estou ciente de que existem maneiras muito fáceis de estilizar esse calendário sem usar o CSS Grid Layout. No entanto, essa pergunta é mais sobre o conhecimento geral sobre o tema do que resolver o exemplo concreto.


O que você quer que aconteça? A fonte em cada célula pode ter qualquer tamanho e nunca faz com que o tamanho da célula da grade aumente?
— Michael Coker

1
Exatamente. Basicamente, é uma maneira mais conveniente do que aconteceria se eu definisse os tamanhos dos itens da grade de acordo com valores percentuais em vez de frações.
— Loilo

Basicamente, eu estou procurando uma versão grid-layouty de table-layout: fixed (ver: codepen.io/loilo/pen/dvxpvq?editors=1100 )
— Loilo

7
Esta é a maior dor em toda a especificação CSS Grid. Eles precisam ser um ambiente em que as áreas de grade não possam escapar das dimensões de qualquer um dos seus contêineres de grade pai! Como é, é um pesadelo para estruturas de grade profundamente aninhadas.
— Lonnie Best

Respostas:


263

Por padrão, um item de grade não pode ser menor que o tamanho do seu conteúdo.

Os itens de grade têm um tamanho inicial de min-width: autoe min-height: auto.

Você pode substituir esse comportamento definindo itens grade para min-width: 0, min-height: 0ou overflowcom qualquer valor diferente de visible.

Das especificações:

6.6 Tamanho mínimo automático de itens de grade

Para fornecer um tamanho mínimo padrão mais razoável para itens de grade, esta especificação define que o autovalor de min-width/ min-heighttambém aplica um tamanho mínimo automático no eixo especificado aos itens de grade que overflowsão visible. (O efeito é análogo ao tamanho mínimo automático imposto aos itens flexíveis.)

Aqui está uma explicação mais detalhada sobre os itens flex, mas também se aplica aos itens da grade:

Esta postagem também aborda possíveis problemas com contêineres aninhados e diferenças de renderização conhecidas entre os principais navegadores .


Para corrigir seu layout, faça estes ajustes no seu código:

.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 */
}

codepen revisado


1fr vs minmax(0, 1fr)

A solução acima opera no nível do item da grade. Para uma solução em nível de contêiner, consulte esta postagem:


3
Uau. Isso é fascinante e interessante ao mesmo tempo, e eu definitivamente não teria pensado nisso apenas tentando. Você deu uma olhada nas especificações dessas informações? Porque depois de não saber para o que procurar no google, foi o que tentei antes, mas acabei lendo a seção errada (depois de concluir a causa errada do problema).
— Loilo

1
Eu já havia enfrentado esse problema antes com itens flexíveis . Sendo que existem muitas semelhanças entre os itens flex e grid, imaginei que o comportamento poderia ser o mesmo e se concentrar nessa seção das especificações.
— Michael Benjamin

1
Ele fixa a altura, mas continua a crescer na direção horizontal, min-width: 0;não ajuda. Estou esquecendo de algo?
— usuário

2
Para grades aninhadas, precisamos aplicar isso a todos os níveis. Mas eu realmente vim aqui para upvote e obrigado ..
— Knack


57

A resposta anterior é muito bom, mas eu também queria mencionar que não é um equivalente layout fixo para as redes, você só precisa escrever minmax(0, 1fr)em vez de 1frcomo o seu tamanho pista.


6
Eu recomendo essa abordagem em relação à resposta anterior aceita.
— Thierry Prost

Embora isso funcione, eu não entendo um pouco disso ... Você poderia explicar por que isso funciona? O que minmax (0, 1fr) está fazendo? Isso nem sempre deve ser 0? Estou confuso :(
— BAERUS

2
minmax(0, 1fr)funciona porque 1fré realmente uma abreviação de minmax(auto,1fr), que não é o valor correto para a pergunta original.
— Mikko Rantalainen 07/02/19

Para obter detalhes adicionais, consulte github.com/w3c/csswg-drafts/issues/1777
— Mikko Rantalainen

1

As respostas existentes resolvem a maioria dos casos. No entanto, deparei-me com um caso em que precisava estar o conteúdo da célula da grade overflow: visible. Eu o resolvi posicionando-o absolutamente dentro de um invólucro (não ideal, mas o melhor que eu sei), assim:


.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


0

uma coisa mais fácil de fazer é definir a largura máxima do item de grade da seguinte maneira:

//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
  }

Estou um pouco confuso para ser honesto. Seu código não se parece com a pergunta original e aplicar max-width: 100% aos itens da grade (em vez de min-width: 0 da solução aceita) não resolverá o problema ...
— Loilo

max-width impedirá que ele se reajuste em relação à sua largura filho
— Pedro JR

Eu tentei reproduzir o seu código, e ele realmente funciona, mas não parece ser por causa da largura máxima: 100%, mas por causa da coluna da grade: extensão 4; sem definir uma coluna inicial. Defina uma coluna inicial (por exemplo, usando grid-column: 1 / span 4;) e ele quebrará o layout novamente. (Esse comportamento é meio estranho, mas tenho certeza de que há um canto em alguma parte da especificação em que isso é definido.)
— Loilo

tudo certo, combinado. mas você não considera um voto positivo para mim ainda
— Pedro JR

Para ser franco: 1. Esse é um problema resolvido há mais de três anos. 2. sua resposta não foi testada corretamente (seu CSS contém vários erros de digitação que precisam ser corrigidos antes que o navegador reconheça sua grade). E 3. sua resposta não atendeu ao exemplo da minha pergunta (caso contrário, você teria percebido que sua solução não funcionava com ela). - Então não, desculpe, mas não estou considerando um voto positivo.
— Loilo
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.