Colspan HTML em CSS

251

Estou tentando construir um layout semelhante ao seguinte:

+---+---+---+
|   |   |   |
+---+---+---+
|           |
+-----------+

onde a parte inferior está preenchendo o espaço da linha superior.

Se essa fosse uma tabela real, eu poderia fazer isso facilmente <td colspan="3">, mas como estou simplesmente criando um layout de tabela , não posso usar <table>tags. Isso é possível usando CSS?

Torre
fonte
8
A melhor solução realmente depende do que está entrando na mesa. Se forem dados (algo que pertence a uma tabela), use uma tabela. Se você estiver usando uma tabela para controlar o layout da página, uma das soluções HTML + CSS abaixo é melhor.
Mwcz 08/03
Adicione a marcação para ambos os casos e mostre apenas um de cada vez usando uma classe CSS de consulta de mídia.
DigitalDesignDj
2
Esqueça o CSS. Se você exibir dados tabulares, certamente saberia quantas colunas eles estenderiam. Use o colspanatributo
Tihomir Mitkov
Eu faria isso por inicialização ou grade personalizado a partir de bootstrap
Arun Prasad ES
Se você estiver usando CSS3, poderá usar columnSpan. Ao contrário de <td colspan = "#">, você não tem a opção de definir o número de colunas, mas pode abranger todas as colunas. w3schools.com/cssref/css3_pr_column-span.asp
MistyDawn

Respostas:

407

Não existe um analógico CSS simples e elegante para colspan.

As pesquisas sobre esse mesmo problema retornarão uma variedade de soluções que incluem várias opções, incluindo posicionamento absoluto, dimensionamento e uma variedade semelhante de advertências específicas do navegador e das circunstâncias. Leia e tome a melhor decisão informada possível, com base no que você encontrar.

David
fonte
10
As tabelas são elementos estruturais e apenas porque o uso de colspan muda sua aparência não significa que não. CSS é usado para estilizar elementos e não alterar a estrutura. O W3C discute a estrutura da tabela aqui: w3.org/TR/html401/struct/tables.html#h-11.2
Rob
88
Rob, entenda sua posição, mas observe as recomendações do W3C - especificamente relacionadas ao paradigma da tabela inteira - e você descobrirá que parte da consideração delas foi, certamente, a apresentação de tabelas. Essa idéia de que as mesas foram puramente concebidas como estrutura é uma ficção contemporânea. Acho que estaríamos melhor servidos para parar de se espalhar. O ponto é que precisamos parar de ser dogmáticos sobre tabelas. Seria errado eu dizer que eles sempre são apresentações, e é tão errado você dizer que eles são sempre estrutura. A realidade simplesmente não é tão cortada e seca.
David
4
Parece que sua resposta é a resposta popular. :) Fico feliz em saber que o dogma anti-mesa (no qual comprei) é muito rigoroso. Eu mantenho minha resposta apenas na medida em que ainda acho que colspané a ferramenta certa para o trabalho. Minha resposta foi 75% certa e a sua 100% certa. Você deve voltar ao SO.
Mwcz
71
Depois de 2 anos, pesquisei no Google e quis votar no autor, mas ele dizia "não pode votar em seu próprio post" e percebi que era eu, lol. Decidi mudar a solução aceita para essa, pois acho que ela tem melhores informações.
Torre
14
Este é um mini-ensaio sobre outra resposta (não especificada), não uma resposta à pergunta.
Jukka K. Korpela
56

Até onde eu sei, não há colspan em css, mas haverá column-spanum layout para várias colunas em um futuro próximo, mas como é apenas um rascunho no CSS3, você pode fazer o check-in aqui . De qualquer forma, você pode executar uma solução alternativa usando dive spancom uma exibição semelhante a uma tabela como esta.

Este seria o HTML:

<div class="table">
  <div class="row">
    <span class="cell red first"></span>
    <span class="cell blue fill"></span>
    <span class="cell green last"></span>
  </div>
</div>
<div class="table">
  <div class="row">
    <span class="cell black"></span>
  </div>
</div>

