Hacer que el div posicionado absoluto expanda la altura div div

204

Como puede ver en el CSS a continuación, quiero child2posicionarme antes child1. Esto se debe a que el sitio que estoy desarrollando actualmente también debería funcionar en dispositivos móviles, en el que child2debería estar en la parte inferior, ya que contiene la navegación que quiero debajo del contenido en los dispositivos móviles. - ¿Por qué no 2 páginas maestras? Estos son los únicos 2 divsque se reposicionan en todo el HTML, por lo que 2 páginas maestras para este cambio menor es una exageración.

HTML:

<div id="parent">
    <div class="child1"></div>
    <div class="child2"></div>
</div>

CSS:

parent { position: relative; width: 100%; }
child1 { width: auto; margin-left: 160px; }
child2 { width: 145px; position: absolute; top: 0px; bottom: 0px; }

child2 tiene altura dinámica, ya que diferentes subsitios podrían tener más o menos elementos de navegación.

Sé que los elementos posicionados absolutos se eliminan del flujo, por lo que otros elementos los ignoran.
Traté de configurar overflow:hidden;el div padre, pero eso no ayudó, tampoco lo hace el clearfix.

Mi último recurso será JavaScript para reposicionar los dos en divsconsecuencia, pero por ahora intentaré ver si existe una forma de hacerlo que no sea JavaScript.

Micha Wiedenmann
fuente
3
No estoy 100% seguro, pero creo que probablemente tendrá que optar por una solución JS que resuelva la altura de child2 y mueva child1 en consecuencia.
Billy Moat
2
Esto se puede hacer estableciendo la posición del padre en relativa y el hijo en absoluto.
fungusanthrax
1
Vea esta solución, tal vez pueda ayudar.
Az.Youness

Respuestas:

153

Respondió la pregunta usted mismo: "Sé que los elementos posicionados absolutos se eliminan del flujo, por lo que otros elementos los ignoran". Por lo tanto, no puede establecer la altura de los padres de acuerdo con un elemento posicionado absolutamente.

Usted usa alturas fijas o necesita involucrar a JS.

feeela
fuente
1
Estoy marcando esto, ya que técnicamente es la forma correcta, aunque encontré otra solución a mi problema, que es prácticamente anidar el CSS requerido en las páginas específicas que tiene que diferenciarse (2 de 40 en este momento).
16

Aunque position: absoluteno es posible estirar a elementos con , a menudo hay soluciones en las que puede evitar el posicionamiento absoluto mientras obtiene el mismo efecto. Mire este violín que resuelve el problema en su caso particular http://jsfiddle.net/gS9q7/

El truco consiste en invertir el orden de los elementos flotando ambos elementos, el primero a la derecha, el segundo a la izquierda, de modo que el segundo aparece primero.

.child1 {
    width: calc(100% - 160px);
    float: right;
}
.child2 {
    width: 145px;
    float: left;
}

Finalmente, agregue un clearfix al padre y listo (vea el violín para la solución completa).

En general, siempre y cuando el elemento con posición absoluta esté posicionado en la parte superior del elemento padre, es muy probable que encuentre una solución flotando el elemento.

lex82
fuente
10

Feeela tiene razón, pero puede hacer que un padre sedivcontraiga / expanda a un elemento hijo si invierte sudivposición de esta manera:

.parent{
    postion: absolute;
    /* position it in the browser using the `left`, `top` and `margin` 
       attributes */
}

.child{
    position: relative;
    height: 100%;
    width: 100%;

    overflow: hidden;
    /* to pad or move it around using `left` and `top` inside the parent */
}

Esto debería funcionar para ti.

ChrisC
fuente
9

Hay una forma bastante simple de resolver esto.

Solo tiene que duplicar el contenido de child1 y child2 en divs relativos con display: none en parent div. Diga child1_1 y child2_2. Coloque child2_2 en la parte superior y child1_1 en la parte inferior.

