Search code examples
cssheadertabular

Displaying tabular data using only div element


I have a table and I need to add a global header like the image below . enter image description here

I'm working only with divs, not table tags. I've tried many possibilities to make it work but it won't. Here is what the table looks like.

Here is what I've tried:

.clsDashMap_sumSlideSiteContentSummary {
	position : absolute;
	top: 2rem;
	width: 100%;
	height: 14rem;
	color: #000000;
	text-align: center;
}
.clsDashMap_wrapTableSite {
	display: table;
	width: 100%;
	height: 14rem;
	border: 2px solid;
}
.tableSite_blocLogoCategorie {
	display: table-header-group;
	background-color: gray;
}
.siteLogoCategorie_cell {
	display: table-row;
	text-align: justify;
	padding: 10px;
	border: 2px solid red;
}
.tableSite_blocTitreCategorie {
	display: table-header-group;
	background-color: gray;
}
.siteTitleCategorie_cell {
	display: table-cell;
	text-align: justify;
	padding: 10px;
	border: 2px solid red;
}
.tableSite_blocFMTNT {
	display: table-row-group;
	background-color: gray;
	text-align: center;
}
.blocFMTNT-row {
	display: table-row;
	border: 2px solid;
}
.blocFMTNT-rowTitle {
	display: table-cell;
	text-align: justify;
	padding: 10px;
	border: 2px solid green;
}
.blocFMTNT-value {
	display: table-cell;
	text-align: justify;
	padding: 10px;
	border: 2px solid yellow;
	text-align: center;
	background-color: pink;
}
#pieChartAlm, #pieChartTkt {
	margin: auto;
	width: 5rem !important;
    height: 5rem !important;
}
<div class="clsDashMap_sumSlideSiteContentSummary">
     <div class="clsDashMap_wrapTableSite">
          
                <div class="tableSite_blocLogoCategorie"> 
                    <div class="siteLogoCategorie_cell"> <div style="display: table-header-group;background-color: yellow;"> ALARMES</div></div>
                       <div class="siteTitleCategorie_cell" style="width:2rem;">Criticité</div>
                       <div class="siteTitleCategorie_cell" style="width:2rem;">Sans Sup</div>
                       <div class="siteTitleCategorie_cell" style="width:2rem;">Non Nominale</div>
                    </div>
                 

            <div style="display: table-header-group;background-color: yellow;"> TICKETS</div>
								<div class="tableSite_blocLogoCategorie"> 
                    <div class="siteLogoCategorie_cell">
                       <div class="siteTitleCategorie_cell">En cours</div>
                       <div class="siteTitleCategorie_cell">A suivre</div>
                       <div class="siteTitleCategorie_cell">Clôs</div>
                    </div>
                 </div>
       
            <div style="display: table-header-group;background-color: yellow;"> SITES</div>
								<div class="tableSite_blocLogoCategorie">
                  <div class="siteLogoCategorie_cell">
                        <div class="siteTitleCategorie_cell">Perte HF</div>
                        <div class="siteTitleCategorie_cell">-3DB</div>
                        <div class="siteTitleCategorie_cell">Décrochage HS</div>
                        <div class="siteTitleCategorie_cell">Alarme RX</div>
                        <div class="siteTitleCategorie_cell">GE</div>
                   </div>
                </div>

             <div class="tableSite_blocFMTNT">
               <div class="blocFMTNT-row">
                 <div class="blocFMTNT-rowTitle">TNT</div>
                 <div class="blocFMTNT-value"><canvas id="pieChartAlm" ></canvas></div>
                 <div class="blocFMTNT-value">1.2</div>
                 <div class="blocFMTNT-value">1.3</div>
                 <div class="blocFMTNT-value">1.4</div>
                 <div class="blocFMTNT-value">1.5</div>
                 <div class="blocFMTNT-value">1.6</div>
                 <div class="blocFMTNT-value">1.7</div>
                 <div class="blocFMTNT-value">1.8</div>
                 <div class="blocFMTNT-value">1.9</div>
                 <div class="blocFMTNT-value">1.10</div>
                 <div class="blocFMTNT-value">1.11</div>
               </div>
               <div class="blocFMTNT-row">
                 <div class="blocFMTNT-rowTitle">FM</div>
                 <div class="blocFMTNT-value"><canvas id="pieChartTkt" ></canvas></div>
                 <div class="blocFMTNT-value">2.2</div>
                 <div class="blocFMTNT-value">2.3</div>
                 <div class="blocFMTNT-value">2.4</div>
                 <div class="blocFMTNT-value">1.5</div>
                 <div class="blocFMTNT-value">1.6</div>
                 <div class="blocFMTNT-value">1.7</div>
                 <div class="blocFMTNT-value">1.8</div>
                 <div class="blocFMTNT-value">1.9</div>
                 <div class="blocFMTNT-value">1.10</div>
                 <div class="blocFMTNT-value">1.11</div>
               </div>
             </div>
        </div>
  </div>