E este seria o css:

  /* this is to reproduce table-like structure
     for the sake of table-less layout. */
  .table { display:table; table-layout:fixed; width:100px; }
  .row { display:table-row; height:10px; }
  .cell { display:table-cell; }

  /* this is where the colspan tricks works. */
  span { width:100%; }

  /* below is for visual recognition test purposes only. */
  .red { background:red; }
  .blue { background:blue; }
  .green { background:green; }
  .black { background:black; }

  /* this is the benefit of using table display, it is able 
     to set the width of it's child object to fill the rest of 
     the parent width as in table */
  .first { width: 20px; }
  .last { width: 30px; }
  .fill { width: 100%; }

A única razão para usar esse truque é obter o benefício do table-layoutcomportamento, eu o uso muito se apenas definir a largura de div e span para determinada porcentagem não atender aos requisitos de design.

Mas se você não precisa se beneficiar com o table-layoutcomportamento, a resposta de durilai seria adequada para você.

Hendra Uzia
fonte
4
Sim, mas uma pequena correção: em vez disso .span { ..., deveria ser span { ....
Slavik Meltser
2
Usando divas tags para exibir dados tabulares é tão ruim quanto usando tables de layout de página de controle
Tihomir Mitkov
1
@TichomirMitkov depende de você estar ou não usando o design responsivo para alterar o layout - nesse caso, às vezes, isso pode funcionar muito bem.
Simon_Weaver
4
Isso realmente não responde à pergunta, pois você basicamente tem duas tabelas uma após a outra no exemplo que você deu. (Ietwo mergulha com a classe "table")
Inverno
21

Outra sugestão é usar flexbox em vez de tabelas. É claro que isso é um "navegador moderno", mas vamos lá, é 2016;)

Pelo menos essa pode ser uma solução alternativa para quem procura uma resposta hoje em dia, já que o post original era de 2010.

Aqui está um ótimo guia: https://css-tricks.com/snippets/css/a-guide-to-flexbox/

.table {
  border: 1px solid red;
  padding: 2px;
  max-width: 300px;
  display: flex;
  flex-flow: row wrap;
}
.table-cell {
  border: 1px solid blue;
  flex: 1 30%;
}
.colspan-3 {
  border: 1px solid green;
  flex: 1 100%;
}
<div class="table">
  <div class="table-cell">
    row 1 - cell 1
  </div>
  <div class="table-cell">
    row 1 - cell 2
  </div>
  <div class="table-cell">
    row 1 - cell 3
  </div>
  <div class="table-cell colspan-3">
    row 2 - cell 1 (spans 3 columns)
  </div>
</div>

Inverno
fonte
8
<div style="width: 100%;">
    <div style="float: left; width: 33%;">Row 1 - Cell 1</div>
    <div style="float: left; width: 34%;">Row 1 - Cell 2</div>
    <div style="float: left; width: 33%;">Row 1 - Cell 3</div>
</div>
<div style="clear: left; width: 100%;">
Row 2 - Cell 1
</div>
Dustin Laine
fonte
Não sei a largura das células.
Torre
1
Então não coloque uma largura. Não deveria importar. Mas se você deseja que eles abranjam a mesma largura, as duas divs principais precisam ter a mesma largura.
Dustin Laine
1
Você pode usar width: calc (100% / 3), o que será um pouco melhor do que dar ao meio 1% a mais
ii iml0sto1
5

Isso não faz parte do alcance do CSS. colspandescreve a estrutura do conteúdo da página ou dá algum significado aos dados na tabela, que é o trabalho do HTML.

mwcz
fonte
O OP menciona explicitamente "a criação de um layout em forma de tabela ", sem significado estrutural. Não é esse o objetivo das tabelas CSS? Não há nenhuma razão objectiva para tratar a propriedade colspan diferente do que toda a tabela, se houver um elemento de tabela CSS só de design, por que não uma propriedade CSS colspan só de design ...
Skippy le Grand Gourou
2
Confira a resposta mais votada para esta pergunta. Seu sentimento já foi discutido lá e estou inclinado a concordar. Minha opinião sobre o assunto mudou definitivamente nos cinco anos desde que escrevi esta resposta.
mwcz
4

Para fornecer uma resposta atualizada: A melhor maneira de fazer isso hoje é usar o layout da grade css da seguinte maneira:

.container {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-template-rows: auto;
  grid-template-areas: 
    "top-left top-middle top-right"
    "bottom bottom bottom"
}

.item-a {
  grid-area: top-left;
}
.item-b {
  grid-area: top-middle;
}
.item-c {
  grid-area: top-right;
}
.item-d {
  grid-area: bottom;
}

e o HTML

<div class="item-a">1</div>
<div class="item-b">2</div>
<div class="item-c">3</div>
<div class="item-d">123</div>
Toby 1 Kenobi
fonte
3

Você poderia tentar usar um sistema de grade como http://960.gs/

Seu código seria algo assim, supondo que você esteja usando um layout de "12 colunas":

<div class="container_12">
<div class="grid_4">1</div><div class="grid_4">2</div><div class="grid_4">3</div>
<div class="clear"></div>
<div class="grid_12">123</div>
</div>
Jeff
fonte
3

Tente adicionar display: table-cell; width: 1%;ao seu elemento de célula da tabela.

Ismail Farooq
fonte
como isso vai ajudar? O conceito fundamental de uma tabela é que cada linha tem células idênticas. Se uma das linhas tiver uma célula que implementa com êxito "width: 1%", todas as linhas terão essa coluna como "width: 1%". O objetivo de "colspan" é pegar 2 (ou mais) das colunas de largura fixa e combiná-las para obter uma largura combinada.
IAM_AL_X 23/06/19
3

Eu tive algum sucesso, embora dependa de algumas propriedades para funcionar:

table-layout: fixed border-collapse: separate

e 'larguras' de células que se dividem / se expandem facilmente, ou seja, 4 x células com 25% de largura:

.div-table-cell,
* {
  box-sizing: border-box;
}

.div-table {
  display: table;
  border: solid 1px #ccc;
  border-left: none;
  border-bottom: none;
  table-layout: fixed;
  margin: 10px auto;
  width: 50%;
  border-collapse: separate;
  background: #eee;
}

.div-table-row {
  display: table-row;
}

.div-table-cell {
  display: table-cell;
  padding: 15px;
  border-left: solid 1px #ccc;
  border-bottom: solid 1px #ccc;
  text-align: center;
  background: #ddd;
}

.colspan-3 {
  width: 300%;
  display: table;
  background: #eee;
}

.row-1 .div-table-cell:before {
  content: "row 1: ";
}

.row-2 .div-table-cell:before {
  content: "row 2: ";
}

.row-3 .div-table-cell:before {
  content: "row 3: ";
  font-weight: bold;
}

.div-table-row-at-the-top {
  display: table-header-group;
}
<div class="div-table">

  <div class="div-table-row row-1">

    <div class="div-table-cell">Cell 1</div>
    <div class="div-table-cell">Cell 2</div>
    <div class="div-table-cell">Cell 3</div>

  </div>

  <div class="div-table-row row-2">

    <div class="div-table-cell colspan-3">
      Cor blimey he's only gone and done it.
    </div>

  </div>

  <div class="div-table-row row-3">

    <div class="div-table-cell">Cell 1</div>
    <div class="div-table-cell">Cell 2</div>
    <div class="div-table-cell">Cell 3</div>

  </div>

</div>

https://jsfiddle.net/sfjw26rb/2/

Além disso, a aplicação de display: table-header-group ou table-footer-group é uma maneira prática de pular elementos de 'linha' para a parte superior / inferior da 'tabela'.

user3464561
fonte
0

se você usar div e span, ele ocupará mais tamanho de código quando a linha da tabela de datagrid estiver mais em volume. Este código abaixo é verificado em todos os navegadores

HTML:

<div id="gridheading">
<h4>Sl.No</h4><h4 class="big">Name</h4><h4>Location</h4><h4>column</h4><h4>column</h4><h4>column</h4><h4>Amount(Rs)</h4><h4>View</h4><h4>Edit</h4><h4>Delete</h4> 
</div>
<div class="data"> 
<h4>01</h4><h4 class="big">test</h4><h4>TVM</h4><h4>A</h4><h4>I</h4><h4>4575</h4><h4>4575</h4></div>
<div class="data"> 
<h4>01</h4><h4 class="big">test</h4><h4>TVM</h4><h4>A</h4><h4>I</h4><h4>4575</h4><h4>4575</h4></div>

CSS:

#gridheading {
    background: #ccc;
    border-bottom: 1px dotted #BBBBBB;
    font-size: 12px;
    line-height: 30px;
    text-transform: capitalize;
}
.data {
    border-bottom: 1px dotted #BBBBBB;
    display: block;
    font-weight: normal;
    line-height: 20px;
    text-align: left;
    word-wrap: break-word;
}
 h4 {
    border-right: thin dotted #000000;
    display: table-cell;
    margin-right: 100px;
    text-align: center;
    width: 100px;
    word-wrap: break-word;
}
.data .big {
    margin-right: 150px;
    width: 200px;
}
Web Designer cum Promoter
fonte
0
column-span: all; /* W3C */
-webkit-column-span: all; /* Safari & Chrome */
-moz-column-span: all; /* Firefox */
-ms-column-span: all; /* Internet Explorer */
-o-column-span: all; /* Opera */

