CSS: expande la altura DIV flotante del niño a la altura de los padres

451

Tengo la estructura de la página como:

<div class="parent">
    <div class="child-left floatLeft">
    </div>

    <div class="child-right floatLeft">
    </div>
</div>

Ahora, el child-leftDIV tendrá más contenido, por lo que parentla altura del DIV aumenta según el DIV secundario.

Pero el problema es que la child-rightaltura no aumenta. ¿Cómo puedo hacer que su altura sea igual a su padre?

Veera
fuente
2
Simple. Fácil. Columnas de igual altura con Flexbox .
Michael Benjamin

Respuestas:

459

Para el parentelemento, agregue las siguientes propiedades:

.parent {
    overflow: hidden;
    position: relative;
    width: 100%;
}

entonces para .child-rightestos:

.child-right {
    background:green;
    height: 100%;
    width: 50%;
    position: absolute;
    right: 0;
    top: 0;
}

Encuentre resultados más detallados con ejemplos CSS aquí y más información sobre columnas de igual altura aquí .

Sotiris
fuente
14
Su CSS produce un comportamiento indefinido: la altura de los padres depende de la altura de los niños, pero los niños tienen una altura porcentual definida en términos de los padres: esto no es válido y es probable que no funcione de manera cruzada.
Eamon Nerbonne
1
Veo que no está flotando todo, por lo que se define a costa de no escalar si alguna vez la columna derecha crece más que la izquierda (que de hecho no es el caso en la pregunta del OP).
Eamon Nerbonne
44
Sí, debe agregar esto: padding-bottom: 32768px; margen inferior: -32768px; a los ninos.
Michael
3
Esto funciona siempre que se garantice que la columna derecha tenga menos contenido que la izquierda o se recortará. También edité la respuesta para omitir las declaraciones inútiles.
Christoph
3
@MatthewBlackford: es un "truco" ya que evita el colapso del margen. Puede evitar el colapso del margen de otras maneras, como usar un borde transparente de 1 px, pero en esencia, pero lo importante aquí es que evite el colapso del margen. No usaría esta solución, excepto como último recurso, ya que causa errores de diseño extraños y recortes inesperados (o contenido superpuesto) cuando sus suposiciones resultan ser defectuosas. En resumen: no desea hacer esto a menos que realmente lo necesite.
Eamon Nerbonne
206

Una solución común a este problema utiliza posicionamiento absoluto o flotadores recortados, pero estos son difíciles ya que requieren un ajuste exhaustivo si las columnas cambian en número + tamaño, y que debe asegurarse de que su columna "principal" sea siempre la más larga. En cambio, le sugiero que use una de las tres soluciones más robustas:

  1. display: flex: con mucho, la solución más simple y mejor y muy flexible, pero no es compatible con IE9 y versiones anteriores.
  2. tableo display: table: muy simple, muy compatible (casi todos los navegadores), bastante flexible.
  3. display: inline-block; width:50% con un corte de margen negativo: bastante simple, pero los bordes inferiores de la columna son un poco complicados.

1) display:flex

Esto es realmente simple y es fácil adaptarse a diseños más complejos o más detallados, pero flexbox solo es compatible con IE10 o posterior (además de otros navegadores modernos).

Ejemplo: http://output.jsbin.com/hetunujuma/1

HTML relevante:

<div class="parent"><div>column 1</div><div>column 2</div></div>

CSS relevante:

.parent { display: -ms-flex; display: -webkit-flex; display: flex; }
.parent>div { flex:1; }

Flexbox tiene soporte para muchas más opciones, pero para tener simplemente cualquier número de columnas, ¡lo anterior es suficiente!

2. <table>odisplay: table

Una manera simple y extremadamente compatible de hacer esto es usar un table: te recomiendo que lo pruebes primero si necesitas soporte para IE antiguo . Estás lidiando con columnas; divs + flotantes simplemente no son la mejor manera de hacerlo (sin mencionar el hecho de que múltiples niveles de divs anidados solo para hackear las limitaciones de css es apenas más "semántico" que simplemente usar una tabla simple). Si no desea utilizar el tableelemento, considere cssdisplay: table (no compatible con IE7 y versiones anteriores).

