jueves, 25 de septiembre de 2014

Tabla con Cabecera estática, Cuerpo con Scroll Vertical y Responsive

Estaba trabajando con Richfaces en un proyecto, cuando uno de los clientes pido un requerimiento especial para mostrar datos en un tabla y a su vez poder desplegar de cada fila una nueva tabla con los detalles de esta, y al vez tenia que ser Responsive ya que la aplicación puede ser accedida desde cualquier dispositivo. Vaya sorpresa cuando me di cuenta que Richfaces no tenia soporte para este componente, así que me puse en la tarea de desarrollarlo, en fin... uno de los problemas que me toco solucionar, fue hacer la cabecera de la tabla estática, y poder hacer scroll con el body y a la ves que la tabla fuera responsive , bueno vamos al código.

Primero tenemos nuestro html

<table>
    <thead>
        <tr>
            <th>Item #</th>
            <th>Description</th>
            <th>Quantity</th>
            <th>Price Unit</th>
            <th>Price Total</th>
        </tr>
    </thead>
    <tbody>
        <!--!important -->
        <tr >
            <td colspan="5"></td>
        </tr>
        <tr>
            <td>1</td>
            <td>Prod A1</td>
            <td>5</td>
            <td>USD 3.00</td>
            <td>USD 15.00</td>
        </tr>
        <tr>
            <td>2</td>
            <td>Prod B1</td>
            <td>5</td>
            <td>USD 3.00</td>
            <td>USD 15.00</td>
        </tr>
        <tr>
            <td>3</td>
            <td>Prod C1</td>
            <td>5</td>
            <td>USD 3.00</td>
            <td>USD 15.00</td>
        </tr>
        <tr>
            <td>4</td>
            <td>Prod D1</td>
            <td>5</td>
            <td>USD 3.00</td>
            <td>USD 15.00</td>
        </tr>
        <tr>
            <td>5</td>
            <td>Prod A1</td>
            <td>5</td>
            <td>USD 3.00</td>
            <td>USD 15.00</td>
        </tr>
        <tr>
            <td>6</td>
            <td>Prod B1</td>
            <td>5</td>
            <td>USD 3.00</td>
            <td>USD 15.00</td>
        </tr>
        <tr>
            <td>7</td>
            <td>Prod C1</td>
            <td>5</td>
            <td>USD 3.00</td>
            <td>USD 15.00</td>
        </tr>
        <tr>
            <td>8</td>
            <td>Prod D1</td>
            <td>5</td>
            <td>USD 3.00</td>
            <td>USD 15.00</td>
        </tr>
    </tbody>
</table>

El css


table{
    border-spacing: 0;
    display: flex;/*Se ajuste dinamicamente al tamano del dispositivo**/
    max-height: 40vh; /*El alto que necesitemos**/
    overflow-y: auto; /**El scroll verticalmente cuando sea necesario*/
    overflow-x: hidden;/*Sin scroll horizontal*/
    table-layout: fixed;/**Forzamos a que las filas tenga el mismo ancho**/
    width: 98vw; /*El ancho que necesitemos*/
    border:1px solid gray;
}

thead{
    background-color: #f1eee9;
    position: fixed !important;/*el thead va ser siempre estatico**/
}

th{
    border-bottom: 1px solid #c4c0c9;
    border-right: 1px solid #c4c0c9;
}

th,td{
    font-weight: normal;
    margin: 0;
    max-width: 18.5vw; /**Ancho por celda*/
    min-width: 18.5vw;/**Ancho por celda*/
    word-wrap: break-word;/*Si el contenido supera el tamano, adiciona a una nueve linea**/
    font-size: 11px;
    height: 3.5vh !important;/*El mismo alto para todas las celdas**/
    padding: 4px;
    border-right: 1px solid #c4c0c9;
}
tr:nth-child(2n) {
    background: none repeat scroll 0 0 #edebeb;
}   

Como podemos ver es un código muy sencillo, el truco esta en:
  1. Hacer la etiqueta <thead> con position fixed, para que el contenido siempre este estático
  2. Al poner el <thead> fixed, sobrepone la primera fila dentro de la etiqueta <tbody>, es decir el primer tr, entonces para no perder el primer registro usamos la primera fila (<tr>) vacia con un colspan igual al total de columnas, con el fin de que la hacer el head fixed, se sobreponga sobre la fila vacía y no perdamos ningún registro importante.
  3. Aseguramos de que todas las celdas tenga el mismo alto.
  4. Asegurarnos que las columnas tenga el mismo ancho.
  5. En este caso he usado las medidas viewport en lugar de porcentajes, también he usado la tabla con un alto máximo.
  6. Puedes ver el demo aquí.
Espero que les sirva, recuerden comentar, y si tienen preguntas, también.

4 comentarios:

  1. Tengo una duda, me funciono perfecto pero, en mi caso tambien necesito que los campos (thead) se muevan a la derecha ya que son bastantes, en ese caso como seria, de ante mano muchas gracias.

    ResponderEliminar
    Respuestas
    1. como te fue con tu inquietud , si la solucionaste, me colaboras. muchas gracias

      Eliminar
  2. buenas tarde , también tengo la misma inquietud, necesito que los campos (thead) se muevan a la derecha ya que son bastantes . muchas gracias

    ResponderEliminar