Como um CSS “display: table-column” deve funcionar?

87

Dado o seguinte HTML e CSS, não vejo absolutamente nada em meu navegador (Chrome e IE mais recentes no momento da escrita). Tudo se reduz a 0 x 0 px. Por quê?

<!DOCTYPE html>
<html>
<head>
    <style type="text/css">
        section { display: table; height: 100%; background-color: grey; }

        #colLeft { display: table-column; height: 100%; background-color: green; }
        #colRight { display: table-column; height: 100%; background-color: red; }

        #row1 { display: table-row; height: 100%; }
        #row2 { display: table-row; height: 100%; }
        #row3 { display: table-row; height: 100%; }

        #cell1 { display: table-cell; height: 100%; }
        #cell2 { display: table-cell; height: 100%; }
        #cell3 { display: table-cell; height: 100%; }
    </style>
</head>
<body>
    <section>
        <div id="colLeft">
            <div id="row1">
                <div id="cell1">
                    AAA
                </div>
            </div>
            <div id="row2">
                <div id="cell2">
                    BBB
                </div>
            </div>
        </div>
        <div id="colRight">
            <div id="row3">
                <div id="cell3">
                    CCC
                </div>
            </div>
        </div>
    </section>
</body>
</html>
Eliot
fonte

Respostas:

118

O modelo de tabela CSS é baseado no modelo de tabela HTML http://www.w3.org/TR/CSS21/tables.html

Uma tabela é dividida em ROWS e cada linha contém uma ou mais células. As células são filhas de ROWS, NUNCA são filhas de colunas.

"display: table-column" NÃO fornece um mecanismo para fazer layouts em colunas (por exemplo, páginas de jornais com várias colunas, onde o conteúdo pode fluir de uma coluna para a outra).

Em vez disso, "tabela-coluna" SÓ define os atributos que se aplicam às células correspondentes nas linhas de uma tabela. Por exemplo, "A cor de fundo da primeira célula em cada linha é verde" pode ser descrita.

A tabela em si é sempre estruturada da mesma forma que em HTML.

Em HTML (observe que "td" s estão dentro de "tr" s, NÃO dentro de "col" s):

<table ..>
  <col .. />
  <col .. />
  <tr ..>
    <td ..></td>
    <td ..></td>
  </tr>
  <tr ..>
    <td ..></td>
    <td ..></td>
  </tr>
</table>

HTML correspondente usando propriedades da tabela CSS (observe que os divs "coluna" não contêm nenhum conteúdo - o padrão não permite conteúdo diretamente nas colunas):

.mytable {
  display: table;
}
.myrow {
  display: table-row;
}
.mycell {
  display: table-cell;
}
.column1 {
  display: table-column;
  background-color: green;
}
.column2 {
  display: table-column;
}
<div class="mytable">
  <div class="column1"></div>
  <div class="column2"></div>
  <div class="myrow">
    <div class="mycell">contents of first cell in row 1</div>
    <div class="mycell">contents of second cell in row 1</div>
  </div>
  <div class="myrow">
    <div class="mycell">contents of first cell in row 2</div>
    <div class="mycell">contents of second cell in row 2</div>
  </div>
</div>



OPCIONAL : as "linhas" e as "colunas" podem ser estilizadas atribuindo-se várias classes a cada linha e célula da seguinte maneira. Essa abordagem oferece flexibilidade máxima na especificação de vários conjuntos de células, ou células individuais, a serem estilizadas:

//Useful css declarations, depending on what you want to affect, include:

/* all cells (that have "class=mycell") */
.mycell {
}

/* class row1, wherever it is used */
.row1 {
}

/* all the cells of row1 (if you've put "class=mycell" on each cell) */
.row1 .mycell {
}

/* cell1 of row1 */
.row1 .cell1 {
}

/* cell1 of all rows */
.cell1 {
}

/* row1 inside class mytable (so can have different tables with different styles) */
.mytable .row1 {
}

/* all the cells of row1 of a mytable */
.mytable .row1 .mycell {
}

/* cell1 of row1 of a mytable */
.mytable .row1 .cell1 {
}

/* cell1 of all rows of a mytable */
.mytable .cell1 {
}
<div class="mytable">
  <div class="column1"></div>
  <div class="column2"></div>
  <div class="myrow row1">
    <div class="mycell cell1">contents of first cell in row 1</div>
    <div class="mycell cell2">contents of second cell in row 1</div>
  </div>
  <div class="myrow row2">
    <div class="mycell cell1">contents of first cell in row 2</div>
    <div class="mycell cell2">contents of second cell in row 2</div>
  </div>
