tag posicionar posicionamiento posicion fija ejemplos div attribute html css css-position specifications

posicionar - title html css



¿Por qué top: 0 no funciona en elementos de posición absoluta en relación con el cuerpo? (5)

Como se mencionó, el bloque que contiene el elemento de posición superior de nivel superior es el body , ya que el body está relativamente posicionado. Cuando el margen del h1 collapses con el del body , el margen afecta al body y, a su vez, al elemento absolutamente posicionado que contiene. A la inversa, si el body no estuviera relativamente posicionado, el elemento absolutamente posicionado se anclaría al bloque de contención inicial y se pegaría a la parte superior de la ventana gráfica sin que se vieran afectados por ningún margen efectivo en el body (porque el body ya no es su bloque de contención).

En cuanto a por qué el fondo plateado sangra más allá del elemento del body , es por diseño :

3.11.1. El fondo del lienzo y el elemento raíz

El fondo del elemento raíz se convierte en el fondo del lienzo y su área de pintura de fondo se extiende para cubrir todo el lienzo. Sin embargo, todas las imágenes tienen un tamaño y una posición relativas al elemento raíz como si estuvieran pintadas solo para ese elemento. (En otras palabras, el área de posicionamiento del fondo se determina como para el elemento raíz). El elemento raíz no vuelve a pintar este fondo, es decir, el valor utilizado de su fondo es transparente.

3.11.2. El fondo del lienzo y el elemento HTML <body>

Para los documentos cuyo elemento raíz es un elemento HTML HTML o un elemento html XHTML: si el valor calculado de ''background-image'' en el elemento raíz es ''ninguno'' y su ''color de fondo'' es ''transparente'', los agentes de usuario deben en su lugar propagar los valores calculados de las propiedades de fondo del primer elemento HTML BODY o XHTML body child de ese elemento. Los valores utilizados de las propiedades de fondo de ese elemento BODY son sus valores iniciales, y los valores propagados se tratan como si estuvieran especificados en el elemento raíz. Se recomienda que los autores de documentos HTML especifiquen el fondo del lienzo para el elemento BODY lugar del elemento HTML .

El color de fondo predeterminado del elemento raíz siempre es transparent , por lo que establecer un color de fondo en el elemento html evita que el fondo plateado se desangre del elemento del body (y verá que el inspector no está mintiendo):

html { background-color: white; } body { position: relative; margin: 0; padding: 0; overflow: hidden; background-color: silver; } .absolute { position: absolute; top: 0; left: 0; width: 50px; height: 50px; background-color: darkblue; } .wrapper { position: relative; overflow:hidden; width: 50%; height: 200px; overflow: hidden; background-color: yellow; } .wrapper > .absolute { background-color: darkcyan; }

<div class="absolute"></div> <h1>Some title</h1> <div class="wrapper"> <div class="absolute"></div> <h1>Some title</h1> </div>

Puede ver en el código siguiente que el h1 empuja hacia abajo el cuerpo y el bloque absolutamente posicionado .absolute no se pega a la parte superior. Pero también puedes ver que el mismo bloque está pegado a la parte superior de su .wrapper principal. ¿Por qué?

No estoy preguntando cómo hacer ese truco; Sé cómo, por ejemplo, rellenar el margen a h1, o borrar a padre y así sucesivamente.

Sólo me interesa una cosa: ¿por qué el margen de h1 empuja hacia abajo el body , pero no está empujando hacia abajo .wrapper ?

body { position: relative; margin: 0; padding: 0; overflow: hidden; background-color: silver; } .absolute { position: absolute; top: 0; left: 0; width: 50px; height: 50px; background-color: darkblue; } .wrapper { position: relative; overflow:hidden; width: 50%; height: 200px; overflow: hidden; background-color: yellow; } .wrapper > .absolute { background-color: darkcyan; }

<div class="absolute"></div> <h1>Some title</h1> <div class="wrapper"> <div class="absolute"></div> <h1>Some title</h1> </div>

OK, voy a tratar de ser más claro. Si hace clic en el enlace de abajo, puede ver mi JSFiddle. Hay background-color: silver en la etiqueta del body . Cuando miro en el inspector de código, veo que la etiqueta del cuerpo comienza ligeramente más baja debido al margen h1. Pero background-color comienza en la parte superior. Esto significa que el inspector de códigos me está mintiendo, y el cuerpo comienza desde arriba. Pero, ¿por qué, entonces, un elemento de posición absoluta que es un hijo directo del body no comienza en la parte superior?

JSFiddle


Es porque los márgenes de colapso . Como deshabilitarlo, puedes leer algunos artículos / respuestas, por ejemplo, this .
Está utilizando overflow: hidden para .wrapper , y desactiva los márgenes de colapso para este bloque. De la especificación :

Los márgenes de una caja con ''desbordamiento'' que no sea ''visible'' no se colapsan con los márgenes de sus hijos.

Pero parece un overflow: hidden no funciona para <body> , porque si lo configuro
height: 0 / max-height: 0 tampoco funciona:

body { height: 0; max-height: 0; }

<div>Some test text</div>

Creo que es porque (de la especificación ):

