¿Cómo se supone que funciona un CSS "display: table-column"?

87

Dado el siguiente HTML y CSS, no veo absolutamente nada en mi navegador (Chrome e IE son los más recientes al momento de escribir este artículo). Todo se colapsa a 0x0 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
fuente

Respuestas:

118

El modelo de tabla CSS se basa en el modelo de tabla HTML http://www.w3.org/TR/CSS21/tables.html

Una tabla se divide en FILAS y cada fila contiene una o más celdas. Las celdas son hijos de FILAS, NUNCA son hijos de columnas.

"display: table-column" NO proporciona un mecanismo para hacer diseños en columnas (por ejemplo, páginas de periódicos con múltiples columnas, donde el contenido puede fluir de una columna a la siguiente).

Más bien, "table-column" SOLO establece atributos que se aplican a las celdas correspondientes dentro de las filas de una tabla. Por ejemplo, se puede describir "El color de fondo de la primera celda de cada fila es verde".

La tabla en sí siempre está estructurada de la misma manera que en HTML.

En HTML (observe que "td" s están dentro de "tr" s, NO dentro de "col" s):

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

HTML correspondiente usando propiedades de tabla CSS (tenga en cuenta que los divs de "columna" no contienen ningún contenido; el estándar no permite contenido directamente en columnas):

.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 : tanto las "filas" como las "columnas" se pueden diseñar asignando varias clases a cada fila y celda de la siguiente manera. Este enfoque ofrece la máxima flexibilidad para especificar varios conjuntos de celdas, o celdas individuales, que se van a diseñar:

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

En los diseños flexibles de hoy, que se usan <div>para múltiples propósitos, es aconsejable poner algo de clase en cada div, para ayudar a referirse a él. Aquí, lo que solía estar <tr>en HTML se convirtió class myrowy se <td>convirtió en class mycell. Esta convención es lo que hace que los selectores CSS anteriores sean útiles.

NOTA DE RENDIMIENTO : poner nombres de clase en cada celda y usar los selectores de clases múltiples anteriores es un mejor rendimiento que usar selectores que terminan en *, como .row1 *o incluso .row1 > *. La razón es que los selectores se hacen coincidir primero en último lugar , por lo que cuando se buscan elementos coincidentes, .row1 *primero lo hace *, lo que hace coincidir todos los elementos, y luego verifica todos los antepasados ​​de cada elemento , para encontrar si algún antepasado tiene class row1. Esto puede ser lento en un documento complejo en un dispositivo lento. .row1 > *es mejor, porque solo se examina al padre inmediato. Pero es mucho mejor eliminar inmediatamente la mayoría de los elementos a través de .row1 .cell1. (.row1 > .cell1es una especificación aún más estricta, pero es el primer paso de la búsqueda lo que marca la mayor diferencia, por lo que generalmente no vale la pena el desorden y el proceso de pensamiento adicional sobre si siempre será un hijo directo, de agregar el selector de niños >.)

El punto clave para eliminar el rendimiento es que el último elemento de un selector debe ser lo más específico posible y nunca debe serlo *.

ToolmakerSteve
fuente
No lo he probado yo mismo, pero he visto recomendaciones para tanalin.com/en/projects/display-table-htc, que es una solución de JavaScript para IE6 e IE7. Cuando se ejecuta javascript, convierte la página en las etiquetas de tabla HTML más antiguas.
ToolmakerSteve
La solución funciona en IE8 +, Firefox, Chrome, iPad, Android. Es una buena manera de evitar los diseños de tabla si necesita una estructura flexible de una tabla y admite los navegadores más modernos enumerados anteriormente.
mbokil
¡ <col style="color: red;" >No es trabajo, pero <col style="background-color: red;" >está bien! ¿Qué pasa con esto?
xgqfrms
@xgqfrms: Alguna otra regla CSS debe anular el color. Probablemente una regla aplicada a un elemento dentro de sus celdas. Por ejemplo, si su texto está dentro de <p>, entonces en algún lugar tiene una configuración de regla más específica <p> color. Prueba <col style="color: red !important;">. Si esto funciona, entonces ese es el problema. Sin embargo , no adquiera el hábito de abusar !important. Después de ver que funciona, es mejor eliminarlo y encontrar un selector más específico para tener prioridad. google "selector de CSS más específico", o consulte smashingmagazine.com/2007/07/…
ToolmakerSteve
23

El tipo de visualización "columna-tabla" significa que actúa como la <col>etiqueta en HTML, es decir, un elemento invisible cuyo ancho * gobierna el ancho de la columna física correspondiente de la tabla adjunta.

Consulte el estándar W3C para obtener más información sobre el modelo de tabla CSS.

* Y algunas otras propiedades como bordes, fondos.

Aleatorio832
fuente
2
Si el colelemento tiene una estructura lógica, y la tiene, ¿cómo se justifica el uso de la regla CSS display: table-column;, que solo tiene una estructura de presentación? Según las especificaciones de display( w3.org/wiki/CSS/Properties/display ), se supone que se "comporta" como un colelemento. Pero no veo cómo eso es útil ...
chharvey
1
@ TestSubject528491 Porque entonces puede establecer el fondo de la columna, el ancho de la columna, etc., de una tabla [de presentación]. Pero realmente es más útil en términos de especificar la regla de estilo predeterminada para la <col>etiqueta en sí, o una etiqueta equivalente en un lenguaje de marcado basado en XML diferente.
Random832
@chharvey: HTML coles un elemento lógico que contiene solo estilo de presentación . No puede poner una columna de información en él; este es un malentendido común. Los datos de la tabla siempre están en filas. display: table-column;convierte un elemento lógico (normalmente a div) en a col. Hace que otros campos de estilo asignados a ese elemento se apliquen al concepto de presentación "una columna". El resultado es un elemento lógico que no se muestra y cuyo contenido, si lo hay, se ignora; su único efecto es aplicar estilo a las "columnas" de la presentación asociada. Vea mi respuesta para una plantilla.
ToolmakerSteve