http://www.quackit.com/css/css3/properties/css_column-span.cfm

Adam Hunter Peck
fonte
não apoio suficiente ... IE8 é, infelizmente, ainda é um problema persistente para a evolução
beauXjames
9
O OP quer ter um table-cellintervalo de várias colunas da tabela. column-spané para controlar um layout de coluna. O que permite que você flua texto por várias colunas, da mesma forma que os jornais.
21413 Chris Wesseling
1
De fato - embora isso seja realmente bom para usar em exibição: célula de tabela; elementos, que só se aplica a CSS-colunas: jsfiddle.net/mk0rrLc3/1
Mark
@ Mark-- span-span é usado com a propriedade column-count definida no pai. Não é necessário alterar o tipo de exibição. Além disso, o período de coluna pode aceitar apenas 1 ou todos como um valor; ele não permite fracionamento; portanto, "período de coluna: 2", como visto no violino, não é um uso válido da propriedade.
MistyDawn
0

Se você vem aqui porque precisa ativar ou desativar o colspanatributo (digamos, para um layout para celular):

Duplique os se <td>mostre apenas aqueles com o desejado colspan:

table.colspan--on td.single {
  display: none;
}

table.colspan--off td.both {
  display: none;
}
<!-- simple table -->
<table class="colspan--on">
  <thead>
    <th>col 1</th>
    <th>col 2</th>
  </thead>
  <tbody>
    <tr>
      <!-- normal row -->
      <td>a</td>
      <td>b</td>
    </tr>
    <tr>
      <!-- the <td> spanning both columns -->
      <td class="both" colspan="2">both</td>

      <!-- the two single-column <td>s -->
      <td class="single">A</td>
      <td class="single">B</td>
    </tr>
    <tr>
      <!-- normal row -->
      <td>a</td>
      <td>b</td>
    </tr>
  </tbody>
