Saltar al contenido

Tabla HTML con 100% de ancho, con desplazamiento vertical dentro de tbody

Solución:

Para poder hacer <tbody> elemento desplazable, necesitamos cambiar la forma en que se muestra en la página, es decir, usando display: block; para mostrar eso como un elemento de nivel de bloque.

Desde que cambiamos el display propiedad de tbody, deberíamos cambiar esa propiedad por thead elemento también para evitar que se rompa el diseño de la mesa.

Entonces tenemos:

thead, tbody { display: block; }

tbody {
    height: 100px;       /* Just for the demo          */
    overflow-y: auto;    /* Trigger vertical scroll    */
    overflow-x: hidden;  /* Hide the horizontal scroll */
}

Los navegadores web muestran thead y tbody elementos como grupo de filas (table-header-group y table-row-group) por defecto.

Una vez que cambiamos eso, el interior tr los elementos no llenan todo el espacio de su contenedor.

Para arreglar eso, tenemos que calcular el ancho de tbody columnas y aplique el valor correspondiente a la thead columnas a través de JavaScript.

Columnas de ancho automático

Aquí está la versión jQuery de la lógica anterior:

// Change the selector if needed
var $table = $('table'),
    $bodyCells = $table.find('tbody tr:first').children(),
    colWidth;

// Get the tbody columns width array
colWidth = $bodyCells.map(function() {
    return $(this).width();
}).get();

// Set the width of thead columns
$table.find('thead tr').children().each(function(i, v) {
    $(v).width(colWidth[i]);
});    

Y aquí está la salida (en Windows 7 Chrome 32):

desplazamiento vertical dentro de tbody

DEMO DE TRABAJO.

Tabla de ancho completo, columnas de ancho relativo

Como necesitaba el póster original, podríamos expandir el table al 100% de width de su contenedor, y luego usando un relativo (Porcentaje) width para cada columna de la tabla.

table {
    width: 100%; /* Optional */
}

tbody td, thead th {
    width: 20%;  /* Optional */
}

Dado que la mesa tiene una (especie de) diseño fluido, debemos ajustar el ancho de thead columnas cuando el contenedor cambia de tamaño.

Por lo tanto, deberíamos establecer el ancho de las columnas una vez que se cambia el tamaño de la ventana:

// Adjust the width of thead cells when *window* resizes
$(window).resize(function() {
    /* Same as before */ 
}).resize(); // Trigger the resize handler once the script runs

La salida sería:

Mesa de fluidos con desplazamiento vertical dentro de tbody

DEMO DE TRABAJO.


Compatibilidad con navegadores y alternativas

Probé los dos métodos anteriores en Windows 7 a través de las nuevas versiones de los principales navegadores web (incluido IE10 +) y funcionó.

Sin embargo, no funciona correctamente en IE9 y versiones anteriores.

Eso es porque en un diseño de tabla, todos los elementos deben seguir las mismas propiedades estructurales.

Mediante el uso display: block; Para el <thead> y <tbody> elementos, hemos roto la estructura de la tabla.

Rediseño del diseño a través de JavaScript

Un enfoque consiste en rediseñar el diseño (completo) de la tabla. Usar JavaScript para crear un nuevo diseño sobre la marcha y manejar y / o ajustar los anchos / alturas de las celdas de forma dinámica.

Por ejemplo, eche un vistazo a los siguientes ejemplos:

  • jQuery .floatThead () complemento (un complemento de encabezado de tabla flotante / bloqueado / adhesivo)
  • jQuery Mesa desplazable enchufar. (código fuente en github)
  • jQuery .FixedHeaderTable () complemento (código fuente en github)
  • Tablas de datos desplazamiento vertical ejemplo.

Mesas nido

Este enfoque utiliza dos tablas anidadas con un div contenedor. El primero table tiene solo una celda que tiene un div, y la segunda tabla se coloca dentro de esa div elemento.

Consulte las tablas de desplazamiento vertical en Juego CSS.

Esto funciona en la mayoría de los navegadores web. También podemos hacer la lógica anterior de forma dinámica a través de JavaScript.

Tabla con encabezado fijo en scroll

Dado que el propósito de agregar una barra de desplazamiento vertical a la <tbody> está mostrando la mesa encabezamiento en la parte superior de cada fila, podríamos posición los thead elemento para quedarse fixed en la parte superior de la pantalla.

Aquí hay un Demo de trabajo de este enfoque realizado por Julien.
Tiene un soporte de navegador web prometedor.

Y aqui un CSS puro implementación por Willem Van Bockstal.


La solución Pure CSS

Aquí está la vieja respuesta. Por supuesto, agregué un nuevo método y refiné las declaraciones CSS.

Mesa con ancho fijo

