Problema con el posicionamiento absoluto de capas
A veces el posicionamiento absoluto de capas es demasiado rígido, pues si la definición de pantalla cambia de un usuario a otro las capas pueden quedar colocadas en lugares donde no deseamos. He aquí una solución.
15/5/02 - He recibido una consulta en mi correo sobre colocación de capas de manera absoluta, pero en la que no nos importe la definición de la pantalla del usuario y otros ir y venir de los elementos HTML. Nuestro compañero expresó su duda de la siguiente manera:
Si trabajamos con position:absolute dando un left y un top funciona si tienes tu página alineada a la izquierda. Mi página está alineada en el centro, entonces lo que sucede es que dependiendo de la resolución de pantalla que tengas (ancho de 800px,1024px,etc) me baila toda la página y no cuadra nada.
Primero que todo, debemos saber que si trabajamos con el position relative las capas se colocan en el lugar donde aparecen dentro del código HTML. De este modo, si colocamos una capa con position relative dentro de una celda de una tabla, dicha capa aparecería dentro de la celda donde la estamos colocando, independientemente del lugar donde se sitúe la celda al cambiar la definición de la pantalla.
El problema de esta solución es que la capa haría crecer la celda de la tabla donde queremos colocarla (al igual que cualquier otro elemento HTML que colocásemos dentro de la tabla) y es muy probable que nuestro diseño no nos permita este hecho. Seguramente ya habrías notado este problema y si no es así te invito a que crees la capa que intentas colocar con el atributo position a relative para ver si con eso tu problema ya está resuelto.
En casi todos los casos, la capa que intentamos colocar va a tener que tener el position absolute, porque con relative no arreglamos totalmente el problema. Entonces volvemos a el problema inicial, que era situar la capa con position absolute en el lugar exacto, independientemente de la definición de pantalla.
La solución final que propongo pasa por aplicar algún truquillo. De hecho, estuve hace unos días preguntándome sobre esa cuestión y al final encontré la solución, aunque no se me ocurrió a mi, sino que la extraje de www.cross-browser.com.
La idea es un poco compleja y para su puesta en marcha debemos realizar una serie de acciones que, sinceramente, considero excesivas para un problema inicialmente sencillo. Así pues, que no asuste lo que voy a soltar a continuación, que luego trataré de explicarlo un poco mejor.
Nuestro esquema de trabajo consistirá en una capa con posición relativa, que nos servirá de "ancla" y otra con la posición absoluta, donde colocaremos el contenido final a mostrar en la capa.
La capa relativa la colocaremos en el lugar aproximado donde queramos que aparezca la capa absoluta. La capa absoluta la posicionaremos, una vez cargada la página, en un lugar próximo a la capa relativa. Por supuesto, estas acciones las vamos a tener que realizar con Javascript, que es el lenguaje que nos permite actualizar las posiciones de las capas dinámicamente.
Detenidamente
Decíamos que habría que colocar una capa relativa cercana al lugar donde tiene que aparecer la capa con position absolute. Insisto en que las capas relativas se colocan en el lugar donde las metemos dentro del código HTML, por lo que será fácil colocar la capa relativa en el lugar exacto y que este lugar sea válido para cualquier definición.
La segunda capa, la que tiene el contenido final, la pondremos inicialmente en una posición cualquiera y escondida, de manera que no se vea que está mal colocada. Una vez terminada de cargar la página, podremos acceder a la posición de la capa relativa, extrayendo sus valores top y left y colocándolos en los correspondientes top y left de la capa con posición absoluta. Una vez marcada la posición de la capa absoluta podemos volverla visible.
A la vista de la imagen siguiente, la capa con posición relativa la hemos colocado en el enlace. En realidad habría tres capas con posición relativa para poder posicionar otras tantas capas con posición absoluta. La parte que vemos sombreada de verde corresponde al espacio que abarcaría la capa relativa.
Su posición sería la que está marcada por el aspa roja que aparece en su esquina superior izquierda. Dicha posición depende del lugar donde aparezcan los enlaces en la página.
Luego, con Javascript deberíamos asignar la posición de la capa absoluta de una manera parecida a esta.
left de la capa absoluta = left de la capa relativa
top de la capa absoluta = top de la capa relativa + altura de la capa relativa
Podemos sumarle algún píxel más a la posición de la capa, si es que queremos moverla un poco abajo y a la derecha, tal como hemos visto en la imagen.
No pretendo en este artículo, muy a mi pesar y por falta de espacio y tiempo, explicar cómo se hacen esas operaciones de Javascript. Advierto que si no se conoce nada de Javascript va a ser imposible ponerse con una tarea tan tediosa como el manejo de capas. Si por el contrario, ya hemos tenido contacto con Javascript y DHTML anteriormente, no debería ser un problema realizar esas acciones.
Referencias Javascript
En DesarrolloWeb tenemos un par de manuales de Javascript, que sería necesario estudiar para empezar a introducirse en el lenguaje.
- Programación en Javascript I
- Programación en Javascript II
En el Taller de Javascript tenemos algún artículo sobre tratamiento dinámico de capas.
En el momento en el que escribo estas líneas no tenemos un manual de DHTML y tratamiento de capas completo, por lo que sería recomendable estudiarlo en alguno de los enlaces recomendados de nuestra sección de DHTML del buscador.
Seguir navegando a partir aquí:
+ 1 manual relacionado
+ 1 categoria relacionada
+ 12 comentarios (Añadir)
| Autoría, licencia y acciones sobre este artículo |
|
Informe de Miguel Angel Alvarez* Director de DesarrolloWeb.com
Atención: Contenido exclusivo de DesarrolloWeb.com. No reproducir. Copyright.
* Para consultas técnicas utilizar la lista de correo.
|
Manuales relacionados con este artículo
Categorias relacionadas
A través de las categorías de nuestro directorio se pueden encontrar otro tipo de recursos relacionados con este artículo:
+ Entrar en
DHTML
Comentarios de los visitantes
|
Los comentarios de los visitantes son para ampliar la información del artículo. Cualquiera puede participar.
|
| Se muestran 12 comentarios revisados |
Comentario de eyagos
10/8/02
Bueno, eso del javascript está muy bien, pero si lo que queremos es simplemente una capa con posición absoluta que se centre en la ventana del navegador, lo podemos hacer de una manera mucho más simple (y bastante curiosa por cierto):
Se trata de poner una capa con posiciones absolutas, pero sin especificarle ni la posición izquierda ni la posición superior. Estas las "heredará" automáticamente de una tabla que pondremos justo después de la capa (que estará fuera de la capa y que no tiene porque tener ningun contenido), a la que le daremos el mismo ancho que a la capa, y que centraremos en la página con el atributo align="center".
Como veis parece un poco estraño, pero funciona con IE6 y NS6. Si quereis ver como funciona, aquí teneis un ejemplo que he hecho yo (mirar el código fuente):
http://users.servicios.retecal.es/decodingtv/center_absolut_layer.htm
Comentario de Dr_Fasiko
09/4/03
Creo que una manera más sencilla de centrar el contenido de una capa (como eyagos hace referencia) es centrar el contenido y fijar el ancho al 100%, me explico:
Si lo que deseamos es centrar un contenido y ponerlo a cualquier altura, podemos realizar un proceso muy sencillo.
1.- Establecemos el ancho al 100% así a cualquier resolución siempre se adaptaría al ancho de pantalla.
2.- Le indicamos que centre el contenido, así, sea cual sea la resolución, siempre lo centrará.
3.- Establecemos el alto, ya que el alto es completamente independiente de la resolución que utilicemos.
Os pongo un ejemplo:
<div style="width: 100%; top: 220px; position: absolute; visibility: visible; z-index:10" align="center">
Espero que mi explicación os sirva de ayuda.
Dr. Fásiko - webmaster de
www.empanao.com
Comentario de Javivi
22/4/03
Hola gente, la mezcla de la solución que ha dado Dr_Fasiko y eyagos me ha solucionado el problema que tenía de que no se centraba ni tomaba el tamaño exacto que yo deseaba la capa, con esto me ha funcionado a la primera, era algo que lo había dejado casi por imposible por que no conozco tampoco mucho este entorno de programación, lo que he hecho ha sido introducir dentro de la capa una tabla con lo que quiero mostrar (con un ancho fijo la tabla), y la capa con un ancho del 100% y centrada en la página, así da igual el tamaño de la ventana o la configuración de la pantalla.
Un saludo y muchas gracias a todos.
Comentario de Kueik
04/12/03
GENIAL!, TREMENDAMENTE GENIAL. OS FELICITO! Porque creo sinceramente que éste era un problema que muchíssima gente tenía, entre ellos yo, por lo que os felicito de todas todas! hacia tiempo que no continuaba haciendo mi pagina web por motivos del trabajo, y hoy que ya he acabado los examenes, dios! me encuentro la solución al problema con la que la dejé. Simplemente genial!
Comentario de Roberto
14/1/04
A mí me parece realmente sencillo con JavaScript:
.-Creamos la capa con posición absoluta pero sin coordenadas.
.-Obtenemos el tamaño de la ventana, la dividimos entre dos y le restamos la mitad del ancho y/o alto de la capa.
.-Con onresize la podemos reescribir a cambiar el tamaño de la ventana.
//capa: 760*400
var x= Math.floor(document.body.clientWidth / 2) -380;
if(x<0){x=0;}
var y= Math.floor(document.body.clientHeight / 2) -200;
if(y<0){y=0;}
document.write('');
Con esto lo hago yo y ningún problema.
Espero haber sido de ayuda ;-)
Saludos
Roberto
Comentario de Danilo
01/11/04
Para centralizar una pagina basta con meter todo el contenido dentro de un div con estas caracteristas (solo cerrar la equtiqueta al final de la pagina) :
body {
margin:0;
padding:0;
background:#cccccc;
text-align:center; /* hack para el IE */
}
#tudo {
width: 760px;
margin-left:auto;
margin-right:auto;
padding: 10px;
text-align:left; /* "remedio" para el hack de IE */
Comentario de Guillermo
25/4/05
He encontrado la solución al problema. Más adelante copio unos scripts que te devuelven la posición exacta de un elemento, a partir de ahí se puede jugar
con las capas.
SOLUCIÓN DE LA WEB
http://www.quirksmode.org/js/findpos.html
function findPosX(obj)
{
var curleft = 0;
if (obj.offsetParent)
{
while (obj.offsetParent)
{
curleft += obj.offsetLeft
obj = obj.offsetParent;
}
}
else if (obj.x)
curleft += obj.x;
return curleft;
}
function findPosY(obj)
{
var curtop = 0;
if (obj.offsetParent)
{
while (obj.offsetParent)
{
curtop += obj.offsetTop
obj = obj.offsetParent;
}
}
else if (obj.y)
curtop += obj.y;
return curtop;
}
Comentario de Oscar
21/12/06
Yo tenía el problema de la web centrada y querer poner una capa en un punto concreto, y he conseguido ubicar la capa en donde quería y es válido para todas las resoluciones y todos los navegadores. <b>Sin javascript.</b> Ubico una capa "layer1" con posición absoluta anidada en una tabla (de esta forma "layer1" siempre aparecerá en el mismo punto, independientemente de la resolución). Después coloco la capa "layer2" (la que me interesa) anidada en "layer1" y le doy un "margin-left" en CSS para que se me separe de "layer 1" tanto como quiero. El top es independiente de la resolución... y ya está! Igual esto está mal, no soy un gran programador, pero me pareció interesante postearlo porque a mí me ha servido perfectamente. Saludos!!
Comentario de theblabla
07/2/07
Buenas tardes, me encontré con el mismo problema y la solución que le di fue la siguiente:
Pongamos el ejemplo de un formulario que consta de dos capas y que éstas están dentro de <div id="contenedor"></div>
El html seria algo asi:
<style type="text/css">
#capa1{
background-color:#CC6633;
position:relative;
left:10px;
top:10px;
height:250px;
z-index:1;
}
#capa2{
background-color:#3399CC;
position:relative;
top:-240px;/*<----Esta es toda la trama!!! */
left:10px;
height:250px;
z-index:2;
}
</style>
<div id="contenedor">
<div id="capa1">hola mundo</div>
<div id="capa2">adios mundo</div>
</div>
El tema de mostrar-ocultar es cosa del señor JS. Entonces le pedi que hiciese el trabajo sucio por mi (gracias señor JS :p ). Esto lo soporta Ie 6, FF 2.0, NS 8 (opera no lo tengo por aqui).
function showLayer(layerToShow, layerToHide){ document.getElementById(layerToShow).style.visibility="visible"; document.getElementById(layerToHide).style.visibility="hidden";
}
Comentario de Mario
18/5/07
Efectivamente, como ya lo han mencionado, me parece que la forma más sencilla de fijar las capas en una determinada posición es a través de una estructura de tablas. Despues de darle formato al sitio con tablas es posible ubicar una capa dentro de alguna celda con su propiedad position=relative, luego de esto es posible anidar otras capas (dentro de la capa relativa) como absolutas, el margen izquierdo y superior de las capas anidadas estara referenciado al punto superior izquierdo de la capa relativa o principal o madre (como gusten llamarle).
Una última observación es poner en cero los argumentos top y left de la capa relativa para que no se desplace de su posición original.
Este es el script que ilustra lo anterior:
<td width="570" bgcolor="#E7E6E9">
<div style="position: elative; width: 570px; height: 165px; z-index: 1; left: 0px; top: 0px" id="capa1">
<div style="position: absolute; width: 100px; height: 100px; z-index: 1; left: 10px; top: 10px" id="capa2">
xyz</div>
<p>x
</div>
</td>
Comentario de Jorge Padilla
29/8/07
Lo que tenemos que hacer es "anclar" la capa absoluta que queremos tener. Y para anclarla necesitamos una capa relativa. Me explico:
La capa relativa es la capa PADRE, que nos dará las coordenadas que necesitamos para posicionar la capa absoluta HIJO.
El concepto es que la capa HIJO es absoluta, pero no es absoluta a la página (es decir, no comienza en X=0;Y=0), si no que es absoluta a la capa en la que está anidada, a la capa PADRE (con coordenadas X=a;Y=b)
Ej:
<!--Esta es la capa PADRE, que nos va a dar las coordenadas-->
<div style="position: relative; width:150; height:165;; left:0; top:0" id="PADRE">
<a href="itinerarios.html" onmouseover="muestracapa('PADRE','HIJO')">Itinerarios de Viaje</a>
<!--Esta es la capa HIJO, que será absoluta y que colocaremos a continuación de nuestra capa PADRE por medio de JavaScript-->
<div style="position: absolute; width:auto;height:auto;background:red;visibility:hidden" id="HIJO">
NEW YORK<BR>MADRID<BR>LONDRES
</div>
</div>
Después de esto, hay que conseguir las coordenadas en las que queremos posicionar nuestra capa absoluta. Yo lo he hecho a la misma altura que la relativa y justo a la derecha donde termina menos un par de pixels, para que esté dentro de la celda.
<script>
function muestracapa(capa1,capa2)
{
var posicionX = parseInt(document.getElementById(capa1).style.left) + parseInt(document.getElementById(capa1).style.width) - 2;
var posicionY = parseInt(document.getElementById(capa1).style.top);
document.getElementById(capa2).style.top = posicionY;
document.getElementById(capa2).style.left = posicionX ;
document.getElementById(capa2).style.visibility = "visible";
}
</script>
Comentario de Victoria Plaza
12/9/07
Hola, me ha servido mucho este articulo, y para practicar he hecho una mini pagina con las dos posibilidades comentadas (usar una capa anclaje que contenga la capa dependiente, o usar cualquier otro objeto web como punto de referencia y calcular su posicion)
No se si resultara muy largo el codigo pero ahi va, listo para copiar y pegar.
<html >
<head>
<script>
/*Este script es un poco mas complicado pero sirve para cualquier capa
declarada dentro del body (no dentro de la capa anclaje!!)
Ademas con este script no necesitariamos una capa anclaje,
podriamos poner como punto de referencia cualquier imagen, celda, u objeto de
nuestra web */
function findPos(obj) { /*calcula la posicion de un objeto dentro de la web*/
var curleft = curtop = 0;
if (obj.offsetParent) {
curleft = obj.offsetLeft
curtop = obj.offsetTop
while (obj = obj.offsetParent) {
curleft += obj.offsetLeft
curtop += obj.offsetTop
}
}
return [curleft,curtop];
}
function start1() /*posiciona la capa dependiente*/
{
limpiar();
posicion= new Array();
var anclaje=document.getElementById("celda");
/* Para poner este punto de anclaje no necesitamos la capa relativa
yo he utilizado el objeto "celda" */
var submenu=document.getElementById("capaSubmenu1");
posicion=findPos(anclaje);
submenu.style.left=posicion[0] + 10 ;
submenu.style.top=posicion[1] + 40 ;
submenu.style.visibility="visible";
}
</script>
<script>
/*Este script es el mas sencillo, pero necesita que la capa dependiente
sea HIJO de la capa anclaje, es decir, que su codigo se encuentre interno a la capa anclaje */
function start2() /*posiciona la capa dependiente*/
{
limpiar();
var anclaje=document.getElementById("capaAnclaje");
var submenu=document.getElementById("capaSubmenu2");
submenu.style.left=anclaje.style.left +10 ;
submenu.style.top=anclaje.style.top +20 ;
submenu.style.visibility="visible";
}
</script>
<script>
/* oculta la capa */
function limpiar()
{
var submenu2=document.getElementById("capaSubmenu2");
var submenu1=document.getElementById("capaSubmenu1");
submenu1.style.visibility="hidden";
submenu2.style.visibility="hidden";
}
</script>
</head>
<body >
<table width=100% border="1"> <tr>
<td><a onClick="limpiar()">Quitar capa</a></td>
<td> <a id=celda>celda A </a>
<div id="capaAnclaje" style="position:relative"> Capa anclaje
<div id="capaSubmenu2" style="position:absolute; visibility:hidden">Capa2 bajo celda A</div>
</div>
</td>
<td> <a onClick="start1()" >Muestra capa1 con script1 </a></td>
<td> <a onClick="start2()"> Muestra capa2 con script2 </a></td>
</tr> </table>
<div id="capaSubmenu1" style="position:absolute; visibility:hidden">Capa1 bajo celda A</div>
</body>
</html>
Espero que sirva de resumen o aclaracion de todo este articulo
Ir arriba
Tienda DesarrolloWeb