[css] HTML colspan in CSS

I'm trying to construct a layout similar to the following:

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

where the bottom is filling the space of the upper row.

If this were an actual table, I could easily accomplish this with <td colspan="3">, but as I'm simply creating a table-like layout, I cannot use <table> tags. Is this possible using CSS?

This question is related to css

The answer is


I came here because currently the WordPress table block doesn't support the colspan parameter and i thought i will replace it using CSS. This was my solution, assuming that the columns are the same width:

_x000D_
_x000D_
table {_x000D_
  width: 100%;_x000D_
}_x000D_
_x000D_
table td {_x000D_
  width: 50%;_x000D_
  background: #dbdbdb;_x000D_
  text-align: center;_x000D_
}_x000D_
_x000D_
table tr:nth-child(2n+1) {_x000D_
  position:relative;_x000D_
  display:block;_x000D_
  height:20px;_x000D_
  background:green;_x000D_
}_x000D_
_x000D_
table tr:nth-child(2n+1) td {_x000D_
  position:absolute;_x000D_
  left:0;_x000D_
  right:-100%;_x000D_
  width: auto;_x000D_
  top:0;_x000D_
  bottom:0;_x000D_
  background:red;_x000D_
  text-align:center;_x000D_
}
_x000D_
<table>_x000D_
    <tr>_x000D_
        <td>row</td>_x000D_
    </tr>_x000D_
    <tr>_x000D_
        <td>cell</td>_x000D_
        <td>cell</td>_x000D_
    </tr>_x000D_
    <tr>_x000D_
        <td>row</td>_x000D_
    </tr>_x000D_
    <tr>_x000D_
        <td>cell</td>_x000D_
        <td>cell</td>_x000D_
    </tr>_x000D_
</table>
_x000D_
_x000D_
_x000D_


if you use div and span it will occupy more code size when the datagrid-table row are more in volume. This below code is checked in all browsers

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

You could trying using a grid system like http://960.gs/

Your code would be something like this, assuming you're using a "12 column" layout:

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

The CSS properties "column-count", "column-gap", and "column-span" can do this in a way that keeps all the columns of the pseudo-table inside the same wrapper (HTML stays nice and neat).

The only caveats are that you can only define 1 column or all columns, and column-span doesn't yet work in Firefox, so some additional CSS is necessary to ensure it will displays correctly. https://www.w3schools.com/css/css3_multiple_columns.asp

_x000D_
_x000D_
.split-me {_x000D_
  -webkit-column-count: 3;_x000D_
  -webkit-column-gap: 0;_x000D_
  -moz-column-count: 3;_x000D_
  -moz-column-gap: 0;_x000D_
  column-count: 3;_x000D_
  column-gap: 0;_x000D_
}_x000D_
_x000D_
.cols {_x000D_
  /* column-span is 1 by default */_x000D_
  column-span: 1;_x000D_
}_x000D_
_x000D_
div.three-span {_x000D_
  column-span: all !important;_x000D_
}_x000D_
_x000D_
/* alternate style for column-span in Firefox */_x000D_
@-moz-document url-prefix(){_x000D_
  .three-span {_x000D_
    position: absolute;_x000D_
    left: 8px;_x000D_
    right: 8px;_x000D_
    top: auto;_x000D_
    width: auto;_x000D_
  }_x000D_
}_x000D_
_x000D_
_x000D_
    
_x000D_
<p>The column width stays fully dynamic, just like flex-box, evenly scaling on resize.</p>_x000D_
_x000D_
<div class='split-me'>_x000D_
  <div class='col-1 cols'>Text inside Column 1 div.</div>_x000D_
  <div class='col-2 cols'>Text inside Column 2 div.</div>_x000D_
  <div class='col-3 cols'>Text inside Column 3 div.</div>_x000D_
  <div class='three-span'>Text div spanning 3 columns.</div>_x000D_
</div>_x000D_
_x000D_
_x000D_
_x000D_
  <style>_x000D_
