Colspan / Rowspan pour les éléments dont l'affichage est défini sur table-cell

109

J'ai le code suivant:

<div class="table">
    <div class="row">
        <div class="cell">Cell</div>
        <div class="cell">Cell</div>
    </div>
    <div class="row">
        <div class="cell colspan2">Cell</div>
    </div>
</div>

<style>
    .table {
        display: table;
    }
    .row {
        display: table-row;
    }
    .cell {
        display: table-cell;
    }
    .colspan2 {
        /* What to do here? */
    }
</style>

Assez simple. Comment ajouter un colspan (ou l'équivalent de colspan) pour les éléments avec display: table-cell?

Fantôme de Madara
la source
5
Vous ne pouvez pas simplement utiliser une table? Ce serait beaucoup plus facile. De plus, s'il s'agit de données tabulaires, ce serait aussi plus sémantique.
punkrockbuddyholly
@thirtydot c'est probablement le cas, ce serait juste pénible et inutile. Les systèmes de grille comme 960 y parviennent essentiellement, mais pour une mise en page entière.
punkrockbuddyholly
@MrMisterMan: Je ne suis pas sûr de ce que vous dites. 960.gs n'utilise pas display: table-cell.
thirtydot
@thirtydot désolé, j'ai oublié la question précise que l'OP avait posée. Vous avez raison, vous ne pouvez pas ajouter un colspan via CSS. Je faisais remarquer que vous pouvez faire en sorte que les div se comportent comme des lignes et des colonnes et que cela inclut des cellules couvrant plusieurs colonnes.
punkrockbuddyholly
Utilisez un tableau simulé comme vous le faites pour votre premier niveau d'organisation, ce qui vous donnera la possibilité de créer un pied de page collant par exemple. pour votre émulation colspan, vous pouvez créer un tableau imbriqué dans votre cellule unique, qui aura une seule ligne et autant de cellules dont vous avez besoin, ou utiliser un simple div flottant.
Bernard Dusablon

Réponses:

27

Étant donné qu'OP ne règle pas explicitement que la solution doit être du CSS pur, je serai têtu et j'ajouterai ma solution de contournement que j'ai trouvée aujourd'hui, d'autant plus qu'elle est beaucoup plus élégante que d'avoir une table à l'intérieur d'une table.

L'exemple équivaut à <table> avec deux cellules par ligne et deux lignes, où la cellule de la deuxième ligne est un td avec colspan="2".

J'ai testé cela avec Iceweasel 20, Firefox 23 et IE 10.

div.table {
  display: table;
  width: 100px;
  background-color: lightblue;
  border-collapse: collapse;
  border: 1px solid red;
}

div.row {
  display: table-row;
}

div.cell {
  display: table-cell;
  border: 1px solid red;
}

div.colspan,
div.colspan+div.cell {
  border: 0;
}

div.colspan>div {
  width: 1px;
}

div.colspan>div>div {
  position: relative;
  width: 99px;
  overflow: hidden;
}
<div class="table">
    <div class="row">
        <div class="cell">cell 1</div>
        <div class="cell">cell 2</div>
    </div>
    <div class="row">
        <div class="cell colspan">
            <div><div>
                cell 3
            </div></div>
        </div>
        <div class="cell"></div>
    </div>
</div>

Action en direct (démo) ici .

EDIT: J'ai affiné le code pour qu'il soit plus convivial, car ils laissent les couleurs d'arrière-plan par défaut. J'ai également créé rowspan-demo , inspiré par une réponse tardive ici.

F-3000
la source
Je recherche une solution similaire. Mais à la place, j'ai 5 cellules sur la rangée du haut. Sur la rangée du bas, j'ai besoin d'une cellule de la même taille que la rangée du haut. Ensuite, une cellule ayant colspan = 2 et une autre cellule ayant colspan = 2, soit un total de 5 cellules dans la rangée du bas également. Voici le problème jsfiddle basé sur votre solution. Des pensées? jsfiddle.net/7wdza4ye/1
Varun Verma
1
@VarunVerma, vous devez ajouter une cellule vide entre les cellules 7 et 8. Il suffit d'ajouter des <div class="cell"></div>œuvres (au moins avec Firefox). Avec cette conception, vous devez remplir avec des cellules vides. Par exemple, si vous l'aviez pour que la cellule 7 soit colspan = 3 et que la cellule 8 était normale, alors vous auriez besoin de deux cellules vides entre les cellules 7 et 8. À moins que vous ne conceviez autre chose (marges? Div personnalisé unique?) . De plus, une largeur de 100 pixels et de 5 cellules rend les choses délicates, car les mots étirent les cellules css, les paramètres de débordement ne semblent pas faire de différence. Vous devez également recalculer widthpour div.colspan>div>div.
F-3000
ça a marché. Merci. En fait, j'ai ajouté une cellule vide après la cellule 8 car la bordure inférieure n'apparaissait pas. Voici la dernière: jsfiddle.net/7wdza4ye/3 . Était sûr de savoir comment obtenir la frontière entre les cellules 7 et 8. Des suggestions? Merci de votre aide.
Varun Verma
1
@VarunVerma, avec Chrome, la bordure extérieure était incomplète sans cellule vide après 8, donc c'est vraiment nécessaire. Une façon simple d'ajouter la frontière entre les cellules 7 et 8 pourrait être le suivant: div.colspan{border-left:1px solid red}. Il doit être placé quelque part sous la règle qui définit div.colspan borderless, sinon il sera annulé.
F-3000
Merci @ F-3000. Cela a été utile. Pour le reste, voici le dernier lien basé sur la solution du F-3000: jsfiddle.net/7wdza4ye/4
Varun Verma
16

Une solution plus simple qui fonctionne pour moi dans Chrome 30:

Colspan peut être émulé en utilisant display: tableau lieu de display: table-rowpour les lignes:

.table {
    display: block;
}
.row {
    display: table;
    width: 100%;
}
.cell {
    display: table-cell;
}
.row.colspan2 {/* You'll have to add the 'colspan2' class to the row, and remove the unused <div class=cell> inside it */
    display: block;
}

Le seul inconvénient est que les cellules des lignes empilées ne s'alignent pas verticalement, car elles proviennent de tables différentes.

Philippe97
la source
7

Si vous recherchez un moyen CSS simple pour simuler un colspan, vous pouvez utiliser display: table-caption.

.table {
  display: table;
}
.row {
  display: table-row;
}
.cell {
  display: table-cell;
  border: 1px solid #000;
}
.colspan2 {
  /* What to do here? */
  display: table-caption;
}
<div class="table">
    <div class="row">
        <div class="cell">Cell</div>
        <div class="cell">Cell</div>
    </div>
    <div class="row">
        <div class="cell colspan2">Cell</div>
    </div>
</div>

stacigh
la source
C'est incroyable que vous basculez!
Raj Kamal du
1
L'utilisation de display: table-caption s'étendra sur toutes les colonnes et placera la ligne en haut du tableau, tout comme un élément caption dans un tableau html, donc cela ne fonctionne pas vraiment. Uniquement si vous souhaitez couvrir toutes les colonnes de la première ou de la dernière ligne.
Michiel
6

Utilisez simplement un fichier table.

les tables ne sont mal vues que lorsqu'elles sont utilisées à des fins de mise en page.

Cela ressemble à des données tabulaires (lignes / colonnes de données). Par conséquent, je recommanderais d'utiliser un fichier table.

Voir ma réponse à cette question pour plus d'informations:

créer la même chose avec des divs comme des tables

Sec
la source
11
Le fait est que ce n'est pas pour les données tabulaires, donc je ne veux pas utiliser de tableau :)
Madara's Ghost
13
Je ne comprends pas pourquoi il est préférable de tout CSS pour se comporter exactement comme une table que d'utiliser simplement une table. Certes tr/ tdspam n'est pas le plus joli html mais est-ce la seule raison? Tout le monde dit que les tableaux n'étaient pas «destinés» à être utilisés pour le formatage, mais que le HTML lui-même n'était pas «censé» faire la moitié des choses que nous considérons comme acceptables selon les normes actuelles, y compris les applications Web.
Légère
4
Près d'un an plus tard, mais - Légère, je partage votre irritation avec les gens qui évitent les tables pour aucune raison autre que "les tables sont démodées". Cependant, je rencontre quelques conceptions réactives où il est utile qu'une table ne soit pas une table, afin qu'elle puisse être réorganisée à des largeurs inférieures. Apprendre que je n'ai pas de colspan pour les divs est un peu décevant.
spinn
4

Voici une façon de couvrir les colonnes de CSS que j'ai utilisées pour ma propre situation.

https://jsfiddle.net/mb8npttu/

<div class='table'>
    <div class='row'>
        <div class='cell colspan'>
            spanning
        </div>
        <div class='cell'></div>
        <div class='cell'></div>
    </div>

    <div class='row'>
        <div class='cell'>1</div>
        <div class='cell'>2</div>
        <div class='cell'>3</div>
    </div>
</div>

<style>
    .table { display:table; }
    .row { display:table-row; }
    .cell { display:table-cell; }
    .colspan { max-width:1px; overflow:visible; }
</style>
Tim
la source
2
J'ai dû augmenter .colspanavec white-space: nowrap;pour obtenir le résultat que je voulais, mais cela a très bien fonctionné.
kshetline
2

Il existe une solution pour faire de la colonne la largeur de toute la table. Vous ne pouvez pas utiliser cette technique pour colspan une partie du tableau.

Code:

    *{
      box-sizing: border-box;
    }
    .table {
        display: table;
        position: relative;
    }
    .row {
        display: table-row;
    }
    .cell {
        display: table-cell;
        border: 1px solid red;
        padding: 5px;
        text-align: center;
    }
    .colspan {
        position: absolute;
        left: 0;
        width: 100%;
    }
    .dummycell {
        border-color: transparent;
    }
<div class="table">
    <div class="row">
        <div class="cell">Cell</div>
        <div class="cell">Cell</div>
    </div>
    <div class="row">
        <div class="cell dummycell">&nbsp;</div>
        <div class="cell colspan">Cell</div>
    </div>
    <div class="row">
        <div class="cell">Cell</div>
        <div class="cell">Cell</div>
    </div>
</div>

Explication:

Nous utilisons la position absolue sur le colspan pour en faire toute la largeur de la table. La table elle-même a besoin d'une position relative. On utilise une cellule factice pour maintenir la hauteur des lignes, la position absolue ne suit pas le flux du document.

Bien sûr, vous pouvez également utiliser flexbox et grid pour résoudre ce problème ces jours-ci.

JT Houtenbos
la source
1

CSS

.tablewrapper {
  position: relative;
}
.table {
  display: table;
  position: relative
}
.row {
  display: table-row;
}
.cell {
  border: 1px solid red;
  display: table-cell;
}
.cell.empty
{
  border: none;
  width: 100px;
}
.cell.rowspanned {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 100px;
}
.cell.colspan {
  position: absolute;
  left: 0;
  right: 0;
}

HTML

<div class="tablewrapper">
  <div class="table">
    <div class="row">
      <div class="cell rowspanned">
        Center
      </div>
      <div class="cell">
        Top right
      </div>
    </div>
    <div class="row">
      <div class="cell empty"></div>
      <div class="cell colspan">
        Bottom right
      </div>
    </div>
  </div>
</div>

Code

bderevyaga
la source
1

Cela peut être fait simplement avec du CSS pur et en centrant le texte sur le "faux" colspan.

L'astuce consiste à définir les lignes sur position:relative, puis à placer des "divs vides" à l' rowendroit où vous voulez faire le colspan(ils doivent avoir heightpour fonctionner), à définir celloù se trouve le contenu en tant que display:grid, et enfin, à appliquer position:absoluteà l'élément à l'intérieur de la cellule (et centrez-la comme vous pouvez centrer tout autre élément absolu).

 .table {
        display: table;
  }
  .row {
      display: table-row;
      position: relative;
  }
  .cell {
      display: table-cell;
      background-color: blue;
      color: white;
      height: 26px;
      padding: 0 8px;
  } 
  .colspan2 {
      display: grid;
  }
  .colspan2 p {
    position:absolute;
    left: 50%;
    transform:translateX(-50%);
    margin: 0;
  }
<div class="table">
    <div class="row">
        <div class="cell">Cell</div>
        <div class="cell">Cell</div>
    </div>
    <div class="row">
        <div class="cell colspan2"><p>Cell</p></div>
        <div class="cell"></div>
    </div>
</div>

Joe82
la source
0

En utilisant les classes div et les attributs CSS appropriés, vous pouvez imiter les effets souhaités du colspan et du rowspan.

Voici le CSS

.table {
    display:table;
}

.row {
    display:table-row;
}

.cell {
    display:table-cell;
    padding: 5px;
    vertical-align: middle;
}

Voici l'exemple HTML

<div class="table">
    <div class="row">
        <div class="cell">
            <div class="table">
                <div class="row">
                    <div class="cell">X</div>
                    <div class="cell">Y</div>
                    <div class="cell">Z</div>
                </div>
                <div class="row">
                    <div class="cell">2</div>
                    <div class="cell">4</div>
                    <div class="cell">6</div>
                </div>
            </div>
        </div>
        <div class="cell">
            <div class="table">
                <div class="row">
                    <div class="cell">
                        <div class="table">
                            <div class="row">
                                <div class="cell">A</div>
                            </div>
                            <div class="row">
                                <div class="cell">B</div>
                            </div>
                        </div>
                    </div>
                    <div class="cell">
                        ROW SPAN
                    </div>    
                </div>
            </div>
        </div>
    </div>
</div>    

D'après ce que je vois à la fois dans les questions et dans la plupart des réponses, les gens semblent oublier que dans toute div donnée qui agit comme une "cellule de table", vous pouvez insérer une autre div qui agit comme une table intégrée et démarrer le processus plus de.

*** Ce n'est pas glamour, mais cela fonctionne pour ceux qui recherchent ce type de formatage et qui veulent éviter les TABLE. Si c'est pour DATA LAYOUT, les TABLEs fonctionnent toujours en HTML5.

Espérons que cela aidera quelqu'un.

CCR
la source
Premièrement, HTML5 prend entièrement en charge <table>- c'est juste que les gens devraient éviter de l' utiliser pour le formatage visuel . L'utiliser pour afficher des données structurées est l'endroit où il doit être utilisé , à moins que quelque chose d'autre (comme <ul>, à titre d'exemple) corresponde mieux à la tâche. Deuxièmement, mec, 4 tables. Vous apportez une question intéressante sur la table (rowspan), mais votre réponse pleure pour l'utilisation à la <table>place. Je dois voir comment ma solution fonctionne ici ...
F-3000
Je modifierais mon commentaire précédent, mais la limite de temps arrive. Comme pour ma réponse à propos de colspan, rowspan peut être accompli avec BEAUCOUP moins de tracas qu'avec votre ... approche originale. Voyez-le vous-même .
F-3000
Merci pour vos commentaires. Je n'ai jamais dit que HTML5 ne supportait pas les tableaux. Beaucoup de gens cherchent simplement à l'éviter. Parfois, lors de l'écriture d'une application Web (par opposition à une simple page de type publicité), vous avez besoin de plus d'une mise en page fixe pour le placement des boutons et / ou des commandes.
JRC
0