Ejemplo: http://jsfiddle.net/emn13/7FFp3/

HTML relevante: (pero considere usar un plano en su<table>lugar)

<div class="parent"><div>column 1</div><div>column 2</div></div>

CSS relevante:

.parent { display: table; }
.parent > div {display: table-cell; width:50%; }
/*omit width:50% for auto-scaled column widths*/

Este enfoque es mucho más robusto que el uso overflow:hiddencon flotadores. Puede agregar prácticamente cualquier número de columnas; puede hacer que escalen automáticamente si lo desea; y conserva la compatibilidad con los navegadores antiguos. A diferencia de lo que requiere la solución flotante, tampoco es necesario saber de antemano qué columna es la más larga; la altura escala muy bien.

BESO: no uses hacks de flotación a menos que lo necesites específicamente. Si IE7 es un problema, aún elegiría una tabla simple con columnas semánticas sobre una solución de truco-CSS difícil de mantener y menos flexible cualquier día.

Por cierto, si necesita que su diseño sea receptivo (por ejemplo, sin columnas en teléfonos móviles pequeños), puede usar una @mediaconsulta para recurrir al diseño de bloque simple para anchos de pantalla pequeños; esto funciona si usa <table>o cualquier otro display: tableelemento.

3. display:inline blockcon un truco de margen negativo.

Otra alternativa es usar display:inline block.

Ejemplo: http://jsbin.com/ovuqes/2/edit

HTML relevante: (¡la ausencia de espacios entre lasdivetiquetas es significativa!)

<div class="parent"><div><div>column 1</div></div><div><div>column 2</div></div></div>

CSS relevante:

.parent { 
    position: relative; width: 100%; white-space: nowrap; overflow: hidden; 
}

.parent>div { 
    display:inline-block; width:50%; white-space:normal; vertical-align:top; 
}

.parent>div>div {
    padding-bottom: 32768px; margin-bottom: -32768px; 
}

Esto es un poco complicado, y el margen negativo significa que el fondo "verdadero" de las columnas está oscurecido. Esto a su vez significa que no puede colocar nada en relación con la parte inferior de esas columnas porque eso está cortado por overflow: hidden. Tenga en cuenta que, además de los bloques en línea, puede lograr un efecto similar con flotantes.


TL; DR : use flexbox si puede ignorar IE9 y versiones anteriores; de lo contrario, intente con una tabla (css). Si ninguna de esas opciones funciona para usted, hay hacks de margen negativo, pero estos pueden causar problemas de visualización extraños que son fáciles de omitir durante el desarrollo, y hay limitaciones de diseño que debe tener en cuenta.

Eamon Nerbonne
fuente
1
Buena, pero vale la pena tener en cuenta que no puede usar márgenes entre estas celdas (y el relleno no ayudará si desea que se diseñen).
Wordpressor
3
border-spacing:10px;en la tabla, el elemento introducirá un espaciado de margen. Alternativamente, puede agregar columnas adicionales (vacías) donde desee espacio adicional. Y también puede agregar relleno dentro de las celdas de la tabla; Sin embargo, ese relleno se incluirá en el fondo, por lo que puede que no sea lo que desea. Pero tienes razón en que no es tan flexible como un margen normal. Y no puede colocar nada en relación con las columnas, lo que puede ser un problema.
Eamon Nerbonne
1
Entonces, ¿es mejor un diseño sin mesa o no?
dinámico
3
Tengo que decir: estoy de acuerdo con usted en que en este caso una tabla simple es más que suficiente. El problema es que hay una vista común para ignorar cada diseño con tabla
dinámico
3
El problema con la tabla es que cuando la pantalla se redimensiona a un ancho más pequeño (diseño receptivo), las celdas de la tabla se aplastan en lugar de colocar una sobre la parte superior de la siguiente. El segundo método con relleno de fondo: 32768px; margen inferior: -32768px; es bastante sorprendente y hace casi exactamente lo que necesitaba ... gracias por eso ... el fondo del borde es un problema ...
Serj Sagan
23

