3 soluciones para adaptar las tablas a todos los dispositivos con CSS

El elemento <table> de HTML es un poco rebelde a la hora de adaptarse a los dispositivos más pequeños.

Los profesionales de la maquetación o el diseño web lo sabemos y siempre estamos buscando soluciones para conseguir diseños adaptados a todos los dispositivos y es fácil encallarse cuando te topas con una tabla, sobre todo cuando esta tiene muchas columnas.

Hoy en día existen diversas soluciones para conseguir tablas con diseño adaptativo.

Quizá te has planteado el mero hecho de quitar el elemento <table> de tus diseños con HTML y CSS simplemente por este motivo de rebeldía.

Quizá no lo sabías pero las tablas fueron un elemento muy importante a la hora de diseñar páginas web.

Ya no solo por el simple hecho de mostrar una tabla con datos simples sino que por mucho tiempo fueron la estructura principal o cuerpo de la página web.

Hoy en día, esto es impensable y, doy gracias a dios, porque era bastante tedioso entender la lógica de una tabla en estructuras complejas.

Esto me hace viajar en el tiempo y recordar las peleas que llegué a tener en mis inicios cuando me topaba con tiendas online desarrolladas con Oscommerce.

Existiendo tantos elementos como los <div>, <section>, <nav>, etc, los elementos tipo <table> han quedado relegadas pero todavía siguen siendo útiles y en muchas páginas webs todavía te encontrarás tablas.

En este artículo vas a descubrir 3 formas de conseguir que una tabla se adapte a todos los dispositivos utilizando técnicas de CSS.

Estructura básica de la tabla

En el ejemplo en funcionamiento he creado una tabla con bastantes columnas.

A continuación puedes ver el código HTML de ejemplo:

<table>
    <thead>
        <tr>
            <th>Nombre</th>
            <th>Apellidos</th>
            <th>Email</th>
            <th>Edad</th>
            <th>Nómina</th>
            <th>Ingresos</th>
            <th>Gastos</th>
            <th>Beneficios</th>
            <th>Impuestos</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>Lorem</td>
            <td>Ipsum</td>
            <td>demo@demo.com</td>
            <td>56</td>
            <td>2.560€</td>
            <td>2.560€</td>
            <td>1.000€</td>
            <td>1.560€</td>
            <td>390</td>
        </tr>
        <tr>
            <td>Lorem</td>
            <td>Ipsum</td>
            <td>demo@demo.com</td>
            <td>56</td>
            <td>2.560€</td>
            <td>2.560€</td>
            <td>1.000€</td>
            <td>1.560€</td>
            <td>390</td>
        </tr>
        <tr>
            <td>Lorem</td>
            <td>Ipsum</td>
            <td>demo@demo.com</td>
            <td>56</td>
            <td>2.560€</td>
            <td>2.560€</td>
            <td>1.000€</td>
            <td>1.560€</td>
            <td>390</td>
        </tr>
    </tbody>
</table>

No deja de ser una tabla simple con 9 columnas y 3 filas para poder ver la ilustración sin necesidad de usar el scroll.

Estas 9 columnas nos harán ver que ocurre en dispositivos pequeños y que podemos hacer para remediarlo.

Estilos para la tabla

En la hoja de estilos CSS agrego algo de formato para la tabla:

table {
    border-spacing: 0;
    border-collapse: collapse;
    width: 800px;
    margin: 0px auto;
}
 
td, th {
    border: 1px solid #ccc;
    padding: 5px;
    text-align: left;   
}
 
tr:nth-child(even) {
    background-color: #eee;
}
 
td:nth-child(n + 3),
th:nth-child(n + 3) {
    text-align: center;
}
 
tbody tr:hover {
    background-color: aquamarine;
}
 
thead {
    background-color: black;
    color: white;
}

Para conseguir como resultado algo como lo que sigue:

Tabla con muchas columnas

Solución 1: Tabla responsive escondiendo columnas

Una solución rápida para que esta tabla se adapte a todos los dispositivos es decidir que columnas esconder en dispositivos más pequeños para que la tabla no se salga fuera de órbita.

Esto es bastante personal. En este punto vas a tener que decidir que columnas son menos importantes para no mostrarlas en dispositivos más pequeños.

Desde mi punto de vista, las columnas menos importantes son: email, edad, impuestos, apellidos y nómina.

Según he podido observar con la consola del navegador, aplicando 2 puntos de corte o media queries ya he conseguido que la tabla se vea bien en todos los dispositivos.

@media screen and (max-width: 920px) {
    table {
        width: 100%;
    }
 
    /* Ocultar edad */
    table tr th:nth-child(4),
    table tr td:nth-child(4) {
        display: none;
    }
 
    /* Ocultar email */
    table tr th:nth-child(3),
    table tr td:nth-child(3) {
        display: none;
    }
 
    /* Ocultar impuestos */
    table tr th:nth-child(9),
    table tr td:nth-child(9) {
        display: none;
    }
}
 