Vous pouvez définir la position du contenu colspan comme "relative" et la ligne comme "absolue" comme ceci:

.table {
    display: table;
}
.row {
    display: table-row;
    position: relative;
}
.cell {
    display: table-cell;
}
.colspan2 {
    position: absolute;
    width: 100%;
}
Justo
la source
0

Vous ne pouvez pas y parvenir actuellement.

AFAIK cela serait couvert par les tables CSS , une spécification qui semble actuellement être à l'état "travail en cours".

naXa
la source
0

Vous pouvez essayer cette solution, où vous pouvez trouver comment appliquer colspan en utilisant div https://codepen.io/pkachhia/pen/JyWMxY

HTML:

<div class="div_format">
            <div class="divTable">
                <div class="divTableBody">
                    <div class="divTableRow">
                        <div class="divTableCell cell_lable">Project Name</div>
                        <div class="divTableCell cell_value">: Testing Project</div>
                        <div class="divTableCell cell_lable">Project Type</div>
                        <div class="divTableCell cell_value">: Web application</div>
                    </div>
                    <div class="divTableRow">
                        <div class="divTableCell cell_lable">Version</div>
                        <div class="divTableCell cell_value">: 1.0.0</div>
                        <div class="divTableCell cell_lable">Start Time</div>
                        <div class="divTableCell cell_value">: 2016-07-10 11:00:21</div>
                    </div>
                    <div class="divTableRow">
                        <div class="divTableCell cell_lable">Document Version</div>
                        <div class="divTableCell cell_value">: 2.0.0</div>
                        <div class="divTableCell cell_lable">End Time</div>
                        <div class="divTableCell cell_value">: 2017-07-10 11:00:23</div>
                    </div>
                    <div class="divTableRow">
                        <div class="divTableCell cell_lable">Document Revision</div>
                        <div class="divTableCell cell_value">: 3</div>
                        <div class="divTableCell cell_lable">Overall Result</div>
                        <div class="divTableCell cell_value txt_bold txt_success">: Passed</div>
                    </div>                          
                </div>
                <div class="divCaptionRow">
                    <div class="divCaptionlabel">Description</div>
                    <div class="divCaptionValue">: Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore</div>
                </div>
            </div>
        </div>

