Logo de islavisual
Isotipo de islavisual IslaVisual
imagen de sección

Ultima revisión 29/04/2013

Responsive Design: Tablas CSS3 II

Como os prometí, hoy haremos otro vistazo rápido a algunas técnicas para el diseño de formatos de tablas Responsive. Unas más utilizadas como el método unseen o olumna oculta y otras menos como el Flip Scroll o desplazamiento volteado pero, seguro, interesantes.

UNSEEN: Columna Oculta

Esta técnica, descrita por primera vez por Stuart Curry implica simplemente ir ocultando columnas de menor importancia en función de la resolución del dispositivo.

Explicamos el ejemplo:

  • Cuando estamos en resoluciones mayores de 800px se muestran todas las columnas de la tabla.
  • Cuando estamos en resoluciones comprendidas entre 640px y 800px se ocultará la columna segunda de la tabla.
  • Cuando estamos en resoluciones menores a 640px se ocultarán, además, las columnas cuarta, séptima y octava de la tabla.

<style>
    @media only screen and (max-width: 800px) {
        #unseen table td:nth-child(2),
        #unseen table th:nth-child(2) {display: none;}
    }

    @media only screen and (max-width: 640px) {
        #unseen table td:nth-child(4),
        #unseen table th:nth-child(4),
        #unseen table td:nth-child(7),
        #unseen table th:nth-child(7),
        #unseen table td:nth-child(8),
        #unseen table th:nth-child(8){display: none;}
    }
</style>
<div id="unseen">
    <table>
        <thead>
            <tr>
                <th>Code</th>
                <th>Company</th>
                <th class="numeric">Fecha</th>
                <th class="numeric">Producto</th>
                <th class="numeric">Valor %</th>
                <th class="numeric">Abierto</th>
                <th class="numeric">Alto</th>
                <th class="numeric">Bajo</th>
                <th class="numeric">Volumen</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>2010-04-04</td>
                <td>Arroz</td>
                <td class="numeric">1.38 €</td>
                <td class="numeric">-0.01</td>
                <td class="numeric">-0.36%</td>
                <td class="numeric">1.39 €</td>
                <td class="numeric">1.39 €</td>
                <td class="numeric">1.30 €</td>
                <td class="numeric">9,39</td>
            </tr>
        </tbody>
    </table>
</div>

FLIP SCROLL: Desplazamiento Volteado

Esta técnica fue publicada por primera vez por David Bushell y se basa en cambiar filas por columnas.

Explicamos el ejemplo:

  • Cuando estamos en resoluciones mayores de 800px se muestran todas las columnas de la tabla de manera normal.
  • Cuando estamos en resoluciones menores a 800px, cambia filas por columnas y se añade un scroll que permite ver todos los valores en el nuevo orden.

<style>
    @media only screen and (max-width: 800px) {
        #flip-scroll .cf:after { visibility: hidden; display: block; font-size: 0; content: " "; clear: both; height: 0; }
        #flip-scroll * html .cf { zoom: 1; }
        #flip-scroll *:first-child+html .cf { zoom: 1; }
        #flip-scroll table { width: 100%; border-collapse: collapse; border-spacing: 0; }
         
        #flip-scroll th,
        #flip-scroll td { margin: 0; vertical-align: top; }
        #flip-scroll th { text-align: left; }
        #flip-scroll table { display: block; position: relative; width: 100%; }
        #flip-scroll thead { display: block; float: left; }
        #flip-scroll tbody { display: block; width: auto; position: relative; overflow-x: auto; white-space: nowrap; }
        #flip-scroll thead tr { display: block; }
        #flip-scroll th { display: block; text-align: right; }
        #flip-scroll tbody tr { display: inline-block; vertical-align: top; }
        #flip-scroll td { display: block; min-height: 1.25em; text-align: left; }
         
        /* Tratamiento de los bordes */
        #flip-scroll th { border-bottom: 0; border-left: 0; }
        #flip-scroll td { border-left: 0; border-right: 0; border-bottom: 0; }
        #flip-scroll tbody tr { border-left: 1px solid #babcbf; }
        #flip-scroll th:last-child,
        #flip-scroll td:last-child { border-bottom: 1px solid #babcbf; }
    }