/* Non-Essential Visual Styles */_x000D_
_x000D_
html * { font-size: 12pt; font-family: Arial; text-align: center; }_x000D_
.split-me>* { padding: 5px; } _x000D_
.cols { border: 2px dashed black; border-left: none; }_x000D_
.col-1 { background-color: #ddffff; border-left: 2px dashed black; }_x000D_
.col-2 { background-color: #ffddff; }_x000D_
.col-3 { background-color: #ffffdd; }_x000D_
.three-span {_x000D_
  border: 2px dashed black; border-top: none;_x000D_
  text-align: center; background-color: #ddffdd;_x000D_
}_x000D_
  </style>
_x000D_
_x000D_
_x000D_


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


Media Query classes can be used to achieve something passable with duplicate markup. Here's my approach with 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 for mobile, colspan 5 for others with CSS doing the work.


Another suggestion is using flexbox instead of tables altogether. This is a "modern browser" thing of course, but come on, it's 2016 ;)

At least this might be an alternative solution for those looking for an answer to this nowadays, since the original post was from 2010.

Here's a great guide: https://css-tricks.com/snippets/css/a-guide-to-flexbox/

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


There is no colspan in css as far as I know, but there will be column-span for multi column layout in the near future, but since it is only a draft in CSS3, you can check it in here. Anyway you can do a workaround using div and span with table-like display like this.

This would be the 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>

And this would be the 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%; }

The only reason to use this trick is to gain the benefit of table-layout behaviour, I use it alot if only setting div and span width to certain percentage didn't fullfil our design requirement.

But if you don't need to benefit from the table-layout behaviour, then durilai's answer would suit you enough.


You could always position:absolute; things and specify widths. It's not a very fluid way of doing it, but it would work.


To provide an up-to-date answer: The best way to do this today is to use css grid layout like this:

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

and the HTML

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

If you come here because you have to turn on or off the colspan attribute (say for a mobile layout):

Duplicate the <td>s and only show the ones with the desired colspan:

_x000D_
_x000D_
table.colspan--on td.single {_x000D_
  display: none;_x000D_
}_x000D_
_x000D_
table.colspan--off td.both {_x000D_
  display: none;_x000D_
}
_x000D_
<!-- simple table -->_x000D_
<table class="colspan--on">_x000D_
  <thead>_x000D_
    <th>col 1</th>_x000D_
    <th>col 2</th>_x000D_
  </thead>_x000D_
  <tbody>_x000D_
    <tr>_x000D_
      <!-- normal row -->_x000D_
      <td>a</td>_x000D_
      <td>b</td>_x000D_
    </tr>_x000D_
    <tr>_x000D_
      <!-- the <td> spanning both columns -->_x000D_
      <td class="both" colspan="2">both</td>_x000D_
_x000D_
      <!-- the two single-column <td>s -->_x000D_
      <td class="single">A</td>_x000D_
      <td class="single">B</td>_x000D_
    </tr>_x000D_
    <tr>_x000D_
      <!-- normal row -->_x000D_
      <td>a</td>_x000D_
      <td>b</td>_x000D_
    </tr>_x000D_
  </tbody>_x000D_
</table>_x000D_
<!--_x000D_
that's all_x000D_
-->_x000D_
_x000D_
 _x000D_
_x000D_
<!--_x000D_
stuff only needed for making this interactive example looking good:_x000D_
-->_x000D_
<br><br>_x000D_
<button onclick="toggle()">Toggle colspan</button>_x000D_
<script>/*toggle classes*/var tableClasses = document.querySelector('table').classList;_x000D_
function toggle() {_x000D_
  tableClasses.toggle('colspan--on');_x000D_
  tableClasses.toggle('colspan--off');_x000D_
}_x000D_
</script>_x000D_
<style>/* some not-needed styles to make this example more appealing */_x000D_
td {text-align: center;}_x000D_
table, td, th {border-collapse: collapse; border: 1px solid black;}</style>
_x000D_
_x000D_
_x000D_


That isn't part of the purview of CSS. colspan describes the structure of the page's content, or gives some meaning to the data in the table, which is HTML's job.


I've created this fiddle:

enter image description here

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;

}

I've had some success, although it relies on a few properties to work:

table-layout: fixed border-collapse: separate

and cell 'widths' that divide/span easily, i.e. 4 x cells of 25% width:

_x000D_
_x000D_
.div-table-cell,_x000D_
* {_x000D_
  box-sizing: border-box;_x000D_
}_x000D_
_x000D_
.div-table {_x000D_
  display: table;_x000D_
  border: solid 1px #ccc;_x000D_
  border-left: none;_x000D_
  border-bottom: none;_x000D_
  table-layout: fixed;_x000D_
  margin: 10px auto;_x000D_
  width: 50%;_x000D_
  border-collapse: separate;_x000D_
  background: #eee;_x000D_
}_x000D_
_x000D_
.div-table-row {_x000D_
  display: table-row;_x000D_
}_x000D_
_x000D_
.div-table-cell {_x000D_
  display: table-cell;_x000D_
  padding: 15px;_x000D_
  border-left: solid 1px #ccc;_x000D_
  border-bottom: solid 1px #ccc;_x000D_
  text-align: center;_x000D_
  background: #ddd;_x000D_
}_x000D_
_x000D_
.colspan-3 {_x000D_
  width: 300%;_x000D_
  display: table;_x000D_
  background: #eee;_x000D_
}_x000D_
_x000D_
.row-1 .div-table-cell:before {_x000D_
  content: "row 1: ";_x000D_
}_x000D_
_x000D_
.row-2 .div-table-cell:before {_x000D_
  content: "row 2: ";_x000D_
}_x000D_
_x000D_
.row-3 .div-table-cell:before {_x000D_
  content: "row 3: ";_x000D_
  font-weight: bold;_x000D_
}_x000D_
_x000D_
.div-table-row-at-the-top {_x000D_
  display: table-header-group;_x000D_
}
_x000D_
<div class="div-table">_x000D_
_x000D_
  <div class="div-table-row row-1">_x000D_
_x000D_
    <div class="div-table-cell">Cell 1</div>_x000D_
    <div class="div-table-cell">Cell 2</div>_x000D_
    <div class="div-table-cell">Cell 3</div>_x000D_
_x000D_
  </div>_x000D_
_x000D_
  <div class="div-table-row row-2">_x000D_
_x000D_
    <div class="div-table-cell colspan-3">_x000D_
      Cor blimey he's only gone and done it._x000D_
    </div>_x000D_
_x000D_
  </div>_x000D_
_x000D_
  <div class="div-table-row row-3">_x000D_
_x000D_
    <div class="div-table-cell">Cell 1</div>_x000D_
    <div class="div-table-cell">Cell 2</div>_x000D_
    <div class="div-table-cell">Cell 3</div>_x000D_
_x000D_
  </div>_x000D_
_x000D_
</div>
_x000D_
_x000D_
_x000D_

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

Also, applying display:table-header-group or table-footer-group is a handy way of jumping 'row' elements to the top/bottom of the 'table'.


Try adding display: table-cell; width: 1%; to your table cell element.

_x000D_
_x000D_
.table-cell {_x000D_
  display: table-cell;_x000D_
  width: 1%;_x000D_
  padding: 4px;_x000D_
  border: 1px solid #efefef;_x000D_
}
_x000D_
<div class="table">_x000D_
  <div class="table-cell">one</div>_x000D_
  <div class="table-cell">two</div>_x000D_
  <div class="table-cell">three</div>_x000D_
  <div class="table-cell">four</div>_x000D_
</div>_x000D_
<div class="table">_x000D_
  <div class="table-cell">one</div>_x000D_
  <div class="table-cell">two</div>_x000D_
  <div class="table-cell">three</div>_x000D_
  <div class="table-cell">four</div>_x000D_
</div>_x000D_
<div class="table">_x000D_
  <div class="table-cell">one</div>_x000D_
</div>
_x000D_
_x000D_
_x000D_


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