CSS:

body {
                font-family: arial
            }
            * {
                -webkit-box-sizing: border-box;
                -moz-box-sizing: border-box;
                box-sizing: border-box
            }
            .div_format {
                width: 100%;
                display: inline-block;
                position: relative
            }           
            .divTable {
                display: table;
                width: 100%;            
            }
            .divTableRow {
                display: table-row
            }
            .divTableHeading {
                background-color: #EEE;
                display: table-header-group
            }
            .divTableCell,
            .divTableHead {
                display: table-cell;
                padding: 10px
            }
            .divTableHeading {
                background-color: #EEE;
                display: table-header-group;
                font-weight: bold
            }
            .divTableFoot {
                background-color: #EEE;
                display: table-footer-group;
                font-weight: bold
            }
            .divTableBody {
                display: table-row-group
            }
            .divCaptionRow{
                display: table-caption;
                caption-side: bottom;
                width: 100%;
            }
            .divCaptionlabel{
                caption-side: bottom;
                display: inline-block;
                background: #ccc;
                padding: 10px;
                width: 15.6%;
                margin-left: 10px;
                color: #727272;
            }
            .divCaptionValue{
                float: right;
                width: 83%;
                padding: 10px 1px;
                border-bottom: 1px solid #dddddd;
                border-right: 10px solid #fff;
                color: #5f5f5f;
                text-align: left;
            }

            .cell_lable {
                background: #d0d0d0;
                border-bottom: 1px solid #ffffff;
                border-left: 10px solid #ffffff;
                border-right: 10px solid #fff;
                width: 15%;
                color: #727272;
            }
            .cell_value {
                border-bottom: 1px solid #dddddd;
                width: 30%;
                border-right: 10px solid #fff;   
                color: #5f5f5f;
            }