@media screen and (max-width: 767px) {
    /* Ocultar apellidos */
    table tr th:nth-child(2),
    table tr td:nth-child(2) {
        display: none;
    }
 
    /* Ocultar nómina */
    table tr th:nth-child(5),
    table tr td:nth-child(5) {
        display: none;
    }
}

En pantallas menores a 920px he empezado a detectar problemas que he solucionado ocultando la edad, el email y el impuesto.

En pantallas más pequeñas a 767px, he necesitado ocultar 2 más, en este caso, apellidos y nómina dejan de ser visibles.

Ver demo Descargar

Para mi gusto no es la solución más adecuada ya que esto implica ofrecer menos información a los usuarios que utilizan dispositivos pequeños.

Solución 2: Tabla responsive con scroll horizontal

Otra solución más rápida todavía es aplicar a la tabla un scroll horizontal empleando para ello una capa padre.

De esta forma, la tabla se muestra al mismo tamaño original pero el usuario tiene que desplazar el dedo para visualizar el contenido oculto que hay a la derecha ya que la tabla no se muestra de forma completa.

Visualmente, en dispositivos pequeños el usuario ve una barra de scroll horizontal como la siguiente:

Tabla responsive con scroll horizontal

Esto se consigue aplicando una capa por encima de la tabla.

En el ejemplo en funcionamiento he agregado el contenedor con class=»table-responsive» de la siguiente manera:

<div class="table-responsive">
    <table>
        <thead>
            <tr>
                <th>Nombre</th>
                <th>Apellidos</th>
                <th>Email</th>
                <th>Edad</th>
                <th>Nómina</th>
                <th>Ingresos</th>
                <th>Gastos</th>
                <th>Beneficios</th>
                <th>Impuestos</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>Lorem</td>
                <td>Ipsum</td>
                <td>demo@demo.com</td>
                <td>56</td>
                <td>2.560€</td>
                <td>2.560€</td>
                <td>1.000€</td>
                <td>1.560€</td>
                <td>390</td>
            </tr>
            <tr>
                <td>Lorem</td>
                <td>Ipsum</td>
                <td>demo@demo.com</td>
                <td>56</td>
                <td>2.560€</td>
                <td>2.560€</td>
                <td>1.000€</td>
                <td>1.560€</td>
                <td>390</td>
            </tr>
            <tr>
                <td>Lorem</td>
                <td>Ipsum</td>
                <td>demo@demo.com</td>
                <td>56</td>
                <td>2.560€</td>
                <td>2.560€</td>
                <td>1.000€</td>
                <td>1.560€</td>
                <td>390</td>
            </tr>
        </tbody>
    </table>
</div>

En la hoja de estilos CSS puedes agregar lo siguiente:

.table-responsive {
    display: block;
    width: 100%;
    overflow-x: auto;
}

La clave está en el overflow-x que establezco en automático para que el scroll horizontal aparezca si los datos que hay dentro ya no caben en el contenedor.

Ver demo Descargar

A pesar de ofrecerte esta solución que no parece del todo mala, debo decirte que no me acaba de convencer.  Me da la sensación de que no es del todo usable. Me gustaría ponérselo más fácil al usuario aunque me cueste más trabajo.

Solución 3: Tabla responsive convertida a contenedores en dispositivos pequeños

Conseguir esta solución requiere más tiempo pero me parece la más adecuada de todas ya que, en todas las resoluciones, la tabla se muestra de forma correcta y completa.

Esta solución consiste en disponer de la tabla original en pantallas de escritorio y para dispositivos más pequeños disponer de un contenedor para mostrar los datos de la tabla en 2 columnas: cabecera y datos.

En la estructura HTML, después del código de tu <table>, puedes agregar la estructura de la tabla usando contenedores.

