Como fazer <div> preencher <td> altura

99

Eu li várias postagens no StackOverflow, mas não consegui encontrar uma resposta para esta pergunta bastante simples.

Eu tenho uma construção HTML como esta:

<table>
  <tr>
    <td class="thatSetsABackground">
      <div class="thatSetsABackgroundWithAnIcon">
        <dl>
          <dt>yada
          </dt>
          <dd>yada
          </dd>
        </dl>
      <div>
    </td>
    <td class="thatSetsABackground">
      <div class="thatSetsABackgroundWithAnIcon">
        <dl>
          <dt>yada
          </dt>
          <dd>yada
          </dd>
        </dl>
      <div>
    </td>
  </tr>
</table>

O que eu preciso é que o divpreencha a altura do td, para que possa posicionar o plano de fundo do div (o ícone) no canto inferior direito do td.

Como você sugere que eu faça isso?


fonte
Relacionado: stackoverflow.com/questions/8344850/…
Chris Moschini

Respostas:

177

Se você der ao seu DT uma altura de 1px, o div filho terá um pai elevado para calcular sua%. Como seu conteúdo seria maior que 1px, o td aumentaria automaticamente, assim como o div. Um hack meio sem sentido, mas aposto que funcionaria.

psayre23
fonte
7
Embora pareça funcionar bem no webkit, o IE9 quebra completamente.
Daniel Imms
Funciona para mim no IE11 apenas quando também defino div como bloco embutido. Obrigado!
Danny C
5
Esta é uma solução que também funciona no Firefox: stackoverflow.com/questions/36575846/…
Wouter
Para fazê-lo funcionar no Firefox e no Chrome, tive que usar em min-height: 1px;vez deheight: 1px;
Matt Leonowicz
🤯 Não tenho certeza se gosto ou odeio CSS
noob
35

Altura CSS: 100% só funciona se o pai do elemento tiver uma altura explicitamente definida. Por exemplo, isso funcionaria conforme o esperado:

td {
    height: 200px;
}

td div {
    /* div will now take up full 200px of parent's height */
    height: 100%;
}

Já que parece que sua <td>altura será variável, o que aconteceria se você adicionasse o ícone inferior direito com uma imagem absolutamente posicionada assim:

.thatSetsABackgroundWithAnIcon {
    /* Makes the <div> a coordinate map for the icon */
    position: relative;

    /* Takes the full height of its parent <td>.  For this to work, the <td>
       must have an explicit height set. */
    height: 100%;
}

.thatSetsABackgroundWithAnIcon .theIcon {        
    position: absolute;
    bottom: 0;
    right: 0;
}

Com a marcação de célula da tabela assim:

<td class="thatSetsABackground">  
  <div class="thatSetsABackgroundWithAnIcon">    
    <dl>
      <dt>yada
      </dt>
      <dd>yada
      </dd>
    </dl>
    <img class="theIcon" src="foo-icon.png" alt="foo!"/>
  </div>
</td>

Editar: usando jQuery para definir a altura do div

Se você mantiver o <div>como filho de <td>, este snippet de jQuery definirá corretamente sua altura:

// Loop through all the div.thatSetsABackgroundWithAnIcon on your page
$('div.thatSetsABackgroundWithAnIcon').each(function(){
    var $div = $(this);

    // Set the div's height to its parent td's height
    $div.height($div.closest('td').height());
});
Pat
fonte
Isso poderia funcionar. Deixe-me voltar para você quando eu tentar. Eu li sobre o assunto e entendi que <div> precisa de uma altura específica para ser escalonado para 100%. Pelo que li, foi possível fazer com o jQuery, já que ele pode calcular para mim.
2
Não funcionei muito bem e decidimos usar uma abordagem diferente. Mas vou aceitar sua resposta, pois é a melhor que existe.
3
Hah, se eu tivesse um dólar pelo número de vezes que o CSS me fez mudar minha abordagem :)
Pat
5
Eu sou o único que pensa que "altura CSS: 100% só funciona se o pai do elemento tiver uma altura explicitamente definida" é uma regra realmente estúpida? O navegador determina a altura do elemento pai de qualquer maneira; não há como você definir explicitamente a altura do elemento pai.
Jez
1
a solução jquery funcionou, embora apenas quando a coloquei no final do arquivo, obrigado
luke_mclachlan
5

Você pode tentar fazer seu div flutuar:

.thatSetsABackgroundWithAnIcon{

    float:left;
}

Alternativamente, use inline-block:

.thatSetsABackgroundWithAnIcon{

    display:inline-block;
}

Exemplo prático do método inline-block:

table,
th,
td {
  border: 1px solid black;
}
<table>
  <tr>
    <td>
      <div style="border:1px solid red; height:100%; display:inline-block;">
        I want cell to be the full height
      </div>
    </td>
    <td>
      This cell
      <br/>is higher
      <br/>than the
      <br/>first one
    </td>
  </tr>
</table>

objeto irritado
fonte
O float: a sugestão para a esquerda não parece funcionar. Essa resposta poderia ser melhorada removendo-o, uma vez que a segunda solução mencionada parece funcionar.
Wouter
1
Isso não acontece com o Firefox. Parece funcionar apenas com o Chrome.
YLombardi
8
Esse snippet também não funciona no Chromium, pelo menos hoje em dia (estou usando 63.0.3239.84).
Michael
0

Realmente tenho que fazer isso com JS. Aqui está uma solução. Eu não usei seus nomes de classe, mas chamei a div dentro do nome de classe td de "full-height" :-) Usei jQuery, obviamente. Observe que isso foi chamado de jQuery (document) .ready (function () {setFullHeights ();}); Observe também que, se você tiver imagens, terá que iterá-las primeiro com algo como:

function loadedFullHeights(){
var imgCount = jQuery(".full-height").find("img").length;
if(imgCount===0){
    return setFullHeights();
}
var loaded = 0;
jQuery(".full-height").find("img").load(function(){
    loaded++;
    if(loaded ===imgCount){
        setFullHeights()
    }
});

}

E você gostaria de chamar o carregadoFullHeights () de docReady ao invés. Isso é realmente o que acabei usando apenas no caso. Tenho que pensar à frente, você sabe!

function setFullHeights(){
var par;
var height;
var $ = jQuery;
var heights=[];
var i = 0;
$(".full-height").each(function(){
    par =$(this).parent();
    height = $(par).height();
    var tPad = Number($(par).css('padding-top').replace('px',''));
    var bPad = Number($(par).css('padding-bottom').replace('px',''));
    height -= tPad+bPad;
    heights[i]=height;
    i++;
});
for(ii in heights){
    $(".full-height").eq(ii).css('height', heights[ii]+'px');
}

}

Boas notícias
fonte
-1

Esta questão já foi respondida aqui . Basta colocar height: 100%o dive o recipiente td.

Nacho Coloma
fonte
-4

Modifique a imagem de fundo do próprio <td>.

Ou aplique algum css ao div:

.thatSetsABackgroundWithAnIcon{
    height:100%;
}
Jage
fonte
enquanto escrevo no código. O DT já tem uma imagem de fundo definida usando uma classe. Portanto, essa opção não é viável. Tentei definir a altura da div para 100%, mas não funcionou. Ele simplesmente se ajusta à altura variável do <dl> contido. Portanto, algo é necessário para fazer o div "entender" que deve preencher a altura. E altura: 100% não faz isso. (pelo menos não sozinho)