Cuando su jquery (o lo que sea) llame al div absoluto, solo configure el div relativo relativo (child1_1 o child2_2) con display: block AND visibilidad: oculto. El hijo relativo seguirá siendo invisible, pero aumentará el div de los padres.

MMB
fuente
2
Esto me hizo pensar en la dirección correcta. En la visualización de la configuración de mi caso: ninguno en el contenido del "titular de tamaño" hace que el div no sea de tamaño, sin embargo, la opacidad: 0, dimensiona el div correctamente y no requiere ningún jquery adicional.
edencorbin
La forma en que lo hice fue obtener dos divisiones duplicadas, la primera es el contenido visible con posición absoluta y la segunda es una división con visibilidad oculta que mantiene la división principal con la altura correcta, todo funciona bien = D
Diogo García
4

Con JavaScript puro, solo necesita recuperar la altura de su static position elemento hijo .child1utilizando el método getComputedStyle () y luego establecer ese valor de recuperación como padding-toppara el mismo hijo utilizando la propiedad HTMLElement.style .


Verifique y ejecute el siguiente fragmento de código para obtener un ejemplo práctico de lo que describí anteriormente:

/* JavaScript */

var child1 = document.querySelector(".child1");
var parent = document.getElementById("parent");

var childHeight = parseInt(window.getComputedStyle(child1).height) + "px";
child1.style.paddingTop = childHeight;
/* CSS */

#parent { position: relative; width: 100%; }
.child1 { width: auto; }
.child2 { width: 145px; position: absolute; top: 0px; bottom: 0px; }
html, body { width: 100%;height: 100%; margin: 0; padding: 0; }
<!-- HTML -->

<div id="parent">
    <div class="child1">STATIC</div>
    <div class="child2">ABSOLUTE</div>
</div>

AndrewL64
fuente
3

Esta pregunta se hizo en 2012 antes de flexbox. La forma correcta de resolver este problema usando CSS moderno es con una consulta de medios y una inversión de columna flexible para dispositivos móviles. No se necesita posicionamiento absoluto.

https://jsfiddle.net/tnhsaesop/vjftq198/3/

HTML:

<div class="parent">
  <div style="background-color:lightgrey;">
    <p>
      I stay on top on desktop and I'm on bottom on mobile
    </p>
  </div>
  <div style="background-color:grey;">
    <p>
      I stay on bottom on desktop and I'm on bottom on mobile
    </p>
  </div>
</div>

CSS:

.parent {
  display: flex;
  flex-direction: column;
}

@media (max-width: 768px) {
  .parent {
    flex-direction: column-reverse;
  }
}
Hunter Nelson
fuente
2

Tuve un problema similar. Para resolver esto (en lugar de calcular la altura del iframe usando el cuerpo, el documento o la ventana) creé un div que envuelve todo el contenido de la página (un div con un id = "página" por ejemplo) y luego usé su altura.

Juliano
fuente
1

Se me ocurrió otra solución, que no me encanta pero hace el trabajo.

Básicamente duplicar los elementos secundarios de tal manera que los duplicados no sean visibles.

<div id="parent">
    <div class="width-calc">
        <div class="child1"></div>
        <div class="child2"></div>
    </div>

    <div class="child1"></div>
    <div class="child2"></div>
</div>

CSS:

.width-calc {
    height: 0;
    overflow: hidden;
}

Si esos elementos secundarios contienen poco marcado, entonces el impacto será pequeño.

btx9000
fuente
44
Esto puede dar algunos problemas con el ranking del motor de búsqueda
Mschadegg
1

"Usted usa alturas fijas o necesita involucrar a JS".

Aquí está el ejemplo de JS:

---------- Ejemplo de jQuery JS --------------------

    function findEnvelopSizeOfAbsolutelyPositionedChildren(containerSelector){
        var maxX = $(containerSelector).width(), maxY = $(containerSelector).height();

        $(containerSelector).children().each(function (i){
            if (maxX < parseInt($(this).css('left')) + $(this).width()){
                maxX = parseInt($(this).css('left')) + $(this).width();
            }
            if (maxY < parseInt($(this).css('top')) + $(this).height()){
                maxY = parseInt($(this).css('top')) + $(this).height();
            }
        });
        return {
            'width': maxX,
            'height': maxY
        }
    }

    var specBodySize = findEnvelopSizeOfAbsolutelyPositionedSubDivs("#SpecBody");
    $("#SpecBody").width(specBodySize.width);
    $("#SpecBody").height(specBodySize.height);