</table>
<!--
that's all
-->

 

<!--
stuff only needed for making this interactive example looking good:
-->
<br><br>
<button onclick="toggle()">Toggle colspan</button>
<script>/*toggle classes*/var tableClasses = document.querySelector('table').classList;
function toggle() {
  tableClasses.toggle('colspan--on');
  tableClasses.toggle('colspan--off');
}
</script>
<style>/* some not-needed styles to make this example more appealing */
td {text-align: center;}
table, td, th {border-collapse: collapse; border: 1px solid black;}</style>

luckydonald
fonte
0

As propriedades CSS "column-count", "column-gap" e "column-span" podem fazer isso de maneira a manter todas as colunas da pseudo-tabela dentro do mesmo wrapper (o HTML permanece agradável e limpo).

As únicas ressalvas são que você pode definir apenas uma coluna ou todas as colunas, e o período de coluna ainda não funciona no Firefox; portanto, é necessário algum CSS adicional para garantir que seja exibido corretamente. https://www.w3schools.com/css/css3_multiple_columns.asp

.split-me {
  -webkit-column-count: 3;
  -webkit-column-gap: 0;
  -moz-column-count: 3;
  -moz-column-gap: 0;
  column-count: 3;
  column-gap: 0;
}

.cols {
  /* column-span is 1 by default */
  column-span: 1;
}

div.three-span {
  column-span: all !important;
}

