Colspan / Rowspan para elementos cuja exibição é definida como table-cell

108

Eu tenho o seguinte código:

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

Bem direto. Como adiciono um colspan (ou o equivalente a colspan) para elementos com display: table-cell?

Fantasma de madara
fonte
5
Você não pode simplesmente usar uma mesa? Seria muito mais fácil. Além disso, se forem dados tabulares, também serão mais semânticos.
punkrockbuddyholly
@thirtydot provavelmente pode, seria apenas uma dor e desnecessário. Sistemas de grade como o 960 basicamente conseguem isso, mas para um layout de página inteira.
punkrockbuddyholly
@MrMisterMan: Não tenho certeza do que você está dizendo. 960.gs não usa display: table-cell.
thirtydot
@thirtydot desculpe, esqueci a pergunta específica que o OP havia feito. Você está certo, você não pode adicionar um colspan por meio de CSS. Eu estava apontando que você pode fazer com que divs se comportem como linhas e colunas e isso inclui células que abrangem várias colunas.
punkrockbuddyholly
Use uma tabela simulada como você faz para o seu primeiro nível de organização, o que lhe dará a capacidade de criar um rodapé adesivo, por exemplo. para sua emulação colspan, você pode criar uma tabela aninhada em sua célula única, que terá uma única linha e quantas células você precisar, ou usar div flutuante simples.
Bernard Dusablon,

Respostas:

27

Como o OP não determina explicitamente que a solução deve ser CSS puro, serei teimoso e apresentarei minha solução alternativa que descobri hoje, especialmente porque é muito mais elegante do que ter uma mesa dentro de outra.

O exemplo é igual a <table> com duas células por linha e duas linhas, onde a célula na segunda linha é um td com colspan="2".

Eu testei isso com Iceweasel 20, Firefox 23 e 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>

Ação ao vivo (demonstração) aqui .

EDIT: Eu ajustei o código para ser mais fácil de imprimir, pois eles deixam as cores de fundo fora por padrão. Eu também criei o rowspan-demo , inspirado na resposta tardia aqui.

F-3000
fonte
Estou procurando uma solução semelhante. Mas em vez disso, tenho 5 células na linha superior. Na linha inferior, preciso de 1 célula do mesmo tamanho da linha superior. Em seguida, uma célula com colspan = 2 e outra célula com colspan = 2, perfazendo um total de 5 células na linha inferior também. Aqui está o problema jsfiddle com base em sua solução. Alguma ideia? jsfiddle.net/7wdza4ye/1
Varun Verma
1
@VarunVerma, você deve adicionar uma célula vazia entre as células 7 e 8. Apenas adicionando <div class="cell"></div>funciona (pelo menos com Firefox). Com este design, você precisa preencher com célula (s) vazia (s). Por exemplo, se você tivesse que a célula 7 fosse colspan = 3 e a célula 8 fosse normal, então você precisaria de duas células vazias entre as células 7 e 8. A menos que você projetasse algo diferente (margens? Div personalizado único?) . Além disso, a largura de 100 px e 5 células torna as coisas complicadas, porque as palavras se estendem às células css, as configurações de estouro não parecem fazer diferença. Você também precisa recalcular widthpara div.colspan>div>div.
F-3000 de
funcionou. Obrigado. Na verdade, adicionei uma célula vazia após a célula 8 porque a borda inferior não estava aparecendo. Aqui está o mais recente: jsfiddle.net/7wdza4ye/3 . Tinha certeza de como obter a fronteira entre as células 7 e 8. Alguma sugestão? Obrigado pela ajuda.
Varun Verma
1
@VarunVerma, com o Chrome a borda externa estava incompleta sem a célula vazia após 8, então é obrigatório. Maneira simples de adicionar a fronteira entre as células 7 e 8 poderia ser esta: div.colspan{border-left:1px solid red}. Ele precisa ser colocado em algum lugar abaixo da regra que define div.colspan sem borda, ou será anulado.
F-3000 de
Obrigado @ F-3000. Isso foi útil. Para o resto, aqui está o link mais recente baseado na solução do F-3000: jsfiddle.net/7wdza4ye/4
Varun Verma
16

Uma solução mais simples que funciona para mim no Chrome 30:

Colspan pode ser emulado usando em display: tablevez de display: table-rowpara as linhas:

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

A única armadilha é que as células de linhas empilhadas não se alinham verticalmente, pois são de tabelas diferentes.

Philippe97
fonte
7

Se você está procurando uma maneira CSS direta de simular um colspan, você pode usar 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
fonte
Isso é incrível, você é demais!
Raj Kamal
1
Usar display: table-caption irá abranger todas as colunas e colocar a linha no topo da tabela, assim como um elemento de legenda na tabela html, então isso realmente não funciona. Somente se você quiser abranger todas as colunas da primeira ou da última linha.
Michiel
6

Basta usar um table.

as tabelas são desaprovadas quando usadas para fins de layout.

Isso parece dados tabulares (linhas / colunas de dados). Portanto, eu recomendaria usar um table.

Veja minha resposta a esta pergunta para mais informações:

criando a mesma coisa com divs como tabelas

