Eu tenho um site para montar que tem uma proporção fixa de aproximadamente 16:9
paisagem, como um vídeo.
Quero centralizá-lo e expandi-lo para preencher a largura e a altura disponíveis, mas nunca aumentar em ambos os lados.
Por exemplo:
- Uma página alta e fina teria o conteúdo esticando toda a largura, mantendo uma altura proporcional.
- Uma página curta e larga teria o conteúdo esticando a altura total, com uma largura proporcional.
Existem dois métodos que eu tenho estudado:
- Use uma imagem com a proporção correta para expandir um contêiner
div
, mas não consegui que ela se comportasse da mesma maneira nos principais navegadores. - Definir um preenchimento inferior proporcional, mas que funcione apenas em relação à largura e ignore a altura. Ele fica cada vez maior com a largura e exibe barras de rolagem verticais.
Eu sei que você poderia fazer isso com JS facilmente, mas eu gostaria de uma solução CSS pura.
Alguma ideia?
html
css
responsive-design
aspect-ratio
Henry Gibson
fonte
fonte
position: relative (default) height: 0 padding-<top/bottom>: H/W*100%
Respostas:
Use as novas unidades de janela CSS
vw
evh
(largura / altura da janela)FIDDLE
Redimensione verticalmente e horizontalmente e você verá que o elemento sempre preencherá o tamanho máximo da viewport sem quebrar a proporção e sem as barras de rolagem!
CSS (PURO)
Mostrar snippet de código
Se você deseja usar no máximo 90% de largura e altura da janela atual : FIDDLE
Mostrar snippet de código
Além disso, o suporte ao navegador também é muito bom: IE9 +, FF, Chrome, Safaricaniuse
fonte
vh
,vw
,vmin
,vmax
). No entanto, existe uma solução alternativa , que usa consultas de mídia para direcionar dispositivos iOS.Apenas reformule
Danield
a resposta em um mix MENOS, para uso posterior:fonte
Use uma consulta de mídia CSS
@media
junto com as unidades de viewport CSSvw
evh
para se adaptar à proporção da viewport. Isso tem o benefício de atualizar outras propriedades, comofont-size
também.Esse violino demonstra a proporção fixa da div e o texto que corresponde exatamente à sua escala.
O tamanho inicial é baseado na largura total:
Em seguida, quando a janela de exibição for maior que a proporção desejada, alterne para altura como medida básica:
Isso é muito semelhante à abordagem
max-width
emax-height
da @Danield, apenas mais flexível.fonte
Minha pergunta original para isso era como ter um elemento de aspecto fixo, mas ajustá-lo exatamente a um contêiner especificado, o que o torna um pouco complicado. Se você simplesmente deseja que um elemento individual mantenha sua proporção, é muito mais fácil.
O melhor método que encontrei é atribuir uma altura zero ao elemento e, em seguida, usar a porcentagem de preenchimento inferior para dar a ele altura. O preenchimento de porcentagem é sempre proporcional à largura de um elemento, e não à sua altura, mesmo se o preenchimento superior ou inferior.
Propriedades de preenchimento do W3C
Assim, você pode fornecer a um elemento uma porcentagem de largura para ficar dentro de um contêiner e, em seguida, preencher para especificar a proporção, ou em outros termos, a relação entre sua largura e altura.
Portanto, no exemplo acima, o objeto ocupa 80% da largura do contêiner e sua altura é 56,25% desse valor. Se a largura fosse de 160 px, o preenchimento inferior e, portanto, a altura seria de 90 px - um aspecto 16: 9.
O pequeno problema aqui, que pode não ser um problema para você, é que não há espaço natural dentro do seu novo objeto. Se você precisar inserir algum texto, por exemplo, e esse texto precisar assumir seus próprios valores de preenchimento, será necessário adicionar um contêiner dentro e especificar as propriedades nele.
Além disso, unidades vw e vh não são suportadas em alguns navegadores mais antigos; portanto, a resposta aceita à minha pergunta pode não ser possível para você e você pode precisar usar algo mais lo-fi.
fonte
Entendo que você pediu que gostaria de uma
CSS
solução específica. Para manter a proporção, é necessário dividir a altura pela proporção desejada. 16: 9 = 1,77777777777878.Para obter a altura correta para o contêiner, é necessário dividir a largura atual por 1,77777777777778. Como você não pode verificar o
width
contêiner com apenasCSS
ou dividir por uma porcentagemCSS
, isso não é possível semJavaScript
(que eu saiba).Eu escrevi um script de trabalho que manterá a proporção desejada.
HTML
CSS
Javascript
Você pode usá-lo
function
novamente se desejar exibir outra coisa com uma proporção diferente usandofonte
window.onresize
é acionado no momento em que o navegador altera o tamanho.Existe agora uma nova propriedade CSS especificado para resolver este:
object-fit
.http://docs.webplatform.org/wiki/css/properties/object-fit
O suporte ao navegador ainda está um pouco ausente ( http://caniuse.com/#feat=object-fit ) - atualmente funciona até certo ponto na maioria dos navegadores, exceto a Microsoft - mas, dado o tempo, é exatamente o que era necessário para esta pergunta.
fonte
A resposta de Danield é boa, mas só pode ser usada quando a div preenche toda a viewport, ou usando um pouco de
calc
, pode ser usada se a largura e altura do outro conteúdo na viewport for conhecida.No entanto, combinando o
margin-bottom
truque com o método na resposta mencionada acima, o problema pode ser reduzido a apenas ter que saber a altura do outro conteúdo. Isso é útil se você tiver um cabeçalho de altura fixa, mas a largura da barra lateral, por exemplo, não for conhecida.Aqui está um jsfiddle usando scss , o que torna mais óbvio a origem dos valores.
fonte
Com base na resposta de Daniel , escrevi este mix SASS com interpolation (
#{}
) para o iframe de um vídeo do youtube que está dentro de uma caixa de diálogo modal do Bootstrap:Uso:
HTML:
Isso sempre exibirá o vídeo sem as partes pretas que o youtube adiciona ao iframe quando a largura ou a altura não são proporcionais ao vídeo. Notas:
$sides-adjustment
é um pequeno ajuste para compensar uma pequena parte dessas partes pretas que aparecem nas laterais;.modal-footer
;.modal-dialog
;.modal-header
.Depois de muitos testes, isso está funcionando perfeitamente para mim agora.
fonte
aqui uma solução baseada na solução @Danield, que funciona mesmo dentro de uma div.
Nesse exemplo, estou usando o Angular, mas ele pode se mover rapidamente para o vanilla JS ou outra estrutura.
A idéia principal é apenas mover a solução @Danield para um iframe vazio e copiar as dimensões após a alteração do tamanho da janela do iframe.
Esse iframe deve ajustar as dimensões ao seu elemento pai.
https://stackblitz.com/edit/angular-aspect-ratio-by-iframe?file=src%2Findex.html
Aqui estão algumas capturas de tela:
fonte