Solution

  • As others mentioned in the comments, this really should be handled with a table element, but if you absolutely must use divs, it can be done (with trade-offs).

    The trick is to contain all cells or subheaders under a header within a container div for that header, and all of these cell or subheader elements need to display as inline-blocks.

    To actually get it to look right, the highest level containing element must have its width set exactly to its contents unless you want it to extend the full width of the page. If you're not at all worried about responsive layout and/or how overflow in the cells behaves, you can figure it out (taking borders, margin, and padding into account, of course) and set it via CSS... otherwise you'll have to set it programmatically with JS and update it when needed.

    Take a look at this Codepen example I made or the code snippet of this working in action.

    UPDATE:

    I have found a much better, perhaps even ideal solution that gives you responsiveness. It uses the always wonderful but often forgotten: flex boxes! Go through the new snippet (or Codepen) and read the comments I've put in to see how it's done. This article is also a good resource for flex box tables.

        /* Tables
    ================================== */
    .table-container {
      width: 75%; // Sets table width relative to window width. 
      margin: 0 auto; // Centers table
    }
    
    .Rtable {
      display: flex;
      flex-wrap: wrap;
      margin: 0 0 3em 0;
      padding: 0;
      width: 100%;
    }
    
    .header-row {
      text-align: center;
      font-size: 1.4em;
    }
    
    .header-row h3 {
      margin: 0;
    }
    
    .table-row {
      width: 100%;
      display: flex;
    }
    .Rtable-cell { // This is applied to ALL table cells. 
      box-sizing: border-box; //This takes borders into account for sizing.
      padding: 0.8em 1.2em;
      // Depending on cell content, you may need to change 
      // overflow property, but in some cases, it might break 
      // the flexbox. 
      overflow: hidden;
      outline: solid 2px gray;
      background: lightgray;
    }
    
    //  These classes mimic the effect of the colspan attribute
    //  IMPORTANT: The number of columns in your table will determine
    //    the width percentages to use. 
    //    For instance, for a table with 8 columns at the smallest level,
    //    a colspan-1 would need to be set to 12.5%, colspan-2 to 25%, and so 
    on.
    .colspan-1 {
      width: 25%;
    }
    .colspan-2 {
      width: 50%;
    }
    .colspan-4 {
      width: 100%;
    }
    
    /* Page styling - None of this is particular important to the layout of the 
    table.
    ================================== */
    html { 
      height: 100%;
      background-color: #EEE; 
    }
    body {
      box-sizing: border-box;
      min-height: 100%;
      padding: 2em;
      font-family: 'Josefin Sans', sans-serif;
      background-color: white;
      border: double 3px #DDD;
      border-top: none; border-bottom: none;
    }
    <div class="table-container">
      <div class="Rtable">
        <!-- Breaking things up into rows is ultimately unnecessary 
             but if for any reason a cell were to go missing or an intentded 
    row's cells' widths don't add up to 100%, without splitting into rows, the 
    flexbox would fill in that gap with whatever cell is next... even if it's on 
    the next row. -->
        <div class="table-row header-row">
          <div class="Rtable-cell colspan-4"><h3>I'm at the top level</h3></div>
        </div>
        <div class="table-row header-row">
          <div class="Rtable-cell colspan-2"><h3>I'm a second level header</h3>
          </div>
          <div class="Rtable-cell colspan-1"><h3>Also second level!</h3></div>
          <div class="Rtable-cell colspan-1"><h3>Me too!</h3></div>
        </div>
        <div class="table-row">
          <div class="Rtable-cell colspan-1">Regular cell row 1</div>
          <div class="Rtable-cell colspan-1">Regular cell row 1</div>
          <div class="Rtable-cell colspan-1">Regular cell row 1</div>
          <div class="Rtable-cell colspan-1">Regular cell row 1</div>
        </div>
        <div class="table-row">
          <div class="Rtable-cell colspan-1">Regular cell row 2</div>
          <div class="Rtable-cell colspan-1">Regular cell row 2</div>
          <div class="Rtable-cell colspan-1">I'M JUST A PLAIN OL' CELL</div>
           <div class="Rtable-cell colspan-1">Regular cell row 2</div>
        </div>
      </div>
    </div>