Hacer que div (altura) ocupe la altura restante del padre


107

http://jsfiddle.net/S8g4E/

Tengo un contenedor divcon dos niños. El primer niño tiene una altura determinada. ¿Cómo puedo hacer que el segundo niño ocupe el "espacio libre" del contenedor divsin darle una altura específica?

En el ejemplo, el rosa divdebería ocupar también el espacio en blanco.


Similar a esta pregunta: ¿Cómo hacer que div ocupe la altura restante?

Pero no quiero dar una posición absoluta .


Intenté también dar la altura del segundo niño al 100%, pero no funciona: jsfiddle.net/S8g4E/1
Alvaro

Respuestas:


156

La expansión del #downniño para llenar el espacio restante #containerse puede lograr de varias maneras dependiendo de la compatibilidad del navegador que desee lograr y si tiene o no #upuna altura definida.

Muestras

Cuadrícula

El griddiseño de CSS ofrece otra opción, aunque puede que no sea tan sencillo como el modelo Flexbox. Sin embargo, solo requiere diseñar el elemento contenedor:

.container { display: grid; grid-template-rows: 100px }

los grid-template-rows define la primera fila como una altura fija de 100px, y las filas restantes se estirarán automáticamente para llenar el espacio restante.

Estoy bastante seguro de que IE11 requiere -ms-prefijos, así que asegúrese de validar la funcionalidad en los navegadores que desea admitir.

Flexbox

El módulo de diseño de caja flexibleflexbox de CSS3 ( ) ahora está bien soportado y puede ser muy fácil de implementar. Por ser flexible, funciona incluso cuando #upno tiene una altura definida.

#container { display: flex; flex-direction: column; }
#down { flex-grow: 1; }

Es importante tener en cuenta que el soporte de IE10 e IE11 para algunas propiedades de flexbox puede tener errores, e IE9 o inferior no tiene ningún soporte.

Altura calculada

Otra solución fácil es usar la unidad funcional CSS3calc , como señala Álvaro en su respuesta , pero requiere que la altura del primer niño sea un valor conocido:

#up { height: 100px; }
#down { height: calc( 100% - 100px ); }

Tiene bastante soporte, con las únicas excepciones notables que son <= IE8 o Safari 5 (sin soporte) e IE9 (soporte parcial). Algunos otros problemas incluyen el uso de calc junto con transform o box-shadow , así que asegúrese de probar en varios navegadores si eso le preocupa.

Otras alternativas

Si se necesita un soporte más antiguo, puede agregar height:100%;para #downque el div rosa sea de altura completa, con una advertencia. Causará un desbordamiento del recipiente, porque lo #upestá empujando hacia abajo.

Por lo tanto, podría agregarlo overflow: hidden;al contenedor para solucionarlo.

Alternativamente, si la altura de #upes fija, puede colocarla absolutamente dentro del contenedor y agregarle una tapa acolchada #down.

Y otra opción más sería utilizar una pantalla de mesa:

#container { width: 300px; height: 300px; border: 1px solid red; display: table;}
#up { background: green; display: table-row; height: 0; }
#down { background: pink; display: table-row;}​

4
Me gustaría que #down tenga #container height - #up height. Así que el desbordamiento oculto no es lo que estoy buscando. Y tampoco quiero usar la posición absoluta. ¡Gracias!
Álvaro

@Alvaro, agregué otra opción, usando pantallas de tabla. La desventaja aquí es la compatibilidad. PS Un elemento posicionado absolutamente dentro de un contenedor con la position: relative;posición relativa al contenedor, no a la ventana. Entonces, esa debería ser una opción viable.
usuario

2
Table-row debería funcionar para usted, vea este jsFiddle para una prueba. El método de posición absoluta no podrá dar los mismos resultados que este violín, por lo que podemos tacharlo de la lista (#down y #container tendrán la misma altura en ese escenario).
usuario

3
Estás pidiendo mucho, @Alvaro. CSS no es un lenguaje de programación; no puede calcular cosas. Estás atrapado con ilusiones o js.
Jezen Thomas

1
@Quantastical, gracias por tu ayuda, pero en tu última edición simplemente copiaste la respuesta que publiqué. Algunos mencionarlo al menos sería bueno.
Álvaro

24

Han pasado casi dos años desde que hice esta pregunta. Se me ocurrió css calc () que resuelve este problema que tenía y pensé que sería bueno agregarlo en caso de que alguien tenga el mismo problema. (Por cierto, terminé usando la posición absoluta).

http://jsfiddle.net/S8g4E/955/

Aquí está el css

#up { height:80px;}
#down {
    height: calc(100% - 80px);//The upper div needs to have a fixed height, 80px in this case.
}

Y más información al respecto aquí: http://css-tricks.com/a-couple-of-use-cases-for-calc/

Soporte del navegador: http://caniuse.com/#feat=calc


1
Yo también he estado usando CSS3 calcdonde la compatibilidad con un navegador amplio no es tan importante (IE8 y versiones inferiores y Safari 5 no lo admiten).
usuario

3
¿Alguna forma de hacer algo similar con una #upaltura dinámica ?
Adam Waite

@AdamWaite, con una altura dinámica #up, querrá usar la solución de desbordamiento descrita en la otra respuesta.
usuario

5

Mi respuesta usa solo CSS y no usa overflow: hidden o display: table-row. Requiere que el primer niño realmente tenga una altura determinada, pero en su pregunta indica que solo el segundo niño debe tener su altura no especificada, por lo que creo que debería encontrar esto aceptable.

html

<div id="container">
    <div id="up">Text<br />Text<br />Text<br /></div>
    <div id="down">Text<br />Text<br />Text<br /></div>
</div>

css