pkachhia
la source
-1

Même si c'est une vieille question, je voudrais partager ma solution à ce problème.

<div class="table">
    <div class="row">
        <div class="cell">Cell</div>
        <div class="cell">Cell</div>
    </div>
    <div class="row">
        <div class="cell colspan">
            <div class="spanned-content">Cell</div>
        </div>
    </div>
</div>

<style>
    .table {
        display: table;
    }
    .row {
        display: table-row;
    }
    .cell {
        display: table-cell;
    }
    .colspan:after {
        /* What to do here? */
        content: "c";
        display: inline;
        visibility: hidden;
    }
    .spanned-content {
        position: absolute;
    }
</style>

Voici un violon . Ce n'est pas vraiment un span, et la solution est un peu piratée, mais elle est utile dans certaines situations. Testé sur Chrome 46, Firefox 31 et IE 11.

Dans mon cas, j'ai dû présenter certaines données non tabulaires de manière tabulaire, en gardant la largeur des colonnes et en donnant un titre aux sous-sections des données.

Gabriel
la source
Bien sûr, vous pouvez toujours compter sur une solution de grille comme celle de Bootstrap. Dans ce cas particulier, j'avais vraiment besoin de l'auto-width qui offre display: table.
Gabriel
De plus, si vous voulez donner au contenu fractionné une couleur d'arrière-plan, vous devrez remplir votre tr avec le montant total de tds :(
Gabriel
J'ai fini par créer un tableau, et redéfinir mon concept de "données tabulaires" ^^
Gabriel
-2

Utilisez des tables imbriquées pour imbriquer les portées de colonnes

<div class="table">
  <div class="row">
    <div class="cell">
      <div class="table">
        <div class="row">
          <div class="cell">Cell</div>
          <div class="cell">Cell</div>
        </div>
      </div>
    </div>
  </div>

  <div class="row">
    <div class="cell">Cell</div>
  </div>
</div>

Ou utilisez 2 tables où la portée de la colonne couvre toute la ligne ...

<div class="table">
  <div class="row">
    <div class="cell">Cell</div>
    <div class="cell">Cell</div>
  </div>
</div>

<div class="table">
  <div class="row">
    <div class="cell">Cell</div>
  </div>
</div>
Henry George
la source
2
La question était de savoir comment le faire en utilisant CSS.
Enno Gröper
4
Je suis désolé, mais cela semble être une très mauvaise idée.
Madara's Ghost