same ratio mantener equal based and html css css3 responsive-design aspect-ratio

html - ratio - Mantener la relación de aspecto de un div con CSS



resize image css (20)

Digamos que tiene 2 divs. El div exterior es un contenedor y el interno podría ser cualquier elemento que necesite para mantener su relación (img o un iframe de youtube o lo que sea)

html se ve así:

<div class=''container''> <div class=''element''> </div><!-- end of element -->

Digamos que necesitas mantener la proporción del "elemento"

relación => 4 a 1 o 2 a 1 ...

css se parece a esto

.container{ position: relative; height: 0 padding-bottom : 75% /* for 4 to 3 ratio */ 25% /* for 4 to 1 ratio ..*/ } .element{ width : 100%; height: 100%; position: absolute; top : 0 ; bottom : 0 ; background : red; /* just for illustration */ }

el relleno cuando se especifica en%, se calcula en función del ancho, no de la altura. .. así que básicamente no importa cuál sea su ancho, su altura siempre se calculará en función de eso. que mantendrá la relación.

Quiero crear un div que puede cambiar su ancho / alto a medida que cambia el ancho de la ventana.

¿Hay alguna regla de CSS3 que permita que la altura cambie de acuerdo con el ancho, manteniendo su relación de aspecto ?

Sé que puedo hacerlo a través de JavaScript, pero preferiría usar solo CSS.


unidades vw :

Puede usar unidades vw tanto para el ancho como para la altura del elemento. Esto permite preservar la relación de aspecto del elemento, según el ancho de la ventana gráfica.

vw: 1/100 del ancho de la ventana gráfica. [ MDN ]

Alternativamente, también puede usar vh para la altura de la ventana vmin , o incluso vmin / vmax para usar la menor / mayor de las dimensiones de la ventana vmin ( vmin here ).

Ejemplo: relación de aspecto 1: 1

div { width: 20vw; height: 20vw; background: gold; }

<div></div>

Para otras relaciones de aspecto, puede usar la siguiente tabla para calcular el valor para la altura de acuerdo con el ancho del elemento:

aspect ratio | multiply width by ----------------------------------- 1:1 | 1 1:3 | 3 4:3 | 0.75 16:9 | 0.5625

Ejemplo: cuadrícula 4x4 de divs cuadrados.

body { display: flex; flex-wrap: wrap; justify-content: space-between; } div { width: 23vw; height: 23vw; margin: 0.5vw auto; background: gold; }

<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>

Aquí hay un Fiddle con esta demostración y aquí hay una solución para hacer una cuadrícula de cuadrados con contenido vertical y horizontalmente centrado .

El soporte del navegador para las unidades vh / vw es IE9 + vea canIuse para más información


Basándome en tus soluciones he hecho algunos trucos:

Cuando lo uses, tu HTML será solo

<div data-keep-ratio="75%"> <div>Main content</div> </div>

Para usarlo de esta manera hace: CSS:

*[data-keep-ratio] { display: block; width: 100%; position: relative; } *[data-keep-ratio] > * { position: absolute; left: 0; right: 0; top: 0; bottom: 0; }

y js (jQuery)

$(''*[data-keep-ratio]'').each(function(){ var ratio = $(this).data(''keep-ratio''); $(this).css(''padding-bottom'', ratio); });

Y teniendo esto, simplemente establece attr data-keep-ratio en altura / ancho y eso es todo.


Como @ web-tiki ya muestra una forma de usar vh / vw , también necesito una forma de centrarme en la pantalla, aquí hay un código de fragmento para el retrato de 9:16 .

.container { width: 100vw; height: calc(100vw * 16 / 9); transform: translateY(calc((100vw * 16 / 9 - 100vh) / -2)); }

translateY mantendrá este centro en la pantalla. calc(100vw * 16 / 9) es la altura esperada para 9/16. (100vw * 16 / 9 - 100vh) es la altura de sobreflujo, por lo tanto, levante la overflow height/2 mantendrá centrada en la pantalla.

Para el paisaje, y guárdalo 16: 9 , lo muestras de uso.

.container { width: 100vw; height: calc(100vw * 9 / 16); transform: translateY(calc((100vw * 9 / 16 - 100vh) / -2)); }

La relación 9/16 es fácil de cambiar, no es necesario predefinir 100:56.25 o 100:75 Si desea asegurar primero la altura, debe cambiar el ancho y la altura, por ejemplo, height:100vh;width: calc(100vh * 9 / 16) para 9:16 retrato.

Si desea adaptarse a diferentes tamaños de pantalla, también puede interesarle

  • cubierta de background-size / contener
    • El estilo anterior es similar a contener, depende de la relación ancho: altura.
  • object-fit
    • cubrir / contener para img / video tag
  • @media (orientation: portrait) / @media (orientation: landscape)
    • Consulta de medios para portrait / landscape para cambiar la relación.