#container { width: 300px; height: 300px; border:1px solid red;}
#up { background: green; height: 63px; float:left; width: 100% }
#down { background:pink; padding-top: 63px; height: 100%; box-sizing: border-box; }

http://jsfiddle.net/S8g4E/288/


2

ver la demostración - http://jsfiddle.net/S8g4E/6/

usar css -

#container { width: 300px; height: 300px; border:1px solid red; display: table;}
#up { background: green; display: table-row; }
#down { background:pink; display: table-row;}

Debe agregar height: 1pxpara #upasegurarse de que tome la cantidad mínima de altura. Aquí está el soporte del navegador para display: table: caniuse.com/css-table
thirtydot

¿Podría mostrarme cómo se puede lograr esta solución en este ejemplo "más complejo", por favor: jsfiddle.net/fyNX4 Muchas gracias
Alvaro

2

A menos que lo esté entendiendo mal, puede agregar height: 100%;y overflow:hidden;para #down.

#down { 
    background:pink; 
    height:100%; 
    overflow:hidden;
}​

Demo en vivo

Editar: Dado que no desea utilizar overflow:hidden;, puede utilizar display: table;para este escenario; sin embargo, no se admite antes de IE 8. ( display: table;soporte )

#container { 
    width: 300px; 
    height: 300px; 
    border:1px solid red;
    display:table;
}

#up { 
    background: green;
    display:table-row;
    height:0; 
}

#down { 
    background:pink;
    display:table-row;
}​

Demo en vivo

Nota: ha dicho que desea que la #downaltura sea la #containeraltura menos la #upaltura. La display:table;solución hace exactamente eso y este jsfiddle lo retratará con bastante claridad.


1
No quiero que #down exceda la # altura del contenedor
Alvaro

Solo me di cuenta de eso. Puede agregar overflow:hiddenpara ocultar el contenido adicional.
Josh Mein

1
Copiaré / pegaré lo que le dije a MrSlayer: Me gustaría que #down tenga #container height - #up height. Así que el desbordamiento oculto no es lo que estoy buscando. Y tampoco quiero usar la posición absoluta. ¡Gracias!
Alvaro

El problema con esto es que si revierte los dos divs en su ejemplo, entonces el div verde está afuera.
Ced

Esto no responde a la pregunta en absoluto. Dice "Para ocupar toda la altura restante", aunque esto ocupe toda la altura restante, habrá desbordamiento.
Giridhar Karnik

1

Puede usar flotantes para empujar el contenido hacia abajo:

http://jsfiddle.net/S8g4E/5/

Tienes un contenedor de tamaño fijo:

#container {
    width: 300px; height: 300px;
}

Se permite que el contenido fluya junto a un flotador. A menos que establezcamos el flotador en ancho completo:

#up {
    float: left;
    width: 100%;
}

Mientras #upy #downcomparte la posición superior, #downel contenido de 'solo puede comenzar después de la parte inferior del flotante #up:

#down {
    height:100%;
}​

Tenga en cuenta que en #uprealidad cubre la parte superior de #down: jsfiddle.net/thirtydot/S8g4E/9
thirtydot

Sí, así es como funciona. Pero si OP no necesita un borde redondeado o algo más elegante #up, entonces probablemente sea aceptable.
biziclop

Esta solución está cerca, pero me gustaría que #down tuviera #container height - #up height. (En su solución #down height = #container height). Gracias '
Alvaro

1
@Alvaro: ¿Por qué tiene que ser así? Esta solución parece correcta en la mayoría de los casos, incluso si es solo una ilusión.
thirtydot

Bueno, esta pregunta es un ejemplo simplificado de este ejemplo más "complejo": jsfiddle.net/fyNX4 No funcionaría, ¿no?
Alvaro

1

Resumen

No encontré una respuesta completamente satisfactoria, así que tuve que averiguarlo yo mismo.

Mis requisitos:

  • el elemento debe ocupar exactamente el espacio restante, ya sea cuando el tamaño de su contenido es menor o mayor que el tamaño del espacio restante (en el segundo caso, se debe mostrar la barra de desplazamiento );
  • la solución debería funcionar cuando se calcula la altura del padre y no se especifica ;
  • calc()no debe usarse ya que el elemento restante no debe saber nada sobre otros tamaños de elementos;
  • Se debe utilizar una técnica de diseño moderna y familiar , como cajas flexibles .

La solución

  • Convierta en cajas flexibles todos los padres directos con la altura calculada (si corresponde) y el siguiente padre cuya altura se especifique ;
  • Especifique flex-grow: 1a todos los padres directos con la altura calculada (si corresponde) y el elemento para que ocupen todo el espacio restante cuando el tamaño del contenido del elemento sea menor;
  • Especificar flex-shrink: 0a todos los elementos de flexión con altura fija para que no se reduzca al tamaño del contenido del elemento es más grande que el tamaño del espacio restante;
  • Especifique overflow: hiddena todos los padres directos con altura calculada (si corresponde) para deshabilitar el desplazamiento y prohibir la visualización de contenido desbordado;
  • Especificar overflow: autoque el elemento para permitir el desplazamiento en su interior.

JSFiddle (el elemento tiene padres directos con altura calculada)

JSFiddle (caso simple: sin padres directos con altura calculada)


-3

No estoy seguro de que se pueda hacer únicamente con CSS, a menos que se sienta cómodo fingiéndolo con ilusiones. Tal vez use la respuesta de Josh Mein y configúrelo #containerenoverflow:hidden .

Por lo que vale, aquí hay una solución jQuery:

var contH = $('#container').height(),
upH = $('#up').height();
$('#down').css('height' , contH - upH);

Gracias, estaba buscando una solución Css pura.
Alvaro
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.