Saltar al contenido

Columnas de igual altura usando Javascript

Hoy mismo, en el trabajo, un compañero me ha preguntado por el método CSS para hacer que dos divs adyacentes tengan la misma altura. Como siempre, comencé a rascar en lo más hondo de mi cerebro, elucubrar teorías chorra, buscar en Internet, etc para, al final, reconocerle que no tenía ni idea 🙁

Estuve leyendo, no mucho tiempo os lo reconozco, sobre si había una propiedad de las hojas de estilo que hiciera esto y no encontré la fórmula mágica que buscaba. Encontraba soluciones utilizando JavaScript pero las desechabamos por la, quizas erronea, idea que el uso de Javascript no es compatible con la creación de páginas accesibles (no estoy del todo seguro de esto pero lo dejaremos para otra charla). Dentro de estas soluciones, otro compañero me remitió al código fuente de la página de inicio personalizada de Google del que os pongo las primeras líneas:

<style>
.modbox .el {display:;}
.modbox .csl, .modbox .es {display:none;}
.modbox_e .el {display:none;}
.modbox_e .csl, .modbox .es {display:;}
.dm {position:relative;width:1px;height:1px;}
.fres {width:expression(_gel("ffresults").offsetWidth+"px");overflow:hidden;}
</style>

Fijaros en la última línea, donde pone: width:expression(). Os lo reconozco, jamás había oido hablar de la utilización de Javascript, dentro de las hojas de estilo, para dar valor a ciertas propiedades (según tengo entendido está disponible desde IE5). Alucinado por el descubrimiento (¿con qué poco me contento, eh?) me decido a probarlo pero descubro que el método en cuestión no me funciona en Firefox y si en IE6.

Levemente decepcionado decido tirar por la calle de enmedio y acabar el proceso aunque sea utilizando Javascript. Y diréis, ¿por qué no utiliza alguna de las soluciones existentes? Y yo os digo, ¿por qué no usar una mia? Tras ver en el ejemplo de Google el uso de la propiedad offsetWidth, supongo que exista la equivalente offsetHeight, [1] y [2], decido crearlas sencillas funciones que se encargarán de igualar la altura de los divs que desee.

La función que se encarga de igualar los divs es altura(), que recibe como argumento los nombre -separados por comas- de los divs a tratar. Ló único que hace es averiguar cual es el div con mayor altura, y ese valor asignarselo a los demás.

 

function altura(){
  al = new Array(); max = 0;
	try{
	  if(document.getElementById){
		  for(i=0;i<arguments.length;i++){
			if(document.getElementById(arguments[i]))
			  al[i] = document.getElementById(arguments[i]).offsetHeight;
		  }
		  max = mayor(al);
		  if(max > 0){
			for(i=0;i<arguments.length;i++){
			  if(document.getElementById(arguments[i]))
				document.getElementById(arguments[i]).style.height = max + 'px';
			  }
		  }
	  }
	}
	catch (exc) {
	  alert("Se ha producido un error en la carga del CSS.");
	  throw exc;
	}
}

Y la función mayor() que calcula el mayor de entre los valores de una array.

 function mayor(datos){  
  salida = 0;  
  for(i=0;i<datos.length;i++){  
	  if(parseInt(datos[i]) > salida )  
	  	  salida = datos[i];  
  }  
  return salida;
}

Un ejemplo del uso de estas funciones sería, para el caso de querer igular dos divs llamados 'izq' y 'der':

<script type='text/javascript'>altura('izq', 'der');</script>

Para los que queráis ver todo esto en acción aquí tenéis un ejemplo


[1] http://msdn.microsoft.com/en-us/library/ms534199(VS.85).aspx
[2] http://developer.mozilla.org/en/docs/DOM:element.offsetHeight

