Fondo de CSS: tapa + fondo-adjunto: imágenes de fondo de recorte fijo

Tengo una lista de figuras que contienen imágenes de fondo. Algo como lo siguiente:

Cada una de estas imágenes tiene su background-size configurado para cover y el conjunto de background-attachment fijado a fixed .

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

Cuando cada una de las figuras ocupa toda la ventana gráfica, funciona bien, pero si hay un desplazamiento de cualquier tipo, la imagen de fondo queda recortada.

Por lo que puedo decir, esto es por diseño ( https://developer.mozilla.org/en-US/docs/Web/CSS/background-size#Values ).

Me gustaría que las imágenes se recorten vertical u horizontalmente, pero no ambas, y que estén centradas por el tamaño de la figura misma.

Sé que hay soluciones de JavaScript, pero ¿hay alguna forma de hacerlo con CSS?

Aquí hay un ejemplo de trabajo: http://codepen.io/Godwin/pen/KepiJ

Desafortunadamente, esto es simplemente un artefacto de cómo funciona el posicionamiento fijo en CSS y no hay forma de evitarlo en CSS puro, tienes que usar Javascript.

La razón por la que esto ocurre se debe a la combinación de background-attachment: fixed de background-attachment: fixed y de background-size: cover . Cuando especifica background-attachment: fixed , esencialmente hace que la background-image comporte como si fuera una position: fixed imagen position: fixed , lo que significa que se saca del contexto de posicionamiento y flujo de la página y se relaciona con la ventana gráfica en lugar del elemento la imagen de fondo de.

Por lo tanto, cada vez que utilice estas propiedades, el valor de la cover se calcula en relación con el tamaño de la ventana gráfica, independientemente del tamaño del elemento, por lo que funciona como se espera cuando el elemento tiene el mismo tamaño que la ventana gráfica pero está recortada de maneras inesperadas cuando el elemento es más pequeño que la ventana gráfica.

Para evitar esto, básicamente necesita utilizar background-attachment: scroll y vincular un detector de eventos al evento de scroll en JS que actualiza manualmente la background-position relativa a qué tan lejos se ha desplazado la ventana para simular el posicionamiento fijo, pero aún calcular background-size: cover relativa al elemento contenedor en lugar de a la ventana gráfica.

Hay una solución de jQuery para esto: http://jsfiddle.net/QN9cH/1/ Sé que no es óptimo, pero al 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 ; 

No hay una solución real. Sin embargo, puede hacer que la altura del tamaño de la imagen sea auto lugar de cover . Y ajuste el tamaño del ancho en% en su elemento hasta que muerda el borde.

Verá si cambia el tamaño de su ventana, no se recortará. En cambio, siempre mantendrá el formato de tamaño de imagen original. Con esto encima, básicamente lo “acerca” pero no lo “tapa”.

El fondo de pantalla: cubierta; de hecho, la propiedad está recortando la imagen para que ocupe el área y no tenga ningún espacio vacío.

El tamaño de fondo: contiene; la propiedad es determinar qué dimensión es más grande y escala de acuerdo con eso. Por lo tanto, si tiene un bloque de 100 px x 100 px y una imagen de fondo de 200×150 px, al configurar el tamaño de fondo para que contenga se escalará la imagen a 100×75 px. Sin embargo, en este escenario, tendrá espacio vacío si la relación de aspecto del elemento es diferente a la de la imagen.

También puede controlar manualmente qué proporción tiene prioridad, suponiendo que conozca la relación de aspecto de la imagen.

Entonces, si sabes que tu imagen siempre es 100x200px, esto significa que el ancho siempre es la dimensión pequeña y la altura la grande.

Ahora configurando el tamaño de fondo: 100% automático; se asegurará de que no tendrá espacio vacío, pero terminará con recorte. Si lo configura en fondo de tamaño: auto 100%; se asegurará de que no se produzca ningún recorte y la altura nunca tendrá espacio vacío (pero sí el ancho).

Si desea recortar y simplemente centrar la imagen, use la posición de fondo: 50% ;.

La respuesta de Nick Noordijk me puso en el camino correcto, pero me gusta evitar las secuencias de comandos que realizan un cálculo cada vez que ocurre el evento de desplazamiento. Aquí está mi versión que solo realiza el cálculo cuando la página carga o cambia el tamaño de la pantalla:

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 + '%'); } 

Tenga en cuenta que esto realmente solo funciona con imágenes de “banner” horizontales, usando background-size: auto nn% no tiene la misma ventaja que el background-size: cover en funcionamiento, sin importar si su imagen tiene exceso en cualquier dirección.

Un ejemplo de efecto de paralaje para elementos dispuestos por separado (no para elementos de pantalla completa):

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 

Actualización en julio de 2018: ahora hay una solución de 1 línea para este problema

Tuve el mismo problema hasta que leí este artículo , que me enseñó que podría agregar esta línea a mi CSS para que funcione:

will-change: transform;

¡Funcionó!

Ahora mi CSS se ve así:

 .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; } } 

Me funciona en Windows Chrome, Edge y Safari. Pero no Firefox.

Otra solución muy simple es utilizar las unidades vw y vh (que, en caso de que no lo supiera, tiene soporte de navegación totalmente aceptable para la mayoría de los casos). Por ejemplo, en lugar de hacer background-size: cover , haz background-size: auto 100vh .

Si no está familiarizado con vw y vh , son unidades de ventana gráfica y corresponden al ancho de la ventana gráfica y la altura de la ventana gráfica. Los valores corresponden a un porcentaje del alto o ancho de la ventana gráfica. Por ejemplo, 50vw significa el 50% del ancho de la ventana 50vw .

Para nuestros propósitos, podemos simplemente decir que el fondo es el 100% de la altura de la ventana gráfica.

Aquí hay un violín.

Si necesita acomodarse a diferentes relaciones de aspecto, puede aprovechar las reglas de ratio de aspecto @media .

Hice una versión con una imagen de fondo receptiva.

 .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