Los UA deben aplicar la propiedad de ''desbordamiento'' establecida en el elemento raíz a la ventana gráfica. Cuando el elemento raíz es un elemento HTML "HTML" o un elemento XHTML "html", y ese elemento tiene un elemento HTML "BODY" o un elemento XHTML "cuerpo" como elemento secundario, los agentes de usuario deben aplicar la propiedad ''overflow'' desde el primer elemento secundario a la ventana gráfica, si el valor en el elemento raíz es "visible".

Es por eso que los márgenes entre <body> y la primera <h1> contraen (desde MDN ):

Padre y primer / último hijo
Si no hay borde, relleno, contenido en línea o espacio libre para separar el margin-top de un bloque con el margin-top de su primer bloque secundario, o sin borde, relleno, contenido en línea, altura , mínimo-alto o máximo - La altura para separar el margin-bottom de un bloque con el margin-bottom de su último elemento secundario, entonces esos márgenes colapsan. El margen colapsado termina fuera del padre.

Es por eso que los márgenes entre <html> y <body> no se colapsan (de la especificación ):

Los márgenes de la caja del elemento raíz no se colapsan.

También noté que si <html> tiene background-color predeterminado y <body> ha especificado background-color + margin , el color de fondo llena todo el espacio de <html> , por ejemplo:

html, body { height: 100%; } body { margin: 20px; background-color: yellow; }

Pero si establece background-color en <html> , funciona como un bloque normal, por ejemplo:

html, body { height: 100%; } html { background-color: red; } body { margin: 20px; background-color: yellow; }

Resumiendo, te recomiendo que uses this , o agregar otro envoltorio para <body> , por ejemplo:

body { margin: 0; padding: 0; } .body-wrapper { position: relative; overflow: hidden; background-color: silver; } .absolute { position: absolute; top: 0; left: 0; width: 50px; height: 50px; background-color: darkblue; } .wrapper { position: relative; width: 50%; height: 200px; overflow: hidden; background-color: yellow; } .wrapper > .absolute { background-color: darkcyan; }

<div class="body-wrapper"> <div class="absolute"></div> <h1>Some title</h1> <div class="wrapper"> <div class="absolute"></div> <h1>Some title</h1> </div> </div>


Esta es otra instancia del fenómeno conocido como MDN .

Intentaré explicar lo que está pasando:

Cuando mueve div.absolute con posición absoluta, lo saca del flujo del contenido. Esto hace que el primer h1 actúe como el primer hijo de su padre, que es el body en este caso.

El margen del h1 luego se colapsa fuera del cuerpo, debido al colapso del margen. Es por eso que top: 0; no está en la parte superior izquierda de la ventana gráfica. Está en la parte superior izquierda del body .

Si necesita que esto funcione, agregue un html {position: relative; overflow: hidden:} html {position: relative; overflow: hidden:} .


Este es un comportamiento interesante con poca documentación que se puede encontrar en línea (al menos en una búsqueda básica).

Comenzaré diciendo que no conozco la razón por la cual el cuadro posicionado absolutamente no se alinea con la esquina del body , como se esperaría. Pero aquí hay algunas observaciones:

  1. El posicionamiento esperado funciona en IE11. La brecha existe en Chrome y FF.

  2. Si elimina la position: relative del body , el posicionamiento esperado funciona (como se probó en Chrome, FF e IE11). demo

  3. Si aplica solo 1px de padding al body , también funciona con el navegador cruzado. demo

  4. Si agrega un borde al body , también funciona. demo

ACTUALIZAR

Como un complemento rápido a la respuesta aceptada de @BoltClock , este problema podría haberse ilustrado y comprendido fácilmente simplemente agregando un color de fondo al elemento raíz en el código original ...

html { background-color: red; }

demo

... y eliminando el margen predeterminado en el h1 :

h1 { margin: 0; }

demo


Esto se debe a que h1 tiene un margen predeterminado, que mantiene al body separado de h1 y de su hermano .absolute .

Así que todo lo que tienes que hacer es restablecer el margen en h1 , como hiciste para body :

Fragmento con cada margen restablecido.

body { position: relative; margin: 0; padding: 0; overflow: hidden; background-color: silver; } h1 { margin: 0; /*if you want to see full text, put this into the flow*/ position:relative; z-index:1; } .absolute { position: absolute; top: 0; left: 0; width: 50px; height: 50px; background-color: darkblue; } .wrapper { position: relative; overflow: hidden; width: 50%; height: 200px; overflow: hidden; background-color: yellow; } .wrapper > .absolute { background-color: darkcyan; }

<div class="absolute"></div> <h1>Some title</h1> <div class="wrapper"> <div class="absolute"></div> <h1>Some title</h1> </div>

Fragmento con cada margen sin reiniciar

body { position: relative; /* margin: 0; */ padding: 0; overflow: hidden; background-color: silver; } h1 { /* margin: 0; */ /*if you want to see full text, put this into the flow*/ position: relative; z-index: 1; } .absolute { position: absolute; top: 0; left: 0; width: 50px; height: 50px; background-color: darkblue; } .wrapper { position: relative; overflow: hidden; width: 50%; height: 200px; overflow: hidden; background-color: yellow; } .wrapper > .absolute { background-color: darkcyan; }

<div class="absolute"></div> <h1>Some title</h1> <div class="wrapper"> <div class="absolute"></div> <h1>Some title</h1> </div>