En este caso, el table debería tener un fijo width (incluida la suma de los anchos de las columnas y el ancho de la barra de desplazamiento vertical).

Cada columna debe tener un especifico ancho y el última columna de thead elemento necesita un mayor ancho que es igual a los demás ancho + el ancho de barra de desplazamiento vertical.

Por tanto, el CSS sería:

table {
    width: 716px; /* 140px * 5 column + 16px scrollbar width */
    border-spacing: 0;
}

tbody, thead tr { display: block; }

tbody {
    height: 100px;
    overflow-y: auto;
    overflow-x: hidden;
}

tbody td, thead th {
    width: 140px;
}

thead th:last-child {
    width: 156px; /* 140px + 16px scrollbar width */
}

Aquí está el resultado:

Mesa con ancho fijo

DEMO DE TRABAJO.

Mesa con 100% de ancho

En este enfoque, el table tiene un ancho de 100% y para cada th y td, El valor de width la propiedad debe ser menor que 100% / number of cols.

Además, necesitamos reducir la ancho de thead como valor del ancho de barra de desplazamiento vertical.

Para hacer eso, necesitamos usar CSS3 calc() función, de la siguiente manera:

table {
    width: 100%;
    border-spacing: 0;
}

thead, tbody, tr, th, td { display: block; }

thead tr {
    /* fallback */
    width: 97%;
    /* minus scroll bar width */
    width: -webkit-calc(100% - 16px);
    width:    -moz-calc(100% - 16px);
    width:         calc(100% - 16px);
}

tr:after {  /* clearing float */
    content: ' ';
    display: block;
    visibility: hidden;
    clear: both;
}

tbody {
    height: 100px;
    overflow-y: auto;
    overflow-x: hidden;
}

tbody td, thead th {
    width: 19%;  /* 19% is less than (100% / 5 cols) = 20% */
    float: left;
}

Aquí está el Demostración en línea.

Nota: Este enfoque fallar si el contenido de cada columna rompe la línea, es decir el contenido de cada celda debe ser lo suficientemente corto.


A continuación, hay dos ejemplos sencillos de solución CSS pura que creé en el momento en que respondí esta pregunta.

Aquí está el jsFiddle Demo v2.

Versión antigua: jsFiddle Demo v1

En la siguiente solución, la mesa ocupa el 100% del contenedor principal, no se requieren tamaños absolutos. Es CSS puro, se utiliza un diseño flexible.

Así es como se ve:
ingrese la descripción de la imagen aquí

Posibles desventajas:

  • la barra de desplazamiento vertical siempre está visible, independientemente de si es necesaria;
  • el diseño de la tabla es fijo: las columnas no cambian de tamaño de acuerdo con el ancho del contenido (aún puede establecer el ancho de columna que desee explícitamente);
  • hay un tamaño absoluto: el ancho de la barra de desplazamiento, que es de aproximadamente 0,9 em para los navegadores que pude comprobar.

HTML (abreviado):

<div class="table-container">
    <table>
        <thead>
            <tr>
                <th>head1</th>
                <th>head2</th>
                <th>head3</th>
                <th>head4</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>content1</td>
                <td>content2</td>
                <td>content3</td>
                <td>content4</td>
            </tr>
            <tr>
                <td>content1</td>
                <td>content2</td>
                <td>content3</td>
                <td>content4</td>
            </tr>
            ...
        </tbody>
    </table>
</div>

CSS, con algunas decoraciones omitidas para mayor claridad:

.table-container {
    height: 10em;
}
table {
    display: flex;
    flex-flow: column;
    height: 100%;
    width: 100%;
}
table thead {
    /* head takes the height it requires, 
    and it's not scaled when table is resized */
    flex: 0 0 auto;
    width: calc(100% - 0.9em);
}
table tbody {
    /* body takes all the remaining available space */
    flex: 1 1 auto;
    display: block;
    overflow-y: scroll;
}
table tbody tr {
    width: 100%;
}
table thead, table tbody tr {
    display: table;
    table-layout: fixed;
}

código completo en jsfiddle

Mismo código en MENOS para que pueda mezclarlo en:

.table-scrollable() {
  @scrollbar-width: 0.9em;
  display: flex;
  flex-flow: column;

  thead,
  tbody tr {
    display: table;
    table-layout: fixed;
  }

  thead {
    flex: 0 0 auto;
    width: ~"calc(100% - @{scrollbar-width})";
  }

  tbody {
    display: block;
    flex: 1 1 auto;
    overflow-y: scroll;

    tr {
      width: 100%;
    }
  }
}

En los navegadores modernos, simplemente puede usar css:

th {
  position: sticky;
  top: 0;
  z-index: 2;
}
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *