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
- Convertir cada tarjeta de producto en un contenedor flex con dirección de columna.
- Hacer que el bloque principal de contenido interno crezca (flex: 1) para igualar alturas.
- Colocar elementos de acción (precio, botón) como elementos hermanos que queden al fondo de la tarjeta.
- Aplicar soporte responsive y arreglos en caso de temas con rejillas clásicas (floats) usando selectores seguros o pequeños ajustes de plantilla.
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ñadirSi 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
- El selector ul.products li.product puede variar según tu tema. Asegúrate de inspeccionar el HTML con las herramientas de desarrollador y ajustar.
- Si el tema usa un envoltorio como .product-inner, sustituye la regla al selector que corresponda (por ejemplo, .product .product-inner { display:flex flex-direction:column }).
- La propiedad height: 100% permite que columnas en contenedores flexibles (o grids con celdas iguales) ocupen la misma altura. Si la rejilla no está en un contexto que permita estirado, ver más abajo soluciones alternativas.
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:
ltliCon 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
- Apariencia → Personalizar → CSS Adicional (rápido y reversible).
- En el archivo style.css de tu child theme (preferible para producción).
- 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