</style>
<div id="flip-scroll">
    <table>
        <thead>
            <tr>
                <th>Code</th>
                <th>Company</th>
                <th class="numeric">Fecha</th>
                <th class="numeric">Producto</th>
                <th class="numeric">Valor %</th>
                <th class="numeric">Abierto</th>
                <th class="numeric">Alto</th>
                <th class="numeric">Bajo</th>
                <th class="numeric">Volumen</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>2010-04-04</td>
                <td>Arroz</td>
                <td class="numeric">1.38 €</td>
                <td class="numeric">-0.01</td>
                <td class="numeric">-0.36%</td>
                <td class="numeric">1.39 €</td>
                <td class="numeric">1.39 €</td>
                <td class="numeric">1.30 €</td>
                <td class="numeric">9,39</td>
            </tr>
        </tbody>
    </table>
</div>

NO NORE TABLES: No más tablas

Esta técnica fue desarrollada por Chris Coyier y se basa en cambiar columnas por filas anidando todas las filas una detrás de otra. Es decir, si la tabla tiene 2 filas y 3 columnas, la adaptación se convertirá en 6 filas de 2 columnas.

<style>
    @media only screen and (max-width: 800px) {
        /* Forzamos la tabla a que muestre como bloques en vez de tablas */
        #no-more-tables table,
        #no-more-tables thead,
        #no-more-tables tbody,
        #no-more-tables th,
        #no-more-tables td,
        #no-more-tables tr {
            display: block;
        }
 
        /* Trasladamos la cabecera fuera de la pantalla, en vez de hacer un display:none, para que no afecte a la
           accesibilidad web */
            #no-more-tables thead tr {
            position: absolute;
            top: -9999px;
            left: -9999px;
        }
     
        #no-more-tables tr { border: 1px solid #ccc; }
     
        #no-more-tables td {
            /* Hacemos que las celdas se comporten como filas */
            border: none;
            border-bottom: 1px solid #eee;
            position: relative;
            padding-left: 50%;
            white-space: normal;
            text-align:left;
        }
     
        #no-more-tables td:before {
            /* Ahora hacemos el nuevo encabezado de la tabla y establecemos que los valores top y left hagan efecto de relleno */
            position: absolute;
            top: 6px;
            left: 6px;
            width: 45%;
            padding-right: 10px;
            white-space: nowrap;
            text-align:left;
            font-weight: bold;
        }
     
        #no-more-tables td:before { content: attr(data-title); }
    }
</style>
<div id="no-more-tables">
    <table>
        <thead>
            <tr>
                <th>Code</th>
                <th>Company</th>
                <th class="numeric">Fecha</th>
                <th class="numeric">Producto</th>
                <th class="numeric">Valor %</th>
                <th class="numeric">Abierto</th>
                <th class="numeric">Alto</th>
                <th class="numeric">Bajo</th>
                <th class="numeric">Volumen</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>2010-04-04</td>
                <td>Arroz</td>
                <td class="numeric">1.38 €</td>
                <td class="numeric">-0.01</td>
                <td class="numeric">-0.36%</td>
                <td class="numeric">1.39 €</td>
                <td class="numeric">1.39 €</td>
                <td class="numeric">1.30 €</td>
                <td class="numeric">9,39</td>
            </tr>
        </tbody>
    </table>
</div>

EXPERIMENTO RESPONSIVE: Tabla por lista

Se trata de convertir lo que sería una tabla en una lista para las resoluciones más bajas. Os dejo el código de ejemplo para que lo probéis.

En la imagen podéis ver como pasa de formato tabla aformsato lista.



En el ejemplo:

  • Cuando estamos en resoluciones mayores de 640px se muestra completa.
  • Cuando estamos en resoluciones de entre 480px y 640px se convierten los nombres de los días a 3 letras.
  • Cuando estamos en resoluciones menores a 480px se convierte (de forma visual) en lista.

