---
url: 'https://simonerescio.it/2014/06/css-table-struttura-base-layout-tipica-app-mobile'
title: 'CSS table, struttura base per il layout di una tipica app mobile'
author:
  name: Simone Rescio
  url: 'https://simonerescio.it/chi-sono/'
date: '2014-06-18T15:45:26+02:00'
modified: '2026-04-20T23:37:09+02:00'
type: post
summary: 'Layout verticale per webapp mobile con CSS table: header, area contenuti scrollabile e footer, più header a tre colonne e barra comandi. Note per IE8/IE9 e demo CodePen.'
categories:
  - CSS
tags:
  - CSS
  - css table
  - display
  - mobile
image: 'https://simonerescio.it/wp-content/uploads/2014/06/css-table.png'
published: true
---

# CSS table, struttura base per il layout di una tipica app mobile

Sono serviti diversi anni per far abbandonare agli sviluppatori web le tabelle come strumento di creazione dei layout in favore di elementi semanticamente più rilevanti combinati con il CSS, ma il brutto effetto collaterale che ha avuto la campagna di sensibilizzazione verso la costruzione di layout flessibili con i fogli di stile è stata la completa demonizzazione delle tabelle HTML e delle stesse proprietà CSS che permettono di avvalersi dei loro potenti algoritmi di calcolo delle dimensioni.

Mi capita sempre più spesso di imbattermi in strutture tabellari formattate a mezzo di `div`, `p`, `span` e altri tag testuali con l’uso di strutture CSS a larghezze fisse, che sarebbero state ottenute in maniera molto più semplice (ed efficace in ottica responsive) usando il buon vecchio tag `table` perfettamente lecito in tale contesto.

Questa paura radicata dell’uso delle tabelle ormai viste come uno strumento desueto del passato può farci perdere di vista le grandi potenzialità che le **CSS table** hanno anche in relazione alle nuovissime frontiere del web quali le mobile webapp, sia native con tecnologia PhoneGap che non.