Para los padres:

display: flex;

Para niños:

align-items: stretch;

Debe agregar algunos prefijos, verifique caniuse.

Aiphee
fuente
2
No lo recomendaría IE9 sigue siendo una cosa.
Gracias por su respuesta; ¡funciona bien! "Debe agregar algunos prefijos, verifique caniuse". ¿Qué quieres decir con esa línea? ¿Puedes agregar un poco más de información para principiantes?
Md Sifatul Islam
@MdSifatulIslam Vaya aquí: caniuse.com/#feat=flexbox Puede ver si algún navegador que necesita admitir necesita un prefijo de función.
Aiphee
18

Encontré muchas respuestas, pero probablemente la mejor solución para mí es

.parent { 
  overflow: hidden; 
}
.parent .floatLeft {
  # your other styles
  float: left;
  margin-bottom: -99999px;
  padding-bottom: 99999px;
}

Puede consultar otras soluciones aquí http://css-tricks.com/fluid-width-equal-height-columns/

Dobromir Minchev
fuente
No tengo idea de por qué funciona, pero resuelve mi problema como un encanto. Gracias
Combine
A mí también me funciona. A pesar de que no es la forma limpia. ¡Gracias!
Mark Anthony Uy
18
hacky como el infierno No recomiendo esto para aplicaciones de producción
FedericoCapaldo
esto es asombroso jaja. No pensé que esto realmente funcionaría
Tom McDonough
11

Establezca el elemento primario principal para que overflow: hidden
luego en elementos secundarios puede establecer una gran cantidad para el relleno inferior. por ejemplo,
padding-bottom: 5000px
entonces margin-bottom: -5000px
y luego todos los div secundarios serán la altura del padre.
Por supuesto, esto no funcionará si está tratando de poner contenido en el div padre (fuera de otros divs)

.parent{
    border: 1px solid black;
    overflow: hidden;
    height: auto;
}
.child{
    float: left;
    padding-bottom: 1500px;
    margin-bottom: -1500px;
}
.child1{
    background: red;
    padding-right: 10px;    
}
.child2{
    background: green;
    padding-left: 10px;
}
<div class="parent">
    <div class="child1 child">
        One line text in child1
    </div>
    <div class="child2 child">
        Three line text in child2<br />
        Three line text in child2<br />
        Three line text in child2
    </div>
</div>

Ejemplo: http://jsfiddle.net/Tareqdhk/DAFEC/

Tareq
fuente
parece un poco sucio, pero funcionó para mí, la única solución para esta pregunta. Intenté esto usando Twitter Bootstrap.
cukabeka
8

¿El padre tiene una altura? Si establece la altura de los padres de esta manera.

div.parent { height: 300px };

Luego puede hacer que el niño se estire hasta la altura completa de esta manera.

div.child-right { height: 100% };

EDITAR

Así es como lo haría usando JavaScript.

Olical
fuente
el padre no tiene una altura fija. Se está expandiendo según la altura del niño a la izquierda.
Veera
Ah, pensé eso, entonces necesitarás JavaScript, lo agregaré en un segundo.
Olical
El enlace @Olical JSFiddle está roto. Elimínelo o actualice la respuesta. ¡Gracias!
itsmysterybox
1
El enlace a js ahora da un 404
Chanoch
5

La visualización de la tabla CSS es ideal para esto:

.parent {
  display: table;
  width: 100%;
}
.parent > div {
  display: table-cell;
}
.child-left {
  background: powderblue;
}
.child-right {
  background: papayawhip;
}
<div class="parent">
  <div class="child-left">Short</div>
  <div class="child-right">Tall<br>Tall</div>
</div>

Respuesta original (se supone que cualquier columna podría ser más alta):

Está tratando de hacer que la altura de los padres dependa de la altura de los niños y la altura de los niños dependa de la altura de los padres. No se computará. CSS Faux columnas es la mejor solución. Hay más de una forma de hacerlo. Prefiero no usar JavaScript.

