Tutorial WordPress: Forzar el alto igual en tarjetas de productos con Flexbox

·

·

Introducción

En tiendas WordPress con WooCommerce (o con otros constructores que muestren rejillas de productos) es habitual que las tarjetas de producto queden desiguales en altura cuando los títulos, descripciones o etiquetas varían de longitud. Esto rompe la estética de la rejilla y dificulta la experiencia de usuario. La solución más elegante y robusta es usar Flexbox para que las tarjetas se comporten como columnas flexibles y el contenido que deba “empujar” (por ejemplo el botón de compra o el precio) quede alineado siempre en la parte inferior, mientras que el contenedor central ocupa el espacio disponible.

Resumen de la estrategia

Antes de empezar: identificar la estructura HTML

La mayoría de temas y WooCommerce usan una estructura similar a esta (simplificada):

  • Título del producto

    €99 Añadir
  • Si tu tema ya envuelve el contenido en un div tipo .product-inner o similar, es más fácil. Si no, puedes usar selectores directos (li.product gt a, li.product gt .price, etc.) o crear un pequeño override de plantilla para añadir un envoltorio.

    CSS recomendado (solución sin modificar plantilla)

    Este CSS transforma cada tarjeta en una columna flex y hace que el enlace principal (imagen título) ocupe el espacio flexible, empujando precio y botón hacia abajo.

    / Aplica a la rejilla de WooCommerce clásica. Ajusta selectores según tu tema /
    ul.products li.product {
      display: flex
      flex-direction: column
      height: 100%
      box-sizing: border-box
    }
    
    / Hace que el enlace principal (imagen   título) ocupe el espacio disponible /
    ul.products li.product > a {
      display: block
      flex: 1 1 auto
    }
    
    / Asegura que el título no haga salto inesperado y se muestre correctamente /
    ul.products li.product .woocommerce-loop-product__title {
      margin: .75rem 0 .5rem
      line-height: 1.2
    }
    
    / Mantén precio y botón en la parte inferior visual de la tarjeta /
    ul.products li.product .price,
    ul.products li.product .button {
      margin-top: 0.5rem
    }
    
    / Opcional: hacer el botón ancho para mejorar alineación visual /
    ul.products li.product .button {
      align-self: stretch
      text-align: center
    }
    

    Notas sobre este CSS

    Mejor práctica: añadir un envoltorio en la plantilla

    Si quieres una solución limpia y fiable, añade en tu child theme un envoltorio que agrupe imagen/título/descripción en un mismo bloque y deja precio/botón como pie. Para WooCommerce, copia y edita content-product.php en tu child theme. Ejemplo de fragmento PHP simplificado:

    ltli 
    

    Con este wrapper, el CSS para flexbox resulta más sencillo y robusto:

    / Con envoltorio .product-inner /
    ul.products li.product .product-inner {
      display: flex
      flex-direction: column
      height: 100%
    }
    
    .product-inner .product-link {
      flex: 1 1 auto
      display: block
    }
    
    .product-inner .product-meta {
      margin-top: .75rem
    }
    

    Compatibilidad responsive y consideraciones

    • En móviles, las tarjetas suelen apilarse verticalmente allí no es necesario forzar alturas iguales. Puedes limitar la aplicación de tu CSS a pantallas a partir de un ancho mínimo mediante media queries.
    • Si tu tema usa una rejilla basada en floats y con alturas automáticas, establecer ul.products como display:flex puede cambiar el comportamiento de respuesta. Procura probar antes o usar las reglas solamente para la clase de rejilla del loop del producto.
    • Evita forzar alturas fijas (height: 300px) salvo casos muy concretos flexbox permite mantener flexibilidad entre dispositivos.

    Ejemplo con media queries (para aplicar solo en pantallas grandes)

    @media (min-width: 768px) {
      ul.products li.product {
        display: flex
        flex-direction: column
        height: 100%
      }
    
      ul.products li.product > a {
        flex: 1 1 auto
      }
    }
    

    Solución alternativa: JavaScript para igualar alturas por fila

    Si por compatibilidad no puedes cambiar la plantilla y Flexbox produce problemas con el layout del tema, puedes usar un pequeño script que mida alturas por fila y aplique la máxima altura. Pega este script en tu archivo JS del tema o en un snippet que se cargue en páginas de tienda.

    / Ejemplo simple de equalize por fila /
    (function(){
      function equalizeProducts() {
        var items = document.querySelectorAll(ul.products li.product)
        if (!items.length) return
        // Resetear alturas
        items.forEach(function(i){ i.style.height = auto })
        // Agrupar por top (fila)
        var rows = {}
        items.forEach(function(item){
          var top = Math.round(item.getBoundingClientRect().top)
          rows[top] = rows[top]  []
          rows[top].push(item)
        })
        // Para cada fila aplicar la altura máxima
        Object.keys(rows).forEach(function(key){
          var max = 0
          rows[key].forEach(function(i){
            var h = i.offsetHeight
            if (h > max) max = h
          })
          rows[key].forEach(function(i){ i.style.height = max   px })
        })
      }
    
      window.addEventListener(load, equalizeProducts)
      window.addEventListener(resize, function(){
        clearTimeout(window._equalizeTimeout)
        window._equalizeTimeout = setTimeout(equalizeProducts, 150)
      })
    })()
    

    Problemas habituales y soluciones

    • Las tarjetas no se estiran: revisa que el contenedor padre no limite la altura o que el item no tenga display:inline-block. Asegura que el selector apunta al elemento correcto (inspección DOM).
    • Grid se rompe al usar flex en el padre: evita convertir el contenedor global en flex si el tema depende de floats o utiliza su propio grid en su lugar aplica display:flex sólo a cada tarjeta (li.product).
    • El botón queda en posición intermedia: confirma que el bloque que debe crecer tenga la regla flex:1 y que no haya márgenes colapsados que provoquen saltos. A veces es necesario ajustar padding/margin del título.

    Dónde añadir el CSS

    1. Apariencia → Personalizar → CSS Adicional (rápido y reversible).
    2. En el archivo style.css de tu child theme (preferible para producción).
    3. Usando un plugin de CSS personalizado o en el build de tu tema si usas preprocesadores.

    Resumen final

    Forzar alturas iguales en tarjetas de producto con Flexbox es una solución moderna, accesible y fácil de mantener. La clave es convertir cada tarjeta en una columna flex y hacer crecer el bloque central con flex:1 para que precio y botones queden alineados al fondo. Si el tema no permite ajustes directos, usar un pequeño script que iguale alturas por fila es una alternativa válida. Siempre prueba en distintos anchos y dispositivos antes de desplegar en producción.



    Leave a Reply

    Your email address will not be published. Required fields are marked *