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 elementohtml
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 HTMLBODY
o XHTMLbody
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 elementoBODY
lugar del elementoHTML
.
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?
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 elmargin-top
de un bloque con elmargin-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 elmargin-bottom
de un bloque con elmargin-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:
El posicionamiento esperado funciona en IE11. La brecha existe en Chrome y FF.
Si elimina la
position: relative
delbody
, el posicionamiento esperado funciona (como se probó en Chrome, FF e IE11). demoSi aplica solo 1px de
padding
albody
, también funciona con el navegador cruzado. demoSi 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; }
... y eliminando el margen predeterminado en el h1
:
h1 { margin: 0; }
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>