Salman A
fuente
Buen punto. ¿Qué tal si la altura de los niños depende de la altura del hermano más alto (ya sea determinado por la altura de los padres o no), y no por los padres? Supongo que eso no se puede hacer en CSS.
mikato
No, los hermanos no pueden afectar la altura del otro. Sin embargo, el diseño display: table+ display: table-cellproducirá el resultado deseado.
Salman A
¡Gran actualización! Sin embargo, terminé intentando esto y quería tener una separación de espacios en blanco entre los divs / celdas y terminé teniendo que hacer divs internos dentro de los divs de celda de tabla para lograr eso y, por supuesto, perdí la capacidad de hacer que usaran la altura completa porque los divs internos no eran divs de celda de tabla, exactamente el mismo problema. ¿Alguna idea para eso? Un poco de espacio entre celdas perdido ahora.
mikato
¡Ah, hay espacio entre bordes en CSS! stackoverflow.com/questions/339923/… Pude hacer que mis divs en forma de tabla funcionen bien con la separación de espacios en blanco mediante el uso de espaciado de bordes. Ahora tengo la capacidad de hacer que las celdas de la tabla (bloques de fondo de color) utilicen la altura completa del padre o no mediante el uso inteligente de los divs de celdas de la tabla.
mikato
Solo un problema con el que me encontré: no puedes usar esto con float: stackoverflow.com/questions/20110217/…
Joshua Pinter el
4

Recientemente hice esto en mi sitio web usando jQuery. El código calcula la altura del div más alto y establece los otros divs a la misma altura. Aquí está la técnica:

http://www.broken-links.com/2009/01/20/very-quick-equal-height-columns-in-jquery/

No creo height:100%que funcione, así que si no conoces explícitamente las alturas div, no creo que haya una solución CSS pura.

ajcw
fuente
1
Debe activar esto al menos en listo, cambiar el tamaño, cambio de orientación, cambiar el tamaño de la fuente.
netAction
4

Usé esto para una sección de comentarios:

.parent {
    display: flex;
    float: left;
    border-top:2px solid black;
    width:635px;
    margin:10px 0px 0px 0px;
    padding:0px 20px 0px 20px;
    background-color: rgba(255,255,255,0.5);
}
    
.child-left {
	align-items: stretch;
	float: left;
	width:135px;
	padding:10px 10px 10px 0px;
	height:inherit;
	border-right:2px solid black;
}

.child-right {
	align-items: stretch;
	float: left;
	width:468px;
	padding:10px;
}
<div class="parent">
  <div class="child-left">Short</div>
  <div class="child-right">Tall<br>Tall</div>
</div>

Podrías flotar el niño de derecha a derecha, pero en este caso he calculado los anchos de cada div con precisión.

larsgrafik
fuente
1
Lo primero que me vino a la mente fue la altura: heredar, no estoy seguro de por qué nadie votó
Andreas
3

Si está al tanto de bootstrap, puede hacerlo fácilmente utilizando la propiedad 'flex'. Todo lo que necesita hacer es pasar las propiedades de css a la división principal.

.homepageSection {
  overflow: hidden;
  height: auto;
  display: flex;
  flex-flow: row;
}

¿Dónde .homepageSectionestá mi padre div. Ahora agregue child div en su html como

<div class="abc col-md-6">
<div class="abc col-md-6">

donde abc es mi división infantil. Puede verificar la igualdad de altura en ambas divisiones secundarias independientemente del borde simplemente dando borde a la división secundaria

Ali naved
fuente
0
<div class="parent" style="height:500px;">
<div class="child-left floatLeft" style="height:100%">
</div>

<div class="child-right floatLeft" style="height:100%">
</div>
</div>

Utilicé el estilo en línea solo para dar una idea.

suketup
fuente
-2

Me enteré de este buen truco en una entrevista de pasantía. La pregunta original es cómo garantizar que la altura de cada componente superior en tres columnas tenga la misma altura que muestre todo el contenido disponible. Básicamente, cree un componente hijo que sea invisible que represente la altura máxima posible.

<div class="parent">
    <div class="assert-height invisible">
        <!-- content -->
    </div>
    <div class="shown">
        <!-- content -->
    </div>
</div>
Joel Lim
fuente