Filas alternativas de CSS: algunas filas ocultas

7 minutos de lectura

Avatar de usuario de Andy
Andy

Estoy tratando de diseñar una tabla para que cada fila sea de un color diferente (par/impar). Tengo el siguiente CSS:

#woo tr:nth-child(even) td {
    background-color: #f0f9ff;
}

#woo tr:nth-child(odd) td {
    background-color: white;
}

Sin embargo, algunas de mis filas se pueden ocultar y todavía me gustaría que las filas se alternaran. ¿Cómo puedo ajustar lo anterior para que parezca filas alternas, incluso si las filas que están una al lado de la otra no son necesariamente pares e impares?

  • Oculto las filas con “display: none”.

    – Andy

    4 de junio de 2011 a las 10:15

  • solo un rápido sin embargo: ¿es realmente necesario tener miles de filas? ¿No puedes usar la paginación?

    – Ionus Staicu

    4 de junio de 2011 a las 11:41

Avatar de usuario de Tadeck
Tadeck

Si está utilizando jQuery, puede emplear una de sus funciones, por ejemplo .filter(), para elegir solo los elementos que son visibles. Pero la clave aquí es un selector de CSS :visible.

Por ejemplo (ver jsfiddle):

jQuery('tr:visible:odd').css({'background-color': 'red'});
jQuery('tr:visible:even').css({'background-color': 'yellow'});

  • De hecho, probé esto, pero a medida que mi tabla crecía en tamaño, ya que siempre se agregaba, esto pareció paralizar a Firefox, por lo que estaba buscando una “solución” puramente CSS para ver si podía aliviar la carga de JS. en mi página.

    – Andy

    4 de junio de 2011 a las 10:15

  • Como dije, la clave aquí es el selector de CSS, pero probablemente no funcione en navegadores obsoletos, como versiones anteriores de IE (pruebe si funciona en los navegadores que desea admitir). Si la solución pura de solo CSS no lo satisface, solo queda agregar clases específicas por JS (probablemente alterando mi solución, sin embargo).

    – Tadeck

    4 de junio de 2011 a las 11:47

Dado que el “fenómeno de la raya perdida” solo ocurre si un extraño número de filas está oculto, puede salirse con la suya agregando un solo invisible fila de relleno dondequiera que se oculte un número impar de filas.

Row 1
Row 2
Row 3 (hidden)
Padding (hidden)
Row 4
Row 5

Si esto realmente es una buena solución, depende en gran medida de su código actual, por ejemplo, cómo crea la tabla y cómo se ocultan las filas.

Pero si sus tablas son enormes y se ocultan grandes porciones de filas consecutivas, esto funcionaría mucho mejor que una solución Javascript/jQuery.

  • Simplemente genial!!

    – Moti Korets

    11 de junio de 2019 a las 14:36

Avatar de usuario de Jeff Seifert
jeff seifert

Resolví este problema usando una imagen de fondo para la tabla que constaba de los dos colores alternativos. Esto hace que la solución CSS no sea del todo completa, ya que implica la creación de una imagen, pero debería escalar muy bien para tablas con miles de entradas.

La imagen de fondo en la codificación base64 a continuación es una imagen de 1×50 con los 25 píxeles superiores como un color y los 25 píxeles inferiores como el color alternativo.

table {
  border-collapse: collapse;
  background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAyCAIAAAASmSbdAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3wQbATAssXhCIwAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAAAYSURBVAjXY/j8/joTAwMDTfGXDzdpbQcATuQF2Ze0VigAAAAASUVORK5CYII=);
}
  