/* alternate style for column-span in Firefox */
@-moz-document url-prefix(){
  .three-span {
    position: absolute;
    left: 8px;
    right: 8px;
    top: auto;
    width: auto;
  }
}


    
<p>The column width stays fully dynamic, just like flex-box, evenly scaling on resize.</p>

<div class='split-me'>
  <div class='col-1 cols'>Text inside Column 1 div.</div>
  <div class='col-2 cols'>Text inside Column 2 div.</div>
  <div class='col-3 cols'>Text inside Column 3 div.</div>
  <div class='three-span'>Text div spanning 3 columns.</div>
</div>



  <style>
/* Non-Essential Visual Styles */

html * { font-size: 12pt; font-family: Arial; text-align: center; }
.split-me>* { padding: 5px; } 
.cols { border: 2px dashed black; border-left: none; }
.col-1 { background-color: #ddffff; border-left: 2px dashed black; }
.col-2 { background-color: #ffddff; }
.col-3 { background-color: #ffffdd; }
.three-span {
  border: 2px dashed black; border-top: none;
  text-align: center; background-color: #ddffdd;
}
  </style>

MistyDawn
fonte
0

Eu vim aqui porque atualmente o bloco de tabela do WordPress não suporta o parâmetro colspan e pensei em substituí-lo usando CSS. Esta foi a minha solução, assumindo que as colunas tenham a mesma largura:

table {
  width: 100%;
}

table td {
  width: 50%;
  background: #dbdbdb;
  text-align: center;
}

table tr:nth-child(2n+1) {
  position:relative;
  display:block;
  height:20px;
  background:green;
}

table tr:nth-child(2n+1) td {
  position:absolute;
  left:0;
  right:-100%;
  width: auto;
  top:0;
  bottom:0;
  background:red;
  text-align:center;
}
<table>
    <tr>
        <td>row</td>
    </tr>
    <tr>
        <td>cell</td>
        <td>cell</td>
    </tr>
    <tr>
        <td>row</td>
    </tr>
    <tr>
        <td>cell</td>
        <td>cell</td>
    </tr>
</table>

passatgt
fonte
-1

Você sempre pode position:absolute;coisas e especificar larguras. Não é uma maneira muito fluida de fazê-lo, mas funcionaria.

doubleJ
fonte
Há muito mais maneiras de conseguir isso do que usar marcação incorreta. O posicionamento absoluto para forçar um layout sempre foi considerado uma prática ruim.
precisa saber é o seguinte
-1

Eu criei esse violino:

insira a descrição da imagem aqui

http://jsfiddle.net/wo40ev18/3/

HTML

<div id="table">
<div class="caption">
    Center Caption
</div>
<div class="group">
      <div class="row">
            <div class="cell">Link 1t</div>
            <div class="cell"></div>
          <div class="cell"></div>
          <div class="cell"></div>
            <div class="cell"></div>
            <div class="cell ">Link 2</div>
      </div>
</div>

CSS

   #table {
    display:table;
}

.group {display: table-row-group; }

.row {
    display:table-row;
    height: 80px;
    line-height: 80px;
}

.cell {
    display:table-cell;
    width:1%;
    text-align: center;
    border:1px solid grey;
    height: 80px
        line-height: 80px;
}

.caption {
    border:1px solid red; caption-side: top; display: table-caption; text-align: center; 
    position: relative;
    top: 80px;
    height: 80px;
      height: 80px;
    line-height: 80px;

}
Layke
fonte
1
Mas eu acho grade de inicialização pode torná-lo muito facilmente
Arun Prasad ES
Isso não fornece a solução que o solicitante estava procurando. Apenas cria uma linha de células embutida.
MistyDawn
-1

As classes Media Query podem ser usadas para obter algo aceitável com marcação duplicada. Aqui está minha abordagem com o bootstrap:

  <tr class="total">
    <td colspan="1" class="visible-xs"></td>
    <td colspan="5" class="hidden-xs"></td>
    <td class="focus">Total</td>
    <td class="focus" colspan="2"><%= number_to_currency @cart.total %></td>
  </tr>

colspan 1 para celular, colspan 5 para outras pessoas com CSS fazendo o trabalho.

DigitalDesignDj
fonte
O autor da pergunta declarou especificamente que não poderia usar elementos HTML <table>. Se ele pudesse, este seria um problema fácil de resolver.
precisa saber é o seguinte