Tengo algunos elementos absolutamente posicionados:
span { display: block; } span.sub { color: blue; position: absolute; } <div> <span>Coffee</span> <span class="sub">Tea</span> <span class="sub">Milk</span> <span class="sub">Water</span> </div> ¿Cómo puedo evitar que se derrumben? Quiero que fluyan libremente sobre los elementos bajo div , como un menú de navegación desplegable. ¿Se puede lograr sin anidar los elementos posicionados dentro de un contenedor adicional?
Un enfoque podría ser usar white-space: pre; en div padre:
span { display: block; } span.sub { color: blue; position: absolute; } /* --------------------- */ :root { /* 1em is default font size */ --menu-bar-height: 1.3em; } body div { width: 200px; background-color: rgb(122, 213, 243); height: var(--menu-bar-height); white-space: pre; } span:first-child { margin-top: -2em; width: fit-content; background-color: rgb(48, 171, 212); } span.sub { margin-top: -2.4em; } /* cosmetic changes */ .sub:hover { border: 2px dotted blue; transform: translateX(10px); } .sub:nth-child(even) { background-color: lawngreen; } .sub:nth-child(odd) { background-color: tomato; } #second { width: 200px; height: 200px; background-color: wheat; text-align: center; z-index: -1; } <div> <span>Coffee</span> <span class="sub">Tea</span> <span class="sub">Milk</span> <span class="sub">Water</span> <span class="sub">Chocolate</span> </div> <div id="second">Div 2</div>
El siguiente es un enfoque más. Usando white-space: pre; en span: before pseudo elemento y agregando más líneas usando counter.
span { display: block; } span.sub { color: blue; position: absolute; } /* --------------------- */ @counter-style nuLine { system: symbolic; symbols: "\a"; } body div:first-child { width: 200px; counter-reset: lines; background-color: lightblue; flex-direction: column-reverse; } span.sub { height: 0px; margin-top: -1em; background-color: transparent; mix-blend-mode: multiply; } span.sub::before { counter-increment: lines; content: counter(lines, nuLine) counter(lines) ". "; white-space: pre; } span.sub::after { content: "\00a0"; width: 100%; position: absolute; left: 0px; opacity: .5; } /* cosmetic changes */ span:first-child { width: 200px; } .sub:hover { transform: translateX(10px); } .sub:hover::after { border: 2px dotted blue; } .sub:nth-child(even)::after { background-color: lawngreen; } .sub:nth-child(odd)::after { background-color: tomato; } #second { width: 200px; height: 200px; background-color: wheat; text-align: center; padding: 0px; margin: 0px; } <div> <span>Coffee</span> <span class="sub">Tea</span> <span class="sub">Milk</span> <span class="sub">Water</span> <span class="sub">Chocolate</span> </div> <div id="second">Div 2</div>También puedes hacer esto. Aplicar posicionamiento absoluto en el div principal. Esto hará que todo el elemento principal se posicione absolutamente sobre cualquier otro tipo de contenido, como un menú desplegable como mencionaste, mientras que el elemento secundario span normalmente dentro de este elemento.
div { position:absolute; } span { display: block; } span.sub { color: blue; } <div> <span>Coffee</span> <span class="sub">Tea</span> <span class="sub">Milk</span> <span class="sub">Water</span> </div>En primer lugar tenemos que entender algo.
Cuando usamos posición, generalmente necesitamos: position:relative para el elemento principal y position:absolute para los elementos secundarios.
Si le damos a los hijos position:absolute sin usar position:relative en el padre, estos hijos se posicionarán tomando como referencia la ventana, por lo que se posicionarán en la esquina izquierda/superior de la ventana, provocando así un colapso.
En segundo lugar, cuando usamos position:absolute , también debemos decirle al niño dónde lo queremos usando top, bottom, left, right verá en mi ejemplo.
si no los usamos, se colocarán en el mismo lugar, provocando un colapso.
Entonces, una vez explicado esto, aquí está mi solución, en mi opinión, no es la mejor manera de hacer un menú desplegable.
<div> <span>Coffee</span> <span class="sub">Tea</span> <span class="sub">Milk</span> <span class="sub">Water</span> </div>mi HTML es el mismo que querías.
div{ position: relative; } span { display: block; } span.sub { color: blue; position: absolute; } span.sub:nth-child(2){ left: 0; top: 20px; display: none; } span.sub:nth-child(3){ left: 0; top: 40px; display: none; } span.sub:nth-child(4){ left: 0; top: 60px; display: none; } span:first-child:hover ~ span{ display: block; } fíjate que uso left and top como dije antes.
En primer lugar, necesitamos el elemento padre, en este caso, el div debe ser position: relative porque esta es nuestra referencia.
nuestro lapso que contiene la palabra Coffee está posicionado como debería.
entonces es bastante simple, necesitamos apuntar a cada span.sub porque necesitan diferentes valores de posición para no colapsar, he usado pseudo-clases para apuntarlos, también puedes usar otra clase.
y para hacer un menú desplegable al pasar el mouse he terminado con esta línea span:first-child:hover ~ span{display: block;} cuando se pasa el mouse sobre el café, la visualización de todos los span.sub se cambiará a block para poder verlos.