</div>

Nos designs flexíveis de hoje, que usam <div>para vários propósitos, é aconselhável colocar alguma classe em cada div, para ajudar a referenciá-lo. Aqui, o que costumava ser <tr>em HTML se tornou class myrowe <td>se tornou class mycell. Essa convenção é o que torna os seletores CSS acima úteis.

NOTA DE DESEMPENHO : colocar nomes de classe em cada célula e usar os seletores multiclasse acima é um desempenho melhor do que usar seletores que terminam com *, como .row1 *ou uniforme .row1 > *. O motivo é que os seletores são combinados por último primeiro , portanto, quando os elementos correspondentes estão sendo procurados, .row1 *primeiro o faz *, o que corresponde a todos os elementos e, em seguida, verifica todos os ancestrais de cada elemento , para descobrir se algum ancestral o fez class row1. Isso pode ser lento em um documento complexo em um dispositivo lento. .row1 > *é melhor, porque apenas o pai imediato é examinado. Mas é muito melhor eliminar imediatamente a maioria dos elementos, via .row1 .cell1. (.row1 > .cell1é uma especificação ainda mais restrita, mas é a primeira etapa da pesquisa que faz a maior diferença, então geralmente não vale a desordem e o processo de pensamento extra para saber se sempre será um filho direto, de adicionar o seletor filho >.)

O ponto chave para tirar o desempenho é que o último item em um seletor deve ser o mais específico possível , e nunca deve ser *.

ToolmakerSteve
fonte
Eu não tentei fazer isso sozinho, mas vi recomendações para tanalin.com/en/projects/display-table-htc que é uma solução javascript para IE6 e IE7. Quando o javascript é executado, ele converte a página nas tags de tabela HTML mais antigas.
Toolmaker Steve
A solução funciona no IE8 +, Firefox, Chrome, iPad, Android. É uma boa maneira de evitar layouts de tabela se você precisar de uma estrutura flexível de tabela e oferecer suporte a navegadores mais modernos listados acima.
mbokil
o <col style="color: red;" >não é trabalho, mas o <col style="background-color: red;" >é ok! o que há de errado nisso?
xgqfrms
@xgqfrms: Alguma outra regra css deve estar substituindo a cor. Provavelmente uma regra aplicada a um elemento dentro de suas células. Por exemplo, se o seu texto está dentro de <p>, então em algum lugar você tem uma regra mais específica para definir a cor <p>. Experimente <col style="color: red !important;">. Se funcionar, esse é o problema. No entanto , não adquira o hábito de usar demais !important. Depois de ver esse trabalho, é melhor removê-lo e descobrir um seletor mais específico para ter precedência. google "css more specific selector" ou veja smashingmagazine.com/2007/07/…
ToolmakerSteve
23

O tipo de exibição "coluna da tabela" significa que atua como a <col>tag em HTML - ou seja, um elemento invisível cuja largura * governa a largura da coluna física correspondente da tabela envolvente.

Consulte o padrão W3C para obter mais informações sobre o modelo de tabela CSS.

* E algumas outras propriedades, como bordas, planos de fundo.

Random832
fonte
2
Se o colelemento tem uma estrutura lógica, o que é verdade, como se justifica usar a regra CSS display: table-column;, que só tem estrutura de apresentação? De acordo com as especificações em display( w3.org/wiki/CSS/Properties/display ), ele deve "se comportar" como um colelemento. Mas não consigo ver como isso é útil ...
chharvey
1
@ TestSubject528491 Porque então você pode definir o fundo da coluna, largura da coluna, etc, de uma tabela [apresentação]. Mas, na verdade, é mais útil em termos de especificar a regra de estilo padrão para a <col>própria tag ou uma tag equivalente em uma linguagem de marcação baseada em XML diferente.
Random832
@chharvey: HTML colé um elemento lógico que contém apenas estilo de apresentação . Você não pode colocar uma coluna de informações nele - este é um mal-entendido comum. Os dados da tabela estão sempre em linhas. display: table-column;converte um elemento lógico (normalmente a div) em um col. Isso faz com que outros campos de estilo atribuídos a esse elemento se apliquem ao conceito de apresentação "uma coluna". O resultado é um elemento lógico que não é exibido e cujo conteúdo, se houver, será ignorado; seu único efeito é aplicar estilo às "colunas" da apresentação associada. Veja minha resposta para um modelo.
Toolmaker Steve