Tamanho de fundo do CSS: capa + anexo de fundo: imagens de fundo de recorte fixas

Eu tenho uma lista de figuras contendo imagens de fundo. Algo como o seguinte:

Cada uma dessas imagens tem seu background-size definido como cover e o background-attachment definido como fixed .

 figure { width: 100%; height: 100%; background-size: cover; background-attachment: fixed; } 

Quando cada uma das figuras ocupa a viewport inteira, isso funciona bem, mas se houver um deslocamento de qualquer tipo, a imagem de fundo será cortada.

Tanto quanto eu posso dizer isso é por design ( https://developer.mozilla.org/en-US/docs/Web/CSS/background-size#Values ).

Eu gostaria que as imagens fossem cortadas vertical ou horizontalmente, mas não ambas, e fossem centralizadas pelo tamanho da figura em si.

Eu sei que existem soluções de javascript, mas existe uma maneira de fazer isso usando CSS?

Aqui está um exemplo prático : http://codepen.io/Godwin/pen/KepiJ

Infelizmente, isso é simplesmente um artefato de como o posicionamento fixo funciona em CSS e não há maneira de contorná-lo em CSS puro – você precisa usar JavaScript.

A razão pela qual isso acontece é devido à combinação de background-attachment: fixed de background-attachment: fixed e background-size: cover . Quando você especifica background-attachment: fixed essencialmente faz com que a background-image se comporte como se fosse uma position: fixed imagem position: fixed , significando que é retirada do stream de página e do contexto de posicionamento e se torna relativa à viewport em vez do elemento a imagem de fundo de.

Portanto, sempre que você usar essas propriedades juntas, o valor da cover será calculado em relação ao tamanho da viewport, independentemente do tamanho do próprio elemento, e é por isso que funciona como esperado quando o elemento é do mesmo tamanho da viewport, mas é recortado de maneiras inesperadas quando o elemento é menor que a viewport.

Para contornar isso, você basicamente precisa usar background-attachment: scroll e ligue um ouvinte de evento ao evento de scroll no JS que atualiza manualmente a background-position relação a distância percorrida da janela para simular o posicionamento fixo, mas ainda assim calcular background-size: cover relativa ao elemento container em vez da viewport.

Há uma correção jQuery para isso: http://jsfiddle.net/QN9cH/1/ Eu sei que não é o ideal, mas pelo menos funciona 🙂

 $(window).scroll(function() { var scrolledY = $(window).scrollTop(); $('#container').css('background-position', 'left ' + ((scrolledY)) + 'px'); }); 
 background: url() center top no-repeat fixed; background-size: auto ; 

Não há solução real. No entanto, você pode aumentar a altura do tamanho da imagem em vez da cover . E ajuste o tamanho da largura em% em seu elemento até que ele morde a borda.

Você vê se você redimensiona sua janela, ela não será cortada. Em vez disso, manterá sempre o formato original do tamanho da imagem. Com isso acima você basicamente ‘zoom’, mas não ‘cobri-lo’.

O tamanho do plano de fundo: capa; A propriedade está realmente cortando a imagem para que ela preencha a área e não tenha nenhum espaço vazio.

O background-size: contém; propriedade é determinar qual dimensão é maior e dimensionar de acordo com isso. Portanto, se você tiver um bloco de 100 x 100 pixels e uma imagem de plano de fundo de 200 x 150 pixels, a configuração do tamanho do plano de fundo a ser contado aumentará a imagem para 100 x 75 pixels. Nesse cenário, no entanto, você terá espaço vazio se a proporção do elemento for diferente da proporção da imagem.

Você também pode controlar manualmente qual proporção tem prioridade, supondo que você saiba a proporção da imagem.

Então, se você sabe que sua imagem é sempre 100x200px, isso significa que a largura é sempre a pequena dimensão e a altura a grande.

Agora definindo o tamanho de fundo: 100% auto; vai garantir que você não terá espaço vazio, mas você vai acabar com o recorte. Se você definir como tamanho de plano de fundo: auto 100%; Ele garantirá que nenhum recorte ocorra e a altura nunca terá espaço vazio (mas a largura será).

Se você quiser recortar e apenas centralizar a imagem, use background-position: 50% ;.

A resposta de Nick Noordijk me colocou no caminho certo, mas eu gosto de evitar scripts que executam um cálculo toda vez que o evento de rolagem acontece. Aqui está minha versão que só realiza o cálculo quando a página é carregada ou o tamanho da canvas muda:

html:

 

css:

 .fake-img { display: block; height: 280px; /* set the height here */ width: 100%; background-image: url('http://example.com/path/to/image.jpg'); background-repeat: no-repeat; background-position: center 68px; background-size: auto 50%; /* make a "best guess" here as a default */ background-attachment: fixed; position: relative; } 

jQuery:

 $(window).on('resize load orientationchange', function(){ responsive_calc(); }); var responsive_calc = function(){ // get the viewport height var h = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight; // get the element height var bannerHeight = $('.fake-img').height(); // get the integer percentage value difference between them var bgHeightPercent = Math.ceil(bannerHeight/h*100); // set background-size height to match the element instead of the viewport $('.fake-img').css('background-size', 'auto ' + bgHeightPercent + '%'); } 

Observe que isso realmente funciona apenas com imagens “banner” de paisagem – usando background-size: auto nn% não tem a mesma vantagem de background-size: cover no trabalho, não importa se sua imagem tem excesso em qualquer direção.

Um exemplo de efeito de paralaxe para elementos dispostos separadamente (não para elementos de canvas cheia):

html:

 
Content

css:

 #element_to_scroll { background-repeat: no-repeat; background-size: cover; background-position-x: center; background-position-y: 0; } 

js:

 $(window).scroll(function() { var realImageWidth = 1280; var realImageHeight = 1024; var viewportBottom = $(window).scrollTop() + $(window).height(); $('#element_to_scroll').each(function(){ var scrollAmountPx = realImageHeight/(realImageWidth/$(this).outerWidth())-$(this).outerHeight(); var elementOffsetFromBottom = viewportBottom-$(this).offset().top; var scrollAreaHeight = $(this).outerHeight() + $(window).height(); if(elementOffsetFromBottom>0 && elementOffsetFromBottom 

Atualização em julho de 2018: agora há uma correção de 1 linha para esse problema

Eu tive esse mesmo problema até que eu li este artigo , que me ensinou que eu poderia adicionar essa linha ao meu CSS para fazê-lo funcionar:

will-change: transform;

Funcionou!

Agora meu CSS é assim:

 .myClass{ position: relative; background: hsla(300, 100%, 90%, 0.1); overflow: hidden; &::before { background-image: url(/img/bg.jpg); background-size: cover; background-size: cover !important; -webkit-background-size: cover !important; background-repeat: repeat repeat !important; background-attachment: scroll !important;//"fixed" is the desired effect, but mobile browsers find it too "expensive" and disabled it, so use "scroll" background-position: 30% 50%; @media(min-width: $screen-sm-min){ background-attachment: fixed !important; background-position: 30% 20%; will-change: transform; }//768 content: ""; display: block; position: absolute; top: 0; left: 0; width: 100%; height: 100%; opacity: 0.1; } } 

Está funcionando para mim no Windows Chrome, Edge e Safari. Mas não o Firefox.

Outra solução muito simples é usar as unidades vw e vh (que, caso você não saiba, tem suporte de navegador totalmente aceitável para a maioria dos casos). Por exemplo, em vez de fazer background-size: cover , faça background-size: auto 100vh .

Se você não está familiarizado com vw e vh , eles são unidades de viewport e correspondem à largura da viewport e à altura da viewport. Os valores correspondem a uma porcentagem da altura ou largura da janela de exibição. Por exemplo, 50vw significa 50% da largura da janela de visualização.

Para os nossos propósitos, podemos simplesmente dizer ao fundo como sendo 100% da altura da janela de exibição.

Aqui está um violino.

Se você precisar acomodar proporções diferentes, você pode tirar proveito das regras @media da relação de aspecto .

Eu fiz uma versão com imagem de fundo Responsive.

 .flexslider .slides > li { background-position: center center; background-repeat: no-repeat; -webkit-background-size: cover; -moz-background-size: cover; -o-background-size: cover; background-size: cover; } #slider, .alink { min-height: 300px } .alink { display: block } 

http://jsfiddle.net/onigetoc/grpku1gk/

    Intereting Posts