- [1. I tre elementi verticali di un layout mobile](#i-tre-elementi-verticalidi-un-layout-mobile)
[1.1. Internet Explorer Legacy](#internet-explorer-legacy)

- [2. I tre elementi orizzontali di un header mobile](#i-tre-elementi-orizzontali-di-un-headermobile)
- [3. La barra dei comandi in basso allo schermo](#la-barra-dei-comandi-in-basso-allo-schermo)
- [4. Combinazione delle CSS table](#combinazione-delle-css-table)

## I tre elementi verticali di un layout mobile

[![mobile-layout](https://simonerescio.it/wp-content/uploads/2014/06/mobile-layout.png)](https://simonerescio.it/2014/06/css-table-struttura-base-layout-tipica-app-mobile/mobile-layout)Generalmente il layout di un’applicazione mobile si compone delle seguenti parti principali disposte verticalmente in quest’ordine :

- Header

- Contenuti

- Comandi

L’Header contiene il logo ed il nome dell’app o della vista corrente ed uno o più tasti interattivi. Questa zona inoltre può contenere ulteriori righe di elementi che spingono ulteriormente verso il basso il box dei Contenuti.

La parte dei Comandi può non essere sempre presente in iOS e Windows Phone, mentre in Android è possibile trovarli in questa zona ma generalmente vengono posizionati nella riga sotto l’Header.

La parte centrale dei contenuti ospita di volta in volta gli elementi pertinenti alla vista selezionata ed è scrollabile verticalmente indipendentemente dagli elementi circostanti, tuttavia l’altezza del box dei Contenuti si deve adattare per rientrare tra i due elementi senza mandare fuori schermo nessuno dei tre.

Questo comportamento si ottiene facilmente e in maniera crossbrowser con il seguente HTML :

```
<div id="Layout">

    <header class="layout-top">
      HEADER.
    </header>

    <section class="layout-middle">
        <div class="outWrap">
            <div class="inWrap">
              CONTENTS.
            </div>
        </div>
    </section>

    <footer class="layout-bottom">
      FOOTER.
    </footer>
    
</div>
```

ed il seguente SASS/CSS :

```
html,
body,
#Layout {
    font-family: arial;
    height: 100%;
    margin: 0;
    overflow: hidden;
    width: 100%;
}

#Layout {
    display: table;
    
    .layout-top {
        background-color: orange;
        display: table-header-group;
        height: 1%;
    }

    .layout-middle {
        background-color: azure;
        display: inherit;
        height: 100%;
        min-height: 1px;
        width: 100%;
        position: relative;
        
        .outWrap {
            display: block;
            height: 100%;
            position : absolute;
            overflow: auto;
            -webkit-overflow-scrolling: touch;
            width:100%;
            
            .inWrap {
                height: 100%;
            }
        }
    }

    .layout-bottom {
        background-color: grey;
        display: table-footer-group;
        height: 1%;
    }
}

// Targets Android legacy stockbrowser
@media screen and (-webkit-min-device-pixel-ratio:0) {
    #Layout {
        .layout-middle {
            .outWrap {
                position: static;
            }
        }
    }
}

// Cancel the above and restore position on Safari 10+
_::-webkit-:host:not(:root:root),
#Layout .layout-middle .outWrap {
    position: absolute;
}
```

I due elementi `.layout-top` e `.layout-bottom`, aventi rispettivamente le proprietà `display:<strong>table-header-group</strong>` e `display:<strong>table-footer-group</strong>` fanno in modo che la propria altezza sia determinata dai loro contenuti, se assenti gli elementi collassano lasciando lo spazio all’elemento centrale `.layout-middle` avente `display:<strong>table</strong>` come il padre principale e la direttiva `height:100%`.

Inoltre la proprietà `position` è impostata su `relative`, questo perchè i contenuti saranno ospitati da due `div` interni, il primo dei quali `.outWrap` in `position:absolute` per fare in modo che occupi verticalmente sempre l’altezza del suo genitore, ovvero la riga dinamica `.layout-middle` in `display:table`, mentre il div interno `.inWrap` si espanderà verticalmente in maniera normale, solo che quando i contenuti eccederanno in altezza lo spazio di `.layout-middle` si avrà lo scrolling all’interno di `.outWrap` in modo da non intaccare il resto della struttura.

### Internet Explorer Legacy

Volendo applicare questa struttura HTML/CSS in ambito desktop la punta dolente è naturalmente Internet Explorer, nello specifico la struttura funziona egregiamente anche in **IE8**, che è la versione più aggiornata disponibile sui vetusti sistemi che operano con Window XP ([dismesso per la gioia di tutti l’8 aprile 2014](http://www.microsoft.com/it-it/windows/business/retiring-xp.aspx)), con la seguente modifica CSS :

```
.ie8 {
    #Layout {

        .layout-middle {
            display: table-cell;
            height : auto;
        }
    }
}
```

La versione più problematica è invece **IE9** che, nonostante la seguente fix CSS, presenta un comportamento anomalo :

```
.ie9 {
    #Layout {
       
        .layout-middle {
            display: table-cell;
        }
    }
}
```

[![](https://simonerescio.it/wp-content/uploads/2014/06/ie9-Height-Propagation-Bug-300x226.png)](https://simonerescio.it/2014/06/css-table-struttura-base-layout-tipica-app-mobile/ie9-height-propagation-bug)*L’altezza computata risulta zero nonostante visivamente l’elemento occupi tutta l’altezza disponibile*

Nello specifico vedremo che l’area azzurra dei Contenuti di `.layout-middle` si espande correttamente in altezza ma nessun contenuto appare all’interno. Il problema è causato dalla computazione dell’altezza dell’elemento a livello di box-model, nonostante l’altezza dichiarata 100% sull’elemento per espandersi entro tutto lo spazio verticale disponibile tra i due fratelli, che viene rispettata a livello visivo, il valore computato per l’altezza mostrata dall’inspector risulta 0.

In questo modo si spezza la catena di propagazione delle altezze dinamiche verso i suoi figli, dato che l’elemento `.outWrap` in `position:absolute` avrà come riferimento zero e di conseguenza non sarà disegnato sullo schermo.

Tuttavia richiedendo l’altezza dell’elemento via JavaScript otteniamo il valore corretto, per cui l’unico work-around per questo strano comportamento è “propagare” via JavaScript l’altezza di `.layout-middle` applicandola ad `.outWrap`.

```
//IE detection
$(document).ready(function(){
   var bv = navigator.appVersion;
   var ie = '';
   
   if( bv.indexOf("MSIE 8.")!=(-1) ) {
      ie = 'ie8';
   } else if( bv.indexOf("MSIE 9.")!=(-1) ) {
      ie = 'ie9';
   } else if( bv.indexOf("MSIE 10.")!=(-1) ) {
      ie = 'ie10';
   }
   $('html').addClass(ie);
   
   //Fix IE9 layout propagation bug
   if(ie==='ie9') {
      function setHeight() {
         var parentHeight = $('.layout-middle').height();
         $('.outWrap').height(parentHeight);
      }
      setHeight();
      
      $(window).on('resize', function(){
         setHeight();
      });
   }
   
});
```

In questo modo la struttura nel complesso continua ad essere governata dal meccanismo CSS reflow.

## I tre elementi orizzontali di un header mobile

[![mobile-app-header](https://simonerescio.it/wp-content/uploads/2014/06/mobile-app-header-300x255.png)](https://simonerescio.it/2014/06/css-table-struttura-base-layout-tipica-app-mobile/mobile-app-header)Avendo messo in piedi la struttura generale scendiamo ora nel dettaglio dell’interfaccia per realizzare gli elementi orizzontali. Sia per iOS che Android troviamo una struttura molto simile composta da tre elementi principali :

- Tasto menu/indietro a sinistra

- Nome dell’app/vista corrente centrale

- Uno o più tasti di interazione a destra

A livello di struttura la situazione è simile alla precedente, il primo elemento a sinistra ha tendenzialmente una larghezza fissa, mentre l’area dei pulsanti a destra ha una larghezza variabile a seconda del numero di elementi che contiene, la zona centrale invece è a larghezza elastica ed occupa tutto lo spazio tra i due elementi fratelli.

La struttura HTML necessaria è simile alla precedente :

```
<nav id="top-bar">
  
  <div class="top-bar-left">
    left
  </div>
  
  <div class="top-bar-middle">
    
    <div class="top-bar-outWrap">
      <div class="top-bar-inWrap">
        <p class="app-name">middle</p>
      </div>
    </div>
    
  </div>
  
  <div class="top-bar-right">
    <p class="action-overflow">right</p>
    <p class="action-overflow">right</p>
  </div>

</nav>
```

La differenza sta nel CSS, il contenitore principale `#top-bar` con `display:table` avrà come proprietà `table-layout:auto` in modo da consentire agli elementi figli in `display:table-cell` di adattarsi in base alla larghezza dei propri contenuti.

L’elemento centrale `.top-bar-middle` conterrà un’ulteriore struttura di `div` per consentire il corretto centramento verticale e contenimento orizzontale dei contenuti tramite `position:absolute`, in modo che la dimensione sia dettata dal padre in `display:table-cell`. Questo permetterà agli elementi testuali al suo interno aventi `text-overflow:ellipsis` di non eccedere mai il contenitore centrale e di non influenzare gli elementi circostanti.

La `width:1%` applicata all’elemento `.top-bar-right` serve a limitare la larghezza rispetto ai contenuti interni, i quali se disposti come tag separati dovranno avere impostato `display:table-cell` per poter essere affiancati orizzontalmente.

```
html,
body,
#top-bar {
  font: 16px Arial;
  height:100%;
  margin:0;
  padding:0;
}

#top-bar {
  display:table;
  table-layout:auto;
  
  > * {
    display:table-cell;
    position:relative;
    text-align:center;
    vertical-align:middle;
  }
  
  .top-bar-left {
    width:40px;
  }
  .top-bar-middle {
    vertical-align:top;
  }
  .top-bar-right {
    width:1%;

    .action-overflow {
      display:table-cell;
    }
  }
}

.top-bar-outWrap {
  display:table;
  height:100%;
  position:absolute;
  table-layout:fixed;
  width:100%;
  
  .top-bar-inWrap {
    display:table-cell;
    vertical-align:middle;
    width:100%;
  }
}

.app-name {
  overflow:hidden;
  text-overflow:ellipsis;
  white-space:nowrap;
}
```

In questo frangente non sono necessari accorgimenti JavaScript di alcun tipo in quanto le larghezze vengono calcolate senza problemi nei vari browser.

## La barra dei comandi in basso allo schermo

Realizzare la barra dei comandi è relativamente semplice, sia in iOS che Android gli elementi che la compongono hanno una larghezza variabile che equivale alla larghezza del contenitore padre equamente distribuita tra i suoi figli :

```
<nav id="bottom-bar">
  
  <div class="bottom-elm">one</div>
  
  <div class="bottom-elm">two</div>
    
  <div class="bottom-elm">tree</div>
  
</nav>
```

```
html,
body,
#bottom-bar {
  font: 16px Arial;
  height:100%;
  margin:0;
  padding:0;
}

#bottom-bar {
  display:table;
  width:100%;
}

.bottom-elm {
  border-right:1px solid black;
  display:table-cell;
  text-align:center;
  vertical-align:middle;
  width: 1%;
  
  &:last-child {
    border-right:none;
  }
}
```

## Combinazione delle CSS table

Il risultato finale delle tre tecniche combinate ci restituisce una struttura flessibile sia in altezza che in larghezza, in cui i contenuti possono essere modificati di dimensione e numero senza rischiare di rompere nulla. Inoltre così facendo evitiamo di usare il `position:fixed` notoriamente instabile in diversi frangenti sui dispositivi mobili, e ci assicuriamo che la scrollbar dei contenuti corrisponda esattamente all’area dei contenuti stessi e non si estenda al resto della pagina.

 [](https://mastodon.social/share?text=http%3A%2F%2Fsresc.io%2F1c&title=CSS%20table%2C%20struttura%20base%20per%20il%20layout%20di%20una%20tipica%20app%20mobile)[](https://www.linkedin.com/sharing/share-offsite/?url=http%3A%2F%2Fsresc.io%2F1c)[](https://simonerescio.it/2014/06/css-table-struttura-base-layout-tipica-app-mobile)[](https://reddit.com/submit?url=http%3A%2F%2Fsresc.io%2F1c&title=CSS%20table%2C%20struttura%20base%20per%20il%20layout%20di%20una%20tipica%20app%20mobile)[](https://api.whatsapp.com/send?text=CSS%20table%2C%20struttura%20base%20per%20il%20layout%20di%20una%20tipica%20app%20mobile http%3A%2F%2Fsresc.io%2F1c)[](https://bsky.app/intent/compose?text=CSS%20table%2C%20struttura%20base%20per%20il%20layout%20di%20una%20tipica%20app%20mobile%20http%3A%2F%2Fsresc.io%2F1c)[](https://telegram.me/share/url?url=http%3A%2F%2Fsresc.io%2F1c&text=CSS%20table%2C%20struttura%20base%20per%20il%20layout%20di%20una%20tipica%20app%20mobile)[](https://www.facebook.com/sharer/sharer.php?u=http%3A%2F%2Fsresc.io%2F1c)

