html - ratio - same width and height css




Mantener la relación de aspecto de un div con CSS (14)

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


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


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>


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 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>

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.





aspect-ratio