Nikolay
fuente
Esta respuesta podría beneficiarse de una mejor explicación y dirección de la solución propuesta.
DaniDev
1

Hay un truco muy simple que soluciona este problema

Aquí hay un codeandbox que ilustra la solución: https://codesandbox.io/s/00w06z1n5l

HTML

<div id="parent">
  <div class="hack">
   <div class="child">
   </div>
  </div>
</div>

CSS

.parent { position: relative; width: 100%; }
.hack { position: absolute; left:0; right:0; top:0;}
.child { position: absolute; left: 0; right: 0; bottom:0; }

puedes jugar con la posición del hack div para afectar dónde se ubica el niño.

Aquí hay un fragmento:

html {
  font-family: sans-serif;
  text-align: center;
}

.container {
  border: 2px solid gray;
  height: 400px;
  display: flex;
  flex-direction: column;
}

.stuff-the-middle {
  background: papayawhip
    url("https://camo.githubusercontent.com/6609e7239d46222bbcbd846155351a8ce06eb11f/687474703a2f2f692e696d6775722e636f6d2f4e577a764a6d6d2e706e67");
  flex: 1;
}

.parent {
  background: palevioletred;
  position: relative;
}

.hack {
  position: absolute;
  left: 0;
  top:0;
  right: 0;
}
.child {
  height: 40px;
  background: rgba(0, 0, 0, 0.5);
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
}
    <div class="container">
      <div class="stuff-the-middle">
        I have stuff annoyingly in th emiddle
      </div>
      <div class="parent">
        <div class="hack">
          <div class="child">
            I'm inside of my parent but absolutely on top
          </div>
        </div>
        I'm the parent
        <br /> You can modify my height
        <br /> and my child is always on top
        <br /> absolutely on top
        <br /> try removing this text
      </div>
    </div>

bernatfortet
fuente
0

Hay una mejor manera de hacer esto ahora. Puedes usar la propiedad inferior.

    .my-element {
      position: absolute;
      bottom: 30px;
    }
rlasch
fuente
55
esto funcionará solo si conoce la altura final del padre, que no
conoce
0

Esto es muy similar a lo que sugirió @ChrisC. No está utilizando un elemento posicionado absoluto, sino uno relativo. Tal vez podría funcionar para ti

<div class="container">
  <div class="my-child"></div>
</div>

Y tu CSS como este:

.container{
    background-color: red;
    position: relative;
    border: 1px solid black;
    width: 100%;
}

.my-child{
    position: relative;
    top: 0;
    left: 100%;
    height: 100px;
    width: 100px;
    margin-left: -100px;
    background-color: blue;
}

https://jsfiddle.net/royriojas/dndjwa6t/

roy riojas
fuente
0

Considere también el siguiente enfoque:

CSS:

.parent {
  height: 100%;
}
.parent:after {
  content: '';
  display: block;
}

Además, dado que está intentando reposicionar divs, considere la cuadrícula CSS

Iegor Benzyk
fuente
-2

Las vistas absolutas se posicionan frente al antepasado más cercano que no está posicionado estáticamente ( position: static), por lo tanto, si desea una vista absoluta posicionada contra un padre determinado, establezca el padre positionen relativey el hijo positionenabsolute

Isaac Sekamatte
fuente
-4

Intenta esto, me funcionó

.child {
    width: 100%;
    position: absolute;
    top: 0px;
    bottom: 0px;
    z-index: 1;
}

Establecerá la altura del niño a la altura del padre

Sarath E
fuente
gran solución!
Alexander Cherednichenko el
3
@AlexanderCherednichenko No realmente, se pierde el punto de la pregunta.
wickywills