Curt
fonte
11
Acontece que não é para dados tabulares, então não quero usar uma tabela :)
Madara's Ghost
13
Não entendo por que usar CSS para comportar-se exatamente como uma tabela é preferível a usar apenas uma tabela. É certo que tr/ tdspam não é o html mais bonito, mas é esse o único motivo? Todo mundo diz que as tabelas não foram "feitas" para serem usadas para formatação, mas o html em si não "foi feito" para fazer metade das coisas que consideramos aceitáveis ​​pelos padrões atuais, incluindo aplicativos da web.
Ligeiro
4
Quase um ano depois, mas - Ligeiro, compartilho sua irritação com as pessoas que evitam mesas por nenhuma outra razão além de "as mesas estão fora de moda". No entanto, estou encontrando alguns designs responsivos em que é útil ter uma mesa e não ser uma mesa, para que possa ser reorganizada em larguras menores. Aprender que não tenho colspan para divs é meio decepcionante.
spinn
4

Esta é uma maneira de dividir colunas em CSS que usei para minha situação.

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
fonte
2
Eu tive que aumentar .colspancom white-space: nowrap;para obter o resultado que eu queria, mas funcionou muito bem.
kshetline
2

Existe uma solução para fazer o colspan a largura de toda a tabela. Você não pode usar esta técnica para espalhar uma parte da tabela.

Código:

    *{
      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>

Explicação:

Usamos a posição absoluta no colspan para torná-lo a largura total da tabela. A própria mesa precisa de uma posição relativa. Fazemos uso de uma dummycell para manter a altura das linhas, a posição absoluta não segue o fluxo do documento.

É claro que você também pode usar o flexbox e a grade para resolver esse problema atualmente.

JT Houtenbos
fonte
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>

Código

Bderevyaga
fonte
1

Isso pode ser feito apenas com CSS puro e centralizando o texto no colspan "falso".

O truque é definir as linhas para position:relative, em seguida, colocar "divs vazios" rowonde você deseja fazer o colspan(eles devem ter heightpara funcionar), definir cellonde o conteúdo está como display:gride, finalmente, aplicar position:absoluteao elemento dentro da célula (e centralize-a como você centralizaria qualquer outro elemento absoluto).

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

Usando as classes div e atributos CSS apropriados, você pode imitar os efeitos desejados de colspan e rowspan.

Aqui está o CSS

.table {
    display:table;
}

.row {
    display:table-row;
}

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

Aqui está o exemplo de 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>    

Pelo que estou vendo nas perguntas e na maioria das respostas, as pessoas parecem esquecer que em qualquer div que esteja agindo como uma "célula de tabela", você pode inserir outro div que esteja agindo como uma tabela incorporada e iniciar o processo sobre.

*** Não é glamoroso, mas funciona para quem procura esse tipo de formatação e quer evitar as TABELAS. Se for para DATA LAYOUT, TABLEs ainda funcionam em HTML5.

Esperançosamente, isso ajudará alguém.

JRC
fonte
Em primeiro lugar, o HTML5 tem suporte completo para <table>- apenas que as pessoas devem evitar usá-lo para formatação visual . Usá-lo para exibir dados estruturados é onde ele deve ser usado , a menos que algo mais (como <ul>um mero exemplo) se ajuste melhor à tarefa. Em segundo lugar, cara, 4 mesas. Você traz uma questão interessante para a mesa (rowspan), mas sua resposta clama por ser usada <table>. Tenho que ver como minha solução funciona aqui ...
F-3000
Eu editaria meu comentário anterior, mas o limite de tempo chega. Assim como minha resposta sobre o colspan, o rowspan pode ser realizado com MUITO menos complicações do que com sua ... abordagem original. Veja você mesmo .
F-3000
Obrigado pelo seu feedback! Eu nunca disse que HTML5 não suportava tabelas. Muitas pessoas estão simplesmente procurando evitá-lo. Às vezes, ao escrever um aplicativo da web (em oposição a apenas uma página do tipo de anúncio), você precisa mais de um layout fixo para o posicionamento do botão e / ou controle.
JRC de
0

Você pode definir a posição do conteúdo do colspan como "relativo" e a linha como "absoluta" assim:

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

Você não pode conseguir isso no momento.

AFAIK, isso seria coberto pelas tabelas CSS , uma especificação que parece estar atualmente no estado de "trabalho em andamento".

naXa
fonte
0

Você pode tentar esta solução, onde você pode encontrar como aplicar o colspan usando 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
fonte
-1

Mesmo que esta seja uma questão antiga, gostaria de compartilhar minha solução para este problema.

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

Aqui está um violino . Não é realmente um intervalo e a solução é um pouco hacky, mas é útil em algumas situações. Testado no Chrome 46, Firefox 31 e IE 11.

No meu caso, tive que apresentar alguns dados não tabulares de forma tabular, mantendo a largura das colunas e dando título às subseções dos dados.

Gabriel
fonte
Claro, você sempre pode contar com uma solução de grade como a do Bootstrap. Nesse caso específico, eu realmente precisava da largura automática que oferece display: table.
Gabriel,
Além disso, se quiser dar ao conteúdo estendido alguma cor de fundo, você terá que preencher seu tr com a quantidade total de tds :(
Gabriel
Acabei fazendo uma tabela e redefinindo meu conceito de "dados tabulares" ^^
Gabriel
-2

Use tabelas aninhadas para aninhar extensões de coluna ...

<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 use 2 tabelas onde a extensão da coluna cobre toda a linha ...

<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
fonte
2
A questão era como fazer isso usando CSS.
Enno Gröper
4
Sinto muito, mas parece uma péssima ideia.
Madara's Ghost