<div class="table">
    <div class="item">
        <div class="row">
            <div class="thead">Nombre</div>
            <div class="tbody">Lorem</div>
        </div>
        <div class="row">
            <div class="thead">Apellidos</div>
            <div class="tbody">Ipsum</div>
        </div>
        <div class="row">
            <div class="thead">Email</div>
            <div class="tbody">demo@demo.com</div>
        </div>
        <div class="row">
            <div class="thead">Edad</div>
            <div class="tbody">56</div>
        </div>
        <div class="row">
            <div class="thead">Nómina</div>
            <div class="tbody">2.560€</div>
        </div>
        <div class="row">
            <div class="thead">Ingresos</div>
            <div class="tbody">2.560€</div>
        </div>
        <div class="row">
            <div class="thead">Gastos</div>
            <div class="tbody">1.000€</div>
        </div>
        <div class="row">
            <div class="thead">Beneficios</div>
            <div class="tbody">1.560€</div>
        </div>
        <div class="row">
            <div class="thead">Impuestos</div>
            <div class="tbody">390</div>
        </div>
    </div>
    <div class="item">
        <div class="row">
            <div class="thead">Nombre</div>
            <div class="tbody">Lorem</div>
        </div>
        <div class="row">
            <div class="thead">Apellidos</div>
            <div class="tbody">Ipsum</div>
        </div>
        <div class="row">
            <div class="thead">Email</div>
            <div class="tbody">demo@demo.com</div>
        </div>
        <div class="row">
            <div class="thead">Edad</div>
            <div class="tbody">56</div>
        </div>
        <div class="row">
            <div class="thead">Nómina</div>
            <div class="tbody">2.560€</div>
        </div>
        <div class="row">
            <div class="thead">Ingresos</div>
            <div class="tbody">2.560€</div>
        </div>
        <div class="row">
            <div class="thead">Gastos</div>
            <div class="tbody">1.000€</div>
        </div>
        <div class="row">
            <div class="thead">Beneficios</div>
            <div class="tbody">1.560€</div>
        </div>
        <div class="row">
            <div class="thead">Impuestos</div>
            <div class="tbody">390</div>
        </div>
    </div>
    <div class="item">
        <div class="row">
            <div class="thead">Nombre</div>
            <div class="tbody">Lorem</div>
        </div>
        <div class="row">
            <div class="thead">Apellidos</div>
            <div class="tbody">Ipsum</div>
        </div>
        <div class="row">
            <div class="thead">Email</div>
            <div class="tbody">demo@demo.com</div>
        </div>
        <div class="row">
            <div class="thead">Edad</div>
            <div class="tbody">56</div>
        </div>
        <div class="row">
            <div class="thead">Nómina</div>
            <div class="tbody">2.560€</div>
        </div>
        <div class="row">
            <div class="thead">Ingresos</div>
            <div class="tbody">2.560€</div>
        </div>
        <div class="row">
            <div class="thead">Gastos</div>
            <div class="tbody">1.000€</div>
        </div>
        <div class="row">
            <div class="thead">Beneficios</div>
            <div class="tbody">1.560€</div>
        </div>
        <div class="row">
            <div class="thead">Impuestos</div>
            <div class="tbody">390</div>
        </div>
    </div>
</div>

Se que la cabecera se repite en cada fila pero me lo vas a agradecer cuando veas el resultado final.

En cualquier caso, si esta tablas la armas de forma dinámica con un lenguaje de programación como PHP por ejemplo, podrás crear un código más dinámico y simple para generar este tipo de contenido.

Bien, en la hoja de estilos CSS, este nuevo contenedor que he agregado justo después de mi tabla lo ocultaré de entrada con:

div.table {
    display: none;
}

Luego, sabiendo que a partir de 920px de ancho es cuando se presentan los problemas con mi tabla original, puedo armar una media query como la siguiente:

@media screen and (max-width: 920px) {
    table {
        display: none;
    }
 
    div.table {
        display: block;
        width: 100%;
    }
 
    div.item {
        margin-bottom: 10px;
    }
 
    div.row {
        display: flex;
        justify-content: start;
        align-items: center;
        flex-direction: row;
    }
 
    div.tbody, div.thead {
        border: 1px solid #ccc;
        padding: 5px;
        text-align: left;
        width: 50%;
    }
 
    div.thead {
        background-color: #eee;
    }
}

Donde la tabla original que oculta y el contenedor se muestra al 100%.

Con la clase .row debes saber que la estoy usando para representar lo que sería en la tabla una fila.

Y la clase .item representa un elemento de la tabla.

Con un poco de maquetación y Flexbox puedo conseguir el siguiente efecto:

div tabla responsive

¿Atractivo y usable a la vez verdad?

Ver demo Descargar

Conclusiones

Quizá eres de mentalidad antigua pero te desaconsejo literalmente el uso de tablas para el diseño de las estructuras de tus páginas Webs. Te garantizo que será un dolor de cabeza adaptar una página web estructurada con tablas en los dispositivos más pequeños.

Utilizar contenedores y las técnicas más avanzadas de CSS tales como las media queries son las soluciones que te recomiendo en este momento.

El caso es que este no es el único inconveniente a usar tablas. Crear una estructura será más complicado y requerirá más código HTML. Lo que conlleva más peso para la carga y esto afectaría considerablemente al posicionamiento en buscadores.

A pesar de esto, no quiero darte a entender que debes olvidarte de las tablas por completo.

Las tablas HTML las puedes utilizar para presentar ordenadamente una serie de datos tales como una clasificación de equipos de fútbol, una lista de empleados, un lote de productos, etc pero, eso si, en dispositivos móviles deberás pensar en cual es la mejor solución para presentarlas de forma correcta.

Por cierto, ¿Cómo consigues que tus tablas se vean bien en dispositivos pequeños? ¿Conoces alguna técnica mejor?

Autor
Escrito por Jose Aguilar - Director ejecutivo y tecnológico en JA Modules. Experto programador PrestaShop y Experto programador WordPress.
Te ha servido? Valora esta entrada!
(2 votos, promedio: 5 de 5)
Comparte en las redes sociales
¿Buscas trabajo de programador?

Deja una respuesta

Tu dirección de correo electrónico no será publicada.

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

Ver más sobre