Comment un "display: table-column" CSS est-il censé fonctionner?

87

Compte tenu du HTML et du CSS suivants, je ne vois absolument rien dans mon navigateur (Chrome et IE les plus récents au moment de la rédaction). Tout s'effondre à 0x0 px. Pourquoi?

<!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
la source

Réponses:

118

Le modèle de table CSS est basé sur le modèle de table HTML http://www.w3.org/TR/CSS21/tables.html

Un tableau est divisé en RANGÉES et chaque ligne contient une ou plusieurs cellules. Les cellules sont des enfants de ROWS, ce ne sont JAMAIS des enfants de colonnes.

"display: table-column" ne fournit PAS un mécanisme pour créer des mises en page en colonnes (par exemple des pages de journaux avec plusieurs colonnes, où le contenu peut circuler d'une colonne à l'autre).

Au contraire, "table-colonne" définit UNIQUEMENT les attributs qui s'appliquent aux cellules correspondantes dans les lignes d'un tableau. Par exemple, «La couleur d'arrière-plan de la première cellule de chaque ligne est verte» peut être décrite.

Le tableau lui-même est toujours structuré de la même manière qu'il l'est en HTML.

En HTML (notez que les "td" sont dans les "tr", PAS dans les "col"):

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

HTML correspondant utilisant les propriétés de la table CSS (notez que les divs "colonne" ne contiennent aucun contenu - la norme n'autorise pas le contenu directement dans les colonnes):

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



FACULTATIF : les "lignes" et les "colonnes" peuvent être stylisées en attribuant plusieurs classes à chaque ligne et cellule comme suit. Cette approche donne une flexibilité maximale dans la spécification de divers ensembles de cellules, ou cellules individuelles, à styliser:

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

Dans les conceptions flexibles d'aujourd'hui, qui utilisent <div>à des fins multiples, il est sage de mettre une classe sur chaque div, pour aider à s'y référer. Ici, ce qui était autrefois <tr>en HTML est devenu class myrowet <td>est devenu class mycell. Cette convention est ce qui rend les sélecteurs CSS ci-dessus utiles.

NOTE DE PERFORMANCE : mettre des noms de classe sur chaque cellule et utiliser les sélecteurs multi-classes ci-dessus est une meilleure performance que d'utiliser des sélecteurs se terminant par *, tels que .row1 *ou même .row1 > *. La raison en est que les sélecteurs sont mis en correspondance en dernier , donc lorsque des éléments correspondants sont recherchés, le .row1 *premier le fait *, ce qui correspond à tous les éléments, puis vérifie tous les ancêtres de chaque élément , pour trouver si un ancêtre en a class row1. Cela peut être lent dans un document complexe sur un périphérique lent. .row1 > *est mieux, car seul le parent immédiat est examiné. Mais il vaut mieux éliminer immédiatement la plupart des éléments, via .row1 .cell1. (.row1 > .cell1est une spécification encore plus stricte, mais c'est la première étape de la recherche qui fait la plus grande différence, donc cela ne vaut généralement pas le désordre, et le processus de réflexion supplémentaire pour savoir si ce sera toujours un enfant direct, d'ajouter le sélecteur enfant >.)

Le point clé à retenir sur les performances est que le dernier élément d'un sélecteur doit être aussi spécifique que possible et ne doit jamais l'être *.

OutilleurSteve
la source
Je n'ai pas essayé cela moi-même, mais j'ai vu des recommandations pour tanalin.com/en/projects/display-table-htc qui est une solution javascript pour IE6 et IE7. Lorsque le javascript s'exécute, il convertit la page dans les anciennes balises de table HTML.
ToolmakerSteve
La solution fonctionne sur IE8 +, Firefox, Chrome, iPad, Android. C'est un bon moyen d'éviter les dispositions de tableau si vous avez besoin d'une structure flexible d'un tableau et que vous prenez en charge les navigateurs plus modernes répertoriés ci-dessus.
mbokil le
l' <col style="color: red;" >est pas de travail, mais <col style="background-color: red;" >est ok! quel est le problème avec ça?
xgqfrms
@xgqfrms: une autre règle css doit remplacer la couleur. Probablement une règle appliquée à un élément à l'intérieur de vos cellules. Par exemple, si votre texte est à l'intérieur de <p>, alors quelque part vous avez un paramètre de règle plus spécifique <p> couleur. Essayez <col style="color: red !important;">. Si cela fonctionne, c'est le problème. Cependant , ne prenez pas l'habitude d'en abuser !important. Après avoir vu ce travail, mieux vaut le supprimer et trouver un sélecteur plus spécifique pour avoir la priorité. google "css more specific selector", ou voir smashingmagazine.com/2007/07/...
ToolmakerSteve
23

Le type d'affichage "table-colonne" signifie qu'il agit comme la <col>balise HTML - c'est-à-dire un élément invisible dont la largeur * régit la largeur de la colonne physique correspondante du tableau englobant.

Consultez la norme W3C pour plus d'informations sur le modèle de table CSS.

* Et quelques autres propriétés comme les bordures, les arrière-plans.

Aléatoire832
la source
2
Si l' colélément a une structure logique, ce qu'il a, alors comment justifier l'utilisation de la règle CSS display: table-column;, qui n'a qu'une structure de présentation? Selon les spécifications sur display( w3.org/wiki/CSS/Properties/display ), il est censé "se comporter" comme un colélément. Mais je ne vois pas en quoi c'est utile ...
chharvey
1
@ TestSubject528491 Parce qu'alors vous pouvez définir l'arrière-plan de la colonne, la largeur de la colonne, etc., d'une table [de présentation]. Mais en réalité, c'est surtout utile pour spécifier la règle de style par défaut pour la <col>balise elle-même, ou une balise équivalente dans un autre langage de balisage basé sur XML.
Random832
@chharvey: HTML colest un élément logique qui ne contient que le style de présentation . Vous ne pouvez pas y mettre une colonne d'informations - c'est un malentendu courant. Les données de table sont toujours en lignes. display: table-column;convertit un élément logique (généralement a div) en a col. Cela amène d'autres champs de style affectés à cet élément à s'appliquer au concept de présentation "une colonne". Le résultat est un élément logique qui n'est pas affiché et dont le contenu, le cas échéant, est ignoré; son seul effet est d'appliquer un style aux "colonnes" de la présentation associée. Voir ma réponse pour un modèle.
ToolmakerSteve