Como se indica aquí en w3schools.com y se reitera de alguna manera en esta respuesta aceptada , los valores de relleno como porcentajes (énfasis mío):

Especifica el relleno en porcentaje del ancho del elemento contenedor

Ergo, un ejemplo correcto de un DIV sensible que mantiene una relación de aspecto de 16: 9 es el siguiente:

CSS

.parent { position: relative; width: 100%; } .child { position: relative; padding-bottom: calc(100% * 9 / 16); } .child > div { position: absolute; top: 0; bottom: 0; left: 0; right: 0; }

HTML

<div class="parent"> <div class="child"> <div>Aspect is kept when resizing</div> </div> </div>

Demo en JSFiddle


Dígale que mantenga el Ancho: 100px y el Alto: 50px (es decir, 2: 1) Simplemente haga este cálculo:

.pb-2to1 { padding-bottom: calc(50 / 100 * 100%); // i.e., 2:1 }


Elliot me inspiró a esta solución - gracias:

aspectratio.png es un archivo PNG completamente transparente con el tamaño de su relación de aspecto preferida, en mi caso 30x10 píxeles.

HTML

<div class="eyecatcher"> <img src="/img/aspectratio.png"/> </div>

CSS3

.eyecatcher img { width: 100%; background-repeat: no-repeat; background-size: 100% 100%; background-image: url(../img/autoresized-picture.jpg); }

Tenga en cuenta que: background-size es una característica de css3 que podría no funcionar con sus navegadores de destino. Puede verificar la interoperabilidad (fe en caniuse.com ).


Esta es una mejora en la respuesta aceptada:

  • Utiliza pseudo elementos en lugar de divs envoltura
  • La relación de aspecto se basa en el ancho del cuadro en lugar de su padre
  • La caja se estirará verticalmente cuando el contenido sea más alto.

.box { margin-top: 1em; margin-bottom: 1em; background-color: #CCC; } .fixed-ar::before { content: ""; float: left; width: 1px; margin-left: -1px; } .fixed-ar::after { content: ""; display: table; clear: both; } .fixed-ar-16-9::before { padding-top: 56.25%; } .fixed-ar-3-2::before { padding-top: 66.66%; } .fixed-ar-4-3::before { padding-top: 75%; } .fixed-ar-1-1::before { padding-top: 100%; } .width-50 { display: inline-block; width: 50%; } .width-20 { display: inline-block; width: 20%; }

<div class="box fixed-ar fixed-ar-16-9">16:9 full width</div> <hr> <div class="box fixed-ar fixed-ar-16-9 width-50">16:9</div> <hr> <div class="box fixed-ar fixed-ar-16-9 width-20">16:9</div> <div class="box fixed-ar fixed-ar-3-2 width-20">3:2</div> <div class="box fixed-ar fixed-ar-4-3 width-20">4:3</div> <div class="box fixed-ar fixed-ar-1-1 width-20">1:1</div> <hr> <div class="box fixed-ar fixed-ar-16-9 width-20">16:9</div> <div class="box fixed-ar fixed-ar-16-9 width-50">16:9</div>


He encontrado una forma de hacer esto usando CSS, pero tienes que tener cuidado ya que puede cambiar dependiendo del flujo de tu propio sitio web. Lo he hecho para incrustar videos con una relación de aspecto constante dentro de una porción de ancho fluido de mi sitio web.

Digamos que tienes un video incrustado como este:

<object> <param ... /><param ... />... <embed src="..." ...</embed> </object>

Luego puedes colocar todo esto dentro de un div con una clase de "video". Esta clase de video probablemente será el elemento fluido en su sitio web, de manera que, por sí misma, no tiene restricciones directas de altura, pero cuando cambia el tamaño del navegador cambiará de ancho según el flujo del sitio web. Este sería el elemento en el que probablemente esté tratando de que su video incrustado se mantenga mientras mantiene una cierta relación de aspecto del video.

Para hacer esto, coloco una imagen antes del objeto incrustado dentro de la clase div "video".

!!! La parte importante es que la imagen tiene la relación de aspecto correcta que desea mantener. Además, asegúrese de que el tamaño de la imagen sea POR LO MENOS tan grande como el más pequeño que espera que obtenga el video (o lo que sea de lo que esté manteniendo el AR) según su diseño. Esto evitará posibles problemas en la resolución de la imagen cuando se cambie de tamaño en porcentaje. Por ejemplo, si desea mantener una relación de aspecto de 3: 2, no solo use una imagen de 3px por 2px. Puede funcionar en algunas circunstancias, pero no lo he probado y probablemente sería una buena idea evitar.

Probablemente ya debería tener un ancho mínimo como este definido para elementos fluidos de su sitio web. Si no es así, es una buena idea hacerlo para evitar cortar elementos o superponerse cuando la ventana del navegador es demasiado pequeña. Es mejor tener una barra de desplazamiento en algún momento. El ancho más pequeño que debe obtener una página web es aproximadamente 600px (incluidas las columnas de ancho fijo) porque las resoluciones de pantalla no se reducen a menos que se trate de sitios compatibles con el teléfono. !!!

Uso un png completamente transparente pero realmente no creo que termine importando si lo haces bien. Me gusta esto:

<div class="video"> <img class="maintainaspectratio" src="maintainaspectratio.png" /> <object> <param ... /><param ... />... <embed src="..." ...</embed> </object> </div>

Ahora debería poder agregar CSS similar al siguiente:

div.video { ...; position: relative; } div.video img.maintainaspectratio { width: 100%; } div.video object { position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; } div.video embed {width: 100%; height: 100%; }

Asegúrese de eliminar también cualquier declaración explícita de altura o anchura dentro del objeto y las etiquetas de inserción que generalmente vienen con el código de inserción copiado / pegado.

La forma en que funciona depende de las propiedades de posición del elemento de clase de video y del elemento que desea mantener una cierta relación de aspecto. Aprovecha la forma en que una imagen mantendrá su relación de aspecto adecuada cuando se redimensiona en un elemento. Indica lo que sea que esté en el elemento de clase de video para aprovechar al máximo los bienes inmuebles proporcionados por la imagen dinámica al forzar su ancho / alto al 100% del elemento de clase de video que está ajustando la imagen.

Muy bien, ¿eh?

Puede que tenga que jugar un poco con él para que funcione con su propio diseño, pero esto realmente funciona sorprendentemente bien para mí. El concepto general está ahí.


Me he encontrado con este problema varias veces, así que hice una solución JS para ello. Básicamente, esto ajusta la altura del elemento principal según el ancho del elemento en la proporción que especifique. Podrías usarlo como sigue:

<div ratio="4x3"></div>

Tenga en cuenta que, dado que está configurando la altura del elemento, el elemento debe ser una display:block o display:inline-block .

https://github.com/JeffreyArts/html-ratio-component


Para agregar a la respuesta de Web_Designer, <div> tendrá una altura (compuesta completamente de relleno inferior) del 75% del ancho del elemento que lo contiene . Aquí hay un buen resumen: http://mattsnider.com/css-using-percent-for-margin-and-padding/ . No estoy seguro de por qué esto debería ser así, pero así es como es.

Si desea que su div sea un ancho diferente al 100%, necesita otro div de ajuste en el que establecer el ancho:

div.ar-outer{ width: 60%; /* container; whatever width you want */ margin: 0 auto; /* centered if you like */ } div.ar { width:100%; /* 100% of width of container */ padding-bottom: 75%; /* 75% of width of container */ position:relative; } div.ar-inner { position: absolute; top: 0; bottom: 0; left: 0; right: 0; }

Utilicé algo similar al truco de la imagen de Elliot recientemente para permitirme usar consultas de medios CSS para servir un archivo de logotipo diferente dependiendo de la resolución del dispositivo, pero aún así la escala proporcionalmente como lo haría un <img> (configuro el logotipo como imagen de fondo a .png transparente con la relación de aspecto correcta). Pero la solución de Web_Designer me ahorraría una solicitud http.



Puedes usar un svg. Haga que la posición del contenedor / envoltura sea relativa, coloque primero el svg en posición estática y luego coloque el contenido en posición absoluta (arriba: 0; izquierda: 0; derecha: 0; abajo: 0;)

Ejemplo con proporciones 16: 9:

image.svg: (puede estar en línea en src)

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 9" width="16" height="9"/>

CSS:

.container { position: relative; } .content { position: absolute; top:0; left:0; right:0; bottom:0; }

HTML:

<div class="container"> <img style="width: 100%" src="image.svg" /> <div class="content"></div> </div>

Tenga en cuenta que el svg en línea no parece funcionar, pero puede urlencodificar el svg e insertarlo en el atributo img src de esta forma:

<img src="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2016%209%22%20width%3D%2216%22%20height%3D%229%22%2F%3E" style="width: 100%;" />


SCSS es la mejor solución en mi caso; utilizando un atributo de datos:

[data-aspect-ratio] { display: block; max-width: 100%; position: relative; &:before { content: ''''; display: block; } > * { display: block; height: 100%; left: 0; position: absolute; top: 0; width: 100%; } } [data-aspect-ratio="3:1"]:before { padding-top: 33.33%; } [data-aspect-ratio="2:1"]:before { padding-top: 50%; } [data-aspect-ratio="16:9"]:before { padding-top: 56.25%; } [data-aspect-ratio="3:2"]:before { padding-top: 66.66%; } [data-aspect-ratio="4:3"]:before { padding-top: 75%; } [data-aspect-ratio="1:1"]:before { padding-top: 100%; } [data-aspect-ratio="3:4"]:before { padding-top: 133.33%; } [data-aspect-ratio="2:3"]:before { padding-top: 150%; } [data-aspect-ratio="9:16"]:before { padding-top: 177.77%; } [data-aspect-ratio="1:2"]:before { padding-top: 200%; } [data-aspect-ratio="1:3"]:before { padding-top: 300%; }

Por ejemplo :

<div data-aspect-ratio="16:9"><iframe ...></iframe></div>

source


Si bien la mayoría de las respuestas son muy interesantes, la mayoría de ellas requieren tener una imagen ya dimensionada correctamente ... Otras soluciones solo funcionan con un ancho y no se preocupan por la altura disponible, pero a veces también desea ajustar el contenido a una cierta altura .

Intenté juntarlos para brindar una solución completamente portátil y redimensionable ... El truco consiste en utilizar la escala automática de una imagen, pero usar un elemento svg en línea en lugar de usar una imagen pre-renderizada o cualquier forma de segunda solicitud HTTP ...

div.holder{ background-color:red; display:inline-block; height:100px; width:400px; } svg, img{ background-color:blue; display:block; height:auto; width:auto; max-width:100%; max-height:100%; } .content_sizer{ position:relative; display:inline-block; height:100%; } .content{ position:absolute; top:0; bottom:0; left:0; right:0; background-color:rgba(155,255,0,0.5); }

<div class="holder"> <div class="content_sizer"> <svg width=10000 height=5000 /> <div class="content"> </div> </div> </div>

Tenga en cuenta que he usado grandes valores en los atributos de ancho y alto del SVG, ya que debe ser más grande que el tamaño máximo esperado, ya que solo se puede reducir. El ejemplo hace la relación de div 10: 5.


Si desea colocar un cuadrado dentro de la ventana gráfica en vista vertical u horizontal (lo más grande posible, pero no hay nada pegado afuera), cambie entre usar vw / vh en orientación portrait / landscape :

@media (orientation:portrait ) { .square { width :100vw; height:100vw; } } @media (orientation:landscape) { .square { width :100vh; height:100vh; } }


Si toda la estructura del contenedor se basara en porcentajes, este sería el comportamiento predeterminado, ¿puede proporcionar un ejemplo más específico?

A continuación, se muestra un ejemplo de lo que quiero decir: si toda su jerarquía principal estuviera basada en%, cualquier ajuste de la ventana del navegador funcionaría sin ningún js / css adicional, ¿no es esto una posibilidad con su diseño?

<div style="width: 100%;"> <div style="width: 50%; margin: 0 auto;">Content</div> </div>


Solo una idea o un hack.

div { background-color: blue; width: 10%; transition: background-color 0.5s, width 0.5s; font-size: 0; } div:hover { width: 20%; background-color: red; } img { width: 100%; height: auto; visibility: hidden; }

<div> <!-- use an image with target aspect ratio. sample is a square --> <img src="http://i.imgur.com/9OPnZNk.png" /> </div>


Utilicé una nueva solución.

.squares{ width: 30vw height: 30vw

A la relación de aspecto principal

.aspect-ratio width: 10vw height: 10vh

Sin embargo, esto es relativo a toda la ventana gráfica. Entonces, si necesita un div que sea el 30% del ancho de la ventana gráfica, puede usar 30vw en su lugar, y como conoce el ancho, los reutiliza en altura usando la unidad calc y vw.


Simplemente crea un envoltorio <div> con un valor de porcentaje para padding-bottom , como esto:

div { width: 100%; padding-bottom: 75%; background: gold; /** <-- For the demo **/ }

<div></div>

El resultado será un <div> con una altura igual al 75% del ancho de su contenedor (una relación de aspecto 4: 3).

Esto se basa en el hecho de que para el relleno:

El porcentaje se calcula con respecto al ancho del bloque que contiene la caja generada [...] (fuente: w3.org , énfasis mío)

Valores de relleno del fondo para otras relaciones de aspecto y ancho del 100%:

aspect ratio | padding-bottom value --------------|---------------------- 16:9 | 56.25% 4:3 | 75% 3:2 | 66.66% 8:5 | 62.5%

Colocando contenido en la div:

Para mantener la relación de aspecto del div y evitar que su contenido lo estire, debe agregar un niño en posición absoluta y estirarlo hasta los bordes de la envoltura con:

div.stretchy-wrapper { position: relative; } div.stretchy-wrapper > div { position: absolute; top: 0; bottom: 0; left: 0; right: 0; }

Aquí hay una demo y otra más en profundidad.