td {
   padding: 2px 4px;
   height: 21px;
}
<table>
    <tbody>
        <tr style="display: table-row;">
            <td>ANIMAL!!</td>
        </tr>
        <tr style="display: table-row;">
            <td>Beaker</td>
        </tr>
        <tr style="display: none;">
            <td>Bunsen Honeydew, Ph.D.</td>
        </tr>
        <tr style="display: table-row;">
            <td>Camilla the Chicken</td>
        </tr>
        <tr style="display: table-row;">
            <td>Dr. Julius Strangepork</td>
        </tr>
        <tr style="display: none;">
            <td>Dr. Teeth</td>
        </tr>
        <tr style="display: none;">
            <td>Floyd Pepper</td>
        </tr>
        <tr style="display: none;">
            <td>Gonzo</td>
        </tr>
        <tr style="display: table-row;">
            <td>Janice</td>
        </tr>
        <tr style="display: none;">
            <td>Miss Piggy</td>
        </tr>
        <tr style="display: none;">
            <td>Rizzo</td>
        </tr>
        <tr style="display: none;">
            <td>Robin the Frog</td>
        </tr>
        <tr style="display: table-row;">
            <td>Sam the Eagle</td>
        </tr>
        <tr style="display: table-row;">
            <td>Statler</td>
        </tr>
        <tr style="display: none;">
            <td>The Swedish Chef</td>
        </tr>
        <tr style="display: table-row;">
            <td>Waldorf</td>
        </tr>
        <tr style="display: none;">
            <td>Zoot</td>
        </tr>
    </tbody>
</table>

Me doy cuenta de que es muy tarde, pero me encontré con este mismo problema hoy y se me ocurrió una solución CSS pura usando un nth-child fórmula. No sé si se ajusta a su escenario exacto, pero si todas las demás filas están ocultas pero aún necesita que las filas visibles tengan colores alternos, esto funciona muy bien. El selector de CSS se ve así:

tr:nth-child(4n - 1) { background-color: grey; }

Aquí hay un violín mostrándolo en acción.

Esto hace cada otra fila visible gris. Para obtener más información sobre cómo funcionan estas fórmulas, Este es un gran tutorial.

Este es un problema difícil, acabo de pasar un tiempo jugando con los selectores CSS2 y 3, y no estoy seguro de que estemos allí todavía. Algo como esto debería ser posible, pero no funciona:

tr td {background-color:white;}
tr td:not([style="display:none"]):nth-of-type(even) {
    background-color:#f0f9ff;
}

<tr><td>1</td></tr>
<tr><td style="display:none">2</td></tr>
<tr><td>3</td></tr>

Parece que estás atascado con jQuery’s :visible extensión (no CSS nativo), pero si se está ejecutando lentamente, definitivamente pagina las filas como dice @Ionut.

  • Buena idea, pero no funciona porque nth-of-type no considera ningún otro selector, sino solo el elemento escribe. (En lenguaje XML, sería el nombre del nodo) Tal vez algún día tengamos un nth-of-selector-match seleccionador 🙂

    – Daniel Rikowski

    10 de octubre de 2013 a las 9:59

Esta pregunta puede ser antigua, pero cuando busqué una solución a ese problema, vine aquí e inspirado por la respuesta de Jeff Seifert, utilicé una imagen de fondo de degradado lineal repetitivo para tener una solución puramente basada en css:

tbody {
    background-image: repeating-linear-gradient(grey 0 2em, white 2em 4em);
}
tr {
    height: 2em;
}

El único inconveniente es que tendrá que especificar una altura para la fila de la tabla (y poner el mismo valor en la definición de degradado).

EDITAR: Esto solo funciona si todas las filas tienen la misma altura. Lamentablemente, la altura máxima no funciona para las filas de la tabla. Tengo dos soluciones a medias para eso:

  1. Evite que el texto se ajuste aplicando tr{white-space: nowrap;} – Todavía se debe tener cuidado con los elementos que no son de texto, el desbordamiento también podría convertirse en un problema

  2. envolver el <tr> contenido con otro elemento como un <div> y aplicar div{max-height:2em;} – Esto requiere cambios en el HTML y también necesita tratamiento de desbordamiento

  • Buena idea, pero no funciona porque nth-of-type no considera ningún otro selector, sino solo el elemento escribe. (En lenguaje XML, sería el nombre del nodo) Tal vez algún día tengamos un nth-of-selector-match seleccionador 🙂

    – Daniel Rikowski

    10 de octubre de 2013 a las 9:59

¿Ha sido útil esta solución?