<style>
    .calendar { width: 100%; font-size: 0.75em;/*12*/ line-height: 1.25em;/*15*/ border-collapse: collapse; border-spacing: 0; }
    
    .calendar th { text-align: left; }
    .calendar th span { display: none; }
    
    .calendar tr { display: block; }
    .calendar td,
    .calendar th { display: none; }
    
    .calendar .day { margin: 1em 0 .5em 0; font-weight: bold; }
    
    .calendar .events { display: block; }
    
    .calendar ul { display: block; list-style: none; margin: 0 1.25em 0 0;/*15*/ padding: 0; }
    .calendar li { display: block; position: relative; margin: 0; padding: 0; height: 1.25em;/*15*/ }
    .calendar li a { display: block; position: absolute; left: 0; right: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis;  }
    
    .calendar tr td:nth-of-type(1n) .day:before { content: 'Lunes '; }
    .calendar tr td:nth-of-type(2n) .day:before { content: 'Martes '; }
    .calendar tr td:nth-of-type(3n) .day:before { content: 'Miércoles '; }
    .calendar tr td:nth-of-type(4n) .day:before { content: 'Jueves '; }
    .calendar tr td:nth-of-type(5n) .day:before { content: 'Viernes '; }
    .calendar tr td:nth-of-type(6n) .day:before { content: 'Sábado '; }
    .calendar tr td:nth-of-type(7n) .day:before { content: 'Domingo '; }
    
    .calendar .prev-month,
    .calendar .next-month { display: none; }
    
    @media only screen and (min-width: 30em) { /*480*/
        .calendar tr { display: table-row; }
        .calendar th, .calendar td { display: table-cell !important; margin: 0; width: 14.2857%; padding: 0.4166em;/*10*/ border: 1px solid #babcbf; vertical-align: top; }
    
        .calendar .prev-month .day,
        .calendar .next-month .day { color: #bbb; }
    
        .calendar td .day { display: block; float: right; margin: 0; font-weight: normal; }
        .calendar td .day:before { display: none; }
        .calendar td .suffix { display: none; }
    
    }
    
    @media only screen and (min-width: 40em) { /*640*/
        /* show full days (e.g. "Mon" to "Monday") */
        .calendar th span { display: inline; }
    
    }
    
    @media only screen and (min-width: 40em) and (min-height: 20em) {
        .calendar td { height: 2.5em;/*30*/ }
    
    }
    @media only screen and (min-width: 40em) and (min-height: 40em) {
        .calendar td { height: 6.25em;/*75*/ }
    
    }
</style> 
<div>
    <table class="calendar">
        <thead>
            <tr>
                <th>Lunes</th>
                <th>Martes</th>
                <th>Miércoles</th>
                <th>Jueves</th>
                <th>Viernes</th>
                <th>Sábado</th>
                <th>Domingo</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td class="prev-month">
                    <h3 class="day"><span class="num">26<span class="suffix">th</span></span></h2>
                </td>
                <td class="prev-month">
                    <h3 class="day"><span class="num">27<span class="suffix">th</span></span></h2>
                </td>
                <td class="prev-month">
                    <h3 class="day"><span class="num">28<span class="suffix">th</span></span></h2>
                </td>
                <td class="prev-month">
                    <h3 class="day"><span class="num">29<span class="suffix">th</span></span></h2>
                </td>
                <td class="prev-month">
                    <h3 class="day"><span class="num">30<span class="suffix">th</span></span></h2>
                </td>
                <td class="prev-month">
                    <h3 class="day"><span class="num">31<span class="suffix">st</span></span></h2>
                </td>
                <td>
                    <h3 class="day"><span class="num">1<span class="suffix">st</span></span></h2>
                </td>
            </tr>
            <tr>
                <td>
                    <h3 class="day"><span class="num">2<span class="suffix">nd</span></span></h2>
                </td>
                <td class="events">
                    <h3 class="day"><span class="num">3<span class="suffix">rd</span></span></h2>
                    <ul>
                        <li><a href="/event/1/">Reunión con Carlos</a></li>
                        <li><a href="/event/2/">Entrevista de Trabajo</a></li>
                        <li><a href="/event/3/">Cena con Amigos</a></li>
                    </ul>
                </td>
                <td>
                    <h3 class="day"><span class="num">4<span class="suffix">th</span></span></h2>
                </td>
                <td>
                    <h3 class="day"><span class="num">5<span class="suffix">th</span></span></h2>
                </td>
                <td>
                    <h3 class="day"><span class="num">6<span class="suffix">th</span></span></h2>
                </td>
                <td>
                    <h3 class="day"><span class="num">7<span class="suffix">th</span></span></h2>
                </td>
                <td>
                    <h3 class="day"><span class="num">8<span class="suffix">th</span></span></h2>
                </td>
            </tr>
            <tr>
                <td class="events">
                    <h3 class="day"><span class="num">9<span class="suffix">th</span></span></h2>
                    <ul>
                        <li><a href="/event/4/">Comida con Primo Manuel</a></li>
                    </ul>
                </td>
                <td>
                    <h3 class="day"><span class="num">10<span class="suffix">th</span></span></h2>
                </td>
                <td>
                    <h3 class="day"><span class="num">11<span class="suffix">th</span></span></h2>
                </td>
                <td>
                    <h3 class="day"><span class="num">12<span class="suffix">th</span></span></h2>
                </td>
                <td>
                    <h3 class="day"><span class="num">13<span class="suffix">th</span></span></h2>
                </td>
                <td>
                    <h3 class="day"><span class="num">14<span class="suffix">th</span></span></h2>
                </td>
                <td>
                    <h3 class="day"><span class="num">15<span class="suffix">th</span></span></h2>
                </td>
            </tr>
            <tr>
                <td>
                    <h3 class="day"><span class="num">16<span class="suffix">th</span></span></h2>
                </td>
                <td>
                    <h3 class="day"><span class="num">17<span class="suffix">th</span></span></h2>
                </td>
                <td class="events">
                    <h3 class="day"><span class="num">18<span class="suffix">th</span></span></h2>
                    <ul>
                        <li><a href="/event/5/">Recoger reloj</a></li>
                    </ul>
                </td>
                <td class="events">
                    <h3 class="day"><span class="num">19<span class="suffix">th</span></span></h2>
                    <ul>
                        <li><a href="/event/6/">Ir de compras</a></li>
                    </ul>
                </td>
                <td>
                    <h3 class="day"><span class="num">20<span class="suffix">th</span></span></h2>
                </td>
                <td>
                    <h3 class="day"><span class="num">21<span class="suffix">st</span></span></h2>
                </td>
                <td>
                    <h3 class="day"><span class="num">22<span class="suffix">nd</span></span></h2>
                </td>
            </tr>
            <tr>
                <td>
                    <h3 class="day"><span class="num">23<span class="suffix">rd</span></span></h2>
                </td>
                <td>
                    <h3 class="day"><span class="num">24<span class="suffix">th</span></span></h2>
                </td>
                <td>
                    <h3 class="day"><span class="num">25<span class="suffix">th</span></span></h2>
                </td>
                <td>
                    <h3 class="day"><span class="num">26<span class="suffix">th</span></span></h2>
                </td>
                <td>
                    <h3 class="day"><span class="num">27<span class="suffix">th</span></span></h2>
                </td>
                <td>
                    <h3 class="day"><span class="num">28<span class="suffix">th</span></span></h2>
                </td>
                <td class="events">
                    <h3 class="day"><span class="num">29<span class="suffix">th</span></span></h2>
                    <ul>
                        <li><a href="/event/7/">Comida Familiar</a></li>
                    </ul>
                </td>
            </tr>
            <tr>
                <td>
                    <h3 class="day"><span class="num">30<span class="suffix">th</span></span></h2>
                </td>
                <td>
                    <h3 class="day"><span class="num">31<span class="suffix">st</span></span></h2>
                </td>
                <td class="next-month">
                    <h3 class="day"><span class="num">1<span class="suffix">st</span></span></h2>
                </td>
                <td class="next-month">
                    <h3 class="day"><span class="num">2<span class="suffix">nd</span></span></h2>
                </td>
                <td class="next-month">
                    <h3 class="day"><span class="num">3<span class="suffix">rd</span></span></h2>
                </td>
                <td class="next-month">
                    <h3 class="day"><span class="num">4<span class="suffix">th</span></span></h2>
                </td>
                <td class="next-month">
                    <h3 class="day"><span class="num">5<span class="suffix">th</span></span></h2>
                </td>
            </tr>
        </tbody>
    </table>
 </div>

Sobre el autor

Imagen de Pablo Enrique Fernández Casado
Pablo Enrique Fernández Casado

CEO de IslaVisual, Manager, Full Stack Analyst Developer y formador por cuenta ajena con más de 25 años de experiencia en el campo de la programación y más de 10 en el campo del diseño, UX, usabilidad web y accesibilidad web. También es escritor y compositor de música, además de presentar múltiples soft kills como la escucha activa, el trabajo en equipo, la creatividad, la resiliencia o la capacidad de aprendizaje, entre otras.

Especializado en proveer soluciones integrales de bajo coste y actividades de consultoría de Usabilidad, Accesibilidad y Experiencia de Usuario (UX), además de ofrecer asesoramiento en SEO, optimización de sistemas y páginas web, entre otras habilidades.