21 comentarios

  1. Excelente!!!

    Justo se me había ocurrido que se podría solucionar de la forma que lo has planteado, pero…, no sé por qué, ya que adhiero a uno de los conceptos que tu citas acerca de usar soluciones existentes…, busqué en la web y apareció como por arte de magia tu solución la cual apliqué con excelentes resultados.

    Debo decirte también que originalmente le había escapado a esta solución javascript, aplicando a nivel hoja CSS overflow:hidden, pero la misma no me resultó aplicable en algunos casos, así que ¿¡es necesario ser tan purista!?, a veces…, ¿no deberíamos aplicar un conjunto de soluciones (heterogeneas) para lograr los resultados esperados?

    Muchas gracias.

    PD: fíjate que hay un errorcito en la función mayor(), yo finalmente apliqué las que usaste en la página de ejemplo…

  2. Gracias por comentar lo del error en la función mayor(), ya está solventado 🙂

    Sobre lo que comentas de ser puristas, en cada momento hemos de decidir que tecnología usamos y si sabemos el por qué de cada una de nuestra deciciones podremos estar tranquilos con nuestro trabajo. No tenemos que olvidar que hay tantas posibles soluciones a un problema como gente decida abordarlo.

  3. lucas lucas

    muchas gracias, muy buen recurso… te agradesco.

  4. horacio horacio

    EXCELENTE!!!!!!!!!!!!!!!!! QUE BUEN SCRIPT!!
    Sinceramente, no entendía como iba a funcionar si el script q igualaba estaba al final.. pero.. cada vez uno aprende mas…
    TE FELICITO DE VERDAD!!! LO MEJOR

  5. muchas gracias, tu función me ha quitado mil quebraderos de cabeza. Que pena que no exista posibilidad de hacer esto mediante css ¿no?

    soy bastante nuevo pero muy cabezón y hay cosas que estaría bien implementar en el css y a lo mejor existen pero no lo se.

    Por ejemplo
    El ancho con bordes,
    sería genial poder decir en css:
    width:100%-2px;
    border:1px black solid;

    o poder utilizar el resto de porcentaje combinando px y porcentajes.

    Por ejemplo (abrevio los float y demás)

    <div id=“izq” width:“50px”></div>
    <div id=“derecha” width=“100%-50px”></div>

    eso ayudaría mucho a la hora de adaptar.

    Lo mismo con height y con width.
    podría hacerse una función del tipo
    combinar_anchura (derecha, 50px)

    Gracias por vuestro código otra vez.

  6. Juanolon Juanolon

    Hola, yo justo tuve que hacer exactamente lo mismo como hace una semana. Y también lo resolví con js, pero en el camino tuve que hacer como 3 funciones más para que sea compatible con todos los browsers (para variar ie, opera y ff), como por ejemplo offsetHeight no da los mismos resultados en ie y ff, ya que al agregarle border o padding al div, la medida cambia.

    Muy interesante eso que en css se pueda usar js

    Saludos

  7. Que tal magnifica solucion. Actualmente me encuentro rediseñando y ajustando algunos aspectos de mi site yo habia intentado con margin negativo y padding y el overflow pero a la hora d usar anclajes el div se veia horrible pero con esta solucion todo es perfecto Gracias.

  8. Amigo:

    Muchas gracias, exelente solución a este problema
    MUCHO EXITOO, SALUDOS!!

  9. Florencia Alvado Florencia Alvado

    Millones de Gracias! lo único que encontré que me fué útil y muy sencillo de implementar.

  10. ArO ArO

    NO!!! Al igual que varios de nosotros, no soy un experto en el diseño de páginas web. Pasé horas buscando trucar de alguna forma el CSS para igualar la altura de las columnas.
    No sabés lo que agradezco haberme encontrado con este post.
    No tengo más que un GRACIAS para decirte.

    Es realmente un bien a la comunidad publicar este tipo de cosas.

    Saludos!

  11. Fer Fer

    Estoy montando una web a dos columnas en Textpattern (o sea el contenido es dinámico) y no me funciona la primera vez que carga la página pero si cuando vuelvo a recargar la página.
    O sea, el script trabaja cuando actualizamos nuevamente la página
    Que estaré haciendo mal ?
    Saludos y gracias

  12. Hola Fer,

    si nos dejas la URL donde podamos ver la Web o nos proporcionas el código HTML generado quizás podríamos ayudarte mejor. Si prefieres mándame un privado y hablamos 🙂

  13. Hola, la solucion esta muy bien, pero…
    No pasa el validator de W3c, es una mierda, pero muchos necesitamos codigo validado. No se puede tener todo ;-(

    gracias de todas formas

  14. Hola urkitos,
    el problema del Validador de la W3C era sencillo de resolver, se me había olvidado meter el código javascript dentro de las etiquetas CDATA (gracias por el aviso). Mira ahora a ver si te vale (Comprobación de la validación)

    Un saludo 🙂

  15. Alfonso Alfonso

    Simplemente… eso ya NO funciona.

  16. Hola Alfonso,

    gracias por el aviso, había un problema entre el CDATA y el código javascript. Si quieres saber más de por qué no se funcionaba aquí tienes este enlace: Javascript and XHTML

Deja una respuesta

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

Información básica sobre protección de datos Ver más

  • Responsable: Jorge Hoya.
  • Finalidad:  Moderar los comentarios.
  • Legitimación:  Por consentimiento del interesado.
  • Destinatarios y encargados de tratamiento:  No se ceden o comunican datos a terceros para prestar este servicio. El Titular ha contratado los servicios de alojamiento web a OVH que actúa como encargado de tratamiento.
  • Derechos: Acceder, rectificar y suprimir los datos.
  • Información Adicional: Puede consultar la información detallada en la Política de Privacidad.

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

Esta web utiliza cookies, puedes lees sobre ellas en la política de cookies    Ver política de cookies
Privacidad