CSS: configurando ancho / alto como Porcentaje menos píxeles

He visto esta pregunta en otros dos contextos sobre SO, pero pensé que valdría la pena volver a preguntar por mi caso particular. Intento crear algunas clases de CSS reutilizables para una mayor coherencia y menos desorden en mi sitio, y estoy atascado en tratar de estandarizar una cosa que uso con frecuencia.

Tengo un contenedor div para el que no quiero establecer la altura (porque variará según en qué parte del sitio se encuentre), y dentro hay un encabezado div, y luego una lista desordenada de elementos, todos con CSS aplicado a ellos. Se parece mucho a esto:

Widget

Quiero que la lista desordenada ocupe la habitación restante en el contenedor div, sabiendo que el encabezado div tiene 18 px de alto. Simplemente no sé cómo especificar la altura de la lista como “el resultado de 100% menos 18px”. ¿Alguien tiene algún consejo en esta situación?

Me doy cuenta de que esta es una publicación anterior, pero dado que no se ha sugerido, vale la pena mencionar que si está escribiendo para navegadores compatibles con CSS3, puede usar calc :

 height: calc(100% - 18px); 

Merece la pena señalar que no todos los navegadores actualmente admiten la función estándar calc3 de CSS (), por lo que puede ser necesario implementar las versiones específicas del navegador de la siguiente manera:

 /* Firefox */ height: -moz-calc(100% - 18px); /* WebKit */ height: -webkit-calc(100% - 18px); /* Opera */ height: -o-calc(100% - 18px); /* Standard */ height: calc(100% - 18px); 

Por un enfoque diferente, podrías usar algo como esto en la lista:

 position: absolute; top: 18px; bottom: 0px; width: 100%; 

Esto funciona siempre que el contenedor principal tenga una position: relative;

Yo uso Jquery para esto

 function setSizes() { var containerHeight = $("#listContainer").height(); $("#myList").height(containerHeight - 18); } 

luego ato el tamaño de la ventana para recalcularlo cada vez que se cambia el tamaño de la ventana del navegador (si el tamaño del contenedor cambió con el tamaño de la ventana)

 $(window).resize(function() { setSizes(); }); 

No defina la altura como un porcentaje, simplemente configure la top=0 y la bottom=0 , como esta:

 #div { top: 0; bottom: 0; position: absolute; width: 100%; } 

Presumiendo altura de cabecera 17px

Lista css:

 height: 100%; padding-top: 17px; 

Header css:

 height: 17px; float: left; width: 100%; 
  1. Use márgenes negativos en el elemento que le gustaría tener menos píxeles desactivados. (elemento deseado)
  2. overflow:hidden; en el elemento que contiene
  3. Cambiar a overflow:auto; en el elemento deseado

¡Funcionó para mí!

Prueba el tamaño de la caja. Para la lista:

 height: 100%; /* Presuming 10px header height */ padding-top: 10px; /* Firefox */ -moz-box-sizing: border-box; /* WebKit */ -webkit-box-sizing: border-box; /* Standard */ box-sizing: border-box; 

Para el encabezado:

 position: absolute; left: 0; top: 0; height: 10px; 

Por supuesto, el contenedor principal debería tener algo como:

 position: relative; 

Intenté algunas de las otras respuestas, y ninguna de ellas funcionó como yo quería. Nuestra situación era muy similar donde teníamos un encabezado de ventana y la ventana podía redimensionarse con imágenes en el cuerpo de la ventana. Queríamos bloquear la relación de aspecto del redimensionamiento sin la necesidad de agregar cálculos para tener en cuenta el tamaño fijo del encabezado y aún así tener la imagen llena el cuerpo de la ventana.

A continuación, creé un fragmento muy simple que muestra lo que terminamos haciendo que parece funcionar bien para nuestra situación y debería ser compatible en la mayoría de los navegadores.

En nuestro elemento de ventana agregamos un margen de 20px que contribuye a la posición relativa de otros elementos en la pantalla, pero no contribuye al “tamaño” de la ventana. El encabezado de la ventana se coloca completamente (lo que lo quita del flujo de otros elementos, por lo que no hará que otros elementos como la lista desordenada se desplacen) y su parte superior se coloca -20px, lo que coloca el encabezado dentro del margen de la ventana. Finalmente, nuestro elemento ul se agrega a la ventana, y la altura se puede configurar al 100%, lo que hará que ocupe el cuerpo de la ventana (excluyendo el margen).

 *,*:before,*:after { box-sizing: border-box; } .window { position: relative; top: 20px; left: 50px; margin-top: 20px; width: 150px; height: 150px; } .window-header { position: absolute; top: -20px; height: 20px; border: 2px solid black; width: 100%; } ul { border: 5px dashed gray; height: 100%; } 
 
Hey this is a header
  • Item 1
  • Item 2
  • Item 3
  • Item 4
  • Item 5

Gracias, resolví el mío con tu ayuda, ajustándolo un poco ya que quiero un div 100% width 100% heigth (menos altura de una barra inferior) y no scroll en el cuerpo (sin hackear / ocultar barras de desplazamiento).

Para CSS:

  html{ width:100%;height:100%;margin:0px;border:0px;padding:0px; } body{ position:relative;width:100%;height:100%;margin:0px;border:0px;padding:0px; } div.adjusted{ position:absolute;width:auto;height:auto;left:0px;right:0px;top:0px;bottom:36px;margin:0px;border:0px;padding:0px; } div.the_bottom_bar{ width:100%;height:31px;margin:0px;border:0px;padding:0px; } 

Para HTML:

  
// My elements that go on dynamic size area
// My elements that goes on bottom bar (fixed heigh of 31 pixels)

Eso hizo el truco, oh sí pongo un valor poco más grande en div.ajustado para el fondo que para la altura de la barra inferior, de lo contrario aparece la barra de desplazamiento vertical, ajusté para ser el valor más cercano.

Esa diferencia se debe a que uno de los elementos en el área dinámica está agregando un orificio inferior adicional del que no sé cómo deshacerme … es una etiqueta de video (HTML5), tenga en cuenta que puse esa etiqueta de video con este CSS ( así que no hay razón para que haga un hoyo inferior, pero lo hace):

  video{ width:100%;height:100%;margin:0px;border:0px;padding:0px; } 

El objective: tener un video que tome el 100% del navegador (y cambie el tamaño dinámicamente cuando el navegador cambie de tamaño, pero sin alterar la relación de aspecto) menos un espacio inferior que use para un div con algunos textos, botones, etc. (y validadores w3c y css por supuesto).

EDIT: encontré el motivo, la etiqueta de video es como texto, no como un elemento de bloque, así que lo arreglé con este CSS:

  video{ display:block;width:100%;height:100%;margin:0px;border:0px;padding:0px; } 

Tenga en cuenta la display:block; en la etiqueta de video

Otra forma de lograr el mismo objective: flex boxes . Convierta el contenedor en un cuadro de columna flexible y, a continuación, tenga libertad para permitir que algunos elementos tengan un tamaño fijo (comportamiento predeterminado) o para llenar / reducir al espacio del contenedor (con flex-grow: 1 y flex- encogimiento: 1).

 #wrap { display:flex; flex-direction:column; } .extendOrShrink { flex-shrink:1; flex-grow:1; overflow:auto; } 

Consulte https://jsfiddle.net/2Lmodwxk/ (intente ampliar o reducir la ventana para observar el efecto)

Nota: también puede usar la propiedad de taquigrafía:

  flex:1 1 auto; 

No estoy seguro de si esto funciona en su situación particular, pero he encontrado que el relleno dentro del div empujará el contenido dentro de un div si el div que lo contiene tiene un tamaño fijo. Tendría que flotar o posicionar absolutamente su elemento de encabezado, pero de lo contrario, no lo he intentado para divs de tamaño variable.