it-swarm.com.de

CSS-Hintergrundgröße: Cover + Hintergrundanhang: Clip-Hintergrundbilder korrigiert

Ich habe eine Liste mit Abbildungen, die Hintergrundbilder enthalten. Etwas wie das Folgende:

<ul>
  <li>
    <figure style="background-image: url(...);"></figure>
  </li>
  <li>
    <figure style="background-image: url(...);"></figure>
  </li>
  <li>
    <figure style="background-image: url(...);"></figure>
  </li>
</ul>

Für jedes dieser Bilder ist background-size auf cover und background-attachment auf fixed gesetzt.

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

Wenn jede der Figuren das gesamte Ansichtsfenster einnimmt, funktioniert dies einwandfrei. Wenn jedoch irgendein Versatz auftritt, wird das Hintergrundbild abgeschnitten.

Soweit ich das beurteilen kann, ist dies beabsichtigt ( https://developer.mozilla.org/en-US/docs/Web/CSS/background-size#Values ​​ ).

Ich möchte, dass die Bilder entweder vertikal oder horizontal, jedoch nicht beides, geschnitten werden und durch die Größe der Figur selbst zentriert werden.

Ich weiß, dass es Javascript-Lösungen gibt, aber gibt es eine Möglichkeit, dies mit CSS zu tun?

Hier ist ein Arbeitsbeispiel: http://codepen.io/Godwin/pen/KepiJ

33
Godwin

Leider handelt es sich hierbei lediglich um ein Artefakt der Funktionsweise der festen Positionierung in CSS, und in reinem CSS führt kein Weg daran vorbei - Sie müssen Javascript verwenden.

Der Grund dafür liegt in der Kombination von background-attachment: fixed und background-size: cover. Wenn Sie background-attachment: fixed angeben, verhält sich background-image im Wesentlichen wie ein position: fixed-Bild. Dies bedeutet, dass es aus dem Seitenfluss und dem Positionierungskontext entfernt wird und relativ zum Ansichtsfenster wird, anstatt zu dem Element, in dem es das Hintergrundbild ist.

Immer wenn Sie diese Eigenschaften zusammen verwenden, wird der cover-Wert unabhängig von der Größe des Elements selbst relativ zur Größe des Ansichtsfensters berechnet. Aus diesem Grund funktioniert er wie erwartet, wenn das Element die gleiche Größe wie das Ansichtsfenster hat, aber abgeschnitten ist auf unerwartete Weise, wenn das Element kleiner als das Ansichtsfenster ist.

Um dies zu umgehen, müssen Sie im Grunde background-attachment: scroll verwenden und einen Ereignis-Listener an das scroll -Ereignis in JS binden, das den background-position relativ zu dem Bildlauf des Fensters manuell aktualisiert, um eine feste Positionierung zu simulieren, jedoch background-size: cover relativ zum Containerelement zu berechnen anstatt des Viewports.

53
Ennui

Es gibt ein jQuery-Update für dieses Problem: http://jsfiddle.net/QN9cH/1/ Ich weiß, es ist nicht optimal, aber es funktioniert zumindest 

$(window).scroll(function() {
  var scrolledY = $(window).scrollTop();
  $('#container').css('background-position', 'left ' + ((scrolledY)) + 'px');
});
22
Nick Noordijk
background: url(<image>) center top no-repeat fixed;
background-size: auto <width size in %>;

Es gibt keine echte Lösung. Sie können jedoch anstelle von auto die Größenhöhe des Bildes cover festlegen. Passen Sie die Breitengröße in% in Ihrem Element an, bis es an den Rand reicht. 

Sie sehen, wenn Sie die Größe Ihres Fensters ändern, wird es nicht abgeschnitten. Stattdessen bleibt das ursprüngliche Bildformat immer erhalten. Mit diesem "Zoomen" zoomen Sie es im Grunde, aber verdecken es nicht.

2
Thielicious

Die Hintergrundgröße: Cover; Eigenschaft ist in der Tat das Bild beschneiden, damit es den Bereich ausfüllt und keinen leeren Raum hat.

Die Hintergrundgröße: enthalten; Die Eigenschaft bestimmt, welche Dimension größer ist, und skaliert danach. Wenn Sie also einen 100px x 100px-Block und ein Hintergrundbild von 200x150px haben, wird das Bild bei Einstellung der Hintergrundgröße auf 100x75px skaliert. In diesem Szenario haben Sie jedoch leeren Platz, wenn das Seitenverhältnis des Elements von dem des Bildes abweicht. 

Sie können auch manuell steuern, welcher Anteil Vorrang hat, vorausgesetzt, Sie kennen das Seitenverhältnis des Bildes. 

Wenn Sie also wissen, dass Ihr Bild immer 100x200px ist, bedeutet dies, dass die Breite immer das kleine Maß und die Höhe das große ist. 

Jetzt die Hintergrundgröße einstellen: 100% auto; sorgt dafür, dass Sie keinen leeren Platz erhalten, aber Sie werden mit dem Beschneiden enden. Wenn Sie die Hintergrundgröße einstellen: auto 100%; Dadurch wird sichergestellt, dass keine Beschneidung erfolgt und die Höhe niemals leer ist (aber die Breite).

Wenn Sie das Bild ausschneiden und nur das Bild zentrieren möchten, verwenden Sie die Hintergrundposition: 50% ;.

1
kakashigr

Nick Noordijks Antwort brachte mich auf die richtige Spur, aber ich vermeide es, Skripts zu vermeiden, die bei jedem Scroll-Ereignis eine Berechnung durchführen. Hier ist meine Version, die die Berechnung nur ausführt, wenn die Seite geladen oder die Bildschirmgröße geändert wird:

html:

<div class="fake-img"></div>

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

Beachten Sie, dass dies wirklich nur bei "Banner" -Landbildern funktioniert. Die Verwendung von background-size: auto nn% hat nicht den gleichen Vorteil wie background-size: cover beim Arbeiten, unabhängig davon, ob Ihr Bild in beide Richtungen übermäßig ist.

0
squarecandy

Ein Beispiel für den Parallaxeffekt für separat angeordnete Elemente (nicht für Vollbildelemente)

html:

<div style="background-image: url('/path/to/image.jpg')">Content</div>

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<scrollAreaHeight) {
            var backgroundPositionOffset = Math.ceil(scrollAmountPx/scrollAreaHeight*elementOffsetFromBottom);
            //$(this).css('background-position-y',"-"+backgroundPositionOffset+"px");
            $(this).clearQueue().animate({'background-position-y':"-"+backgroundPositionOffset+"px"},50);
        }
    });
});
0
baduga

Update im Juli 2018: Es gibt jetzt eine einzeilige Lösung für dieses Problem

Ich hatte das gleiche Problem, bis ich diesen Artikel gelesen habe, das mich lehrte, dass ich diese Zeile in mein CSS einfügen könnte, damit es funktioniert:

will-change: transform;

Es funktionierte!

Nun sieht mein CSS so aus:

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

Es funktioniert für mich unter Windows Chrome, Edge und Safari. Aber nicht Firefox.

0
Ryan

Eine andere sehr einfache Lösung ist die Verwendung der vw- und vh-Einheiten (die, falls Sie nicht wussten, völlig passable Browserunterstützung für die meisten Fälle hat). Anstelle von background-size: cover können Sie beispielsweise background-size: auto 100vh ausführen.

Wenn Sie nicht mit vw und vh vertraut sind, handelt es sich um Ansichtsfenster-Einheiten, die der Ansichtsfensterbreite und der Ansichtsfensterhöhe entsprechen. Die Werte entsprechen einem Prozentsatz der Höhe oder Breite des Ansichtsfensters. Zum Beispiel bedeutet 50vw 50% der Breite des Darstellungsbereichs.

Für unsere Zwecke können wir einfach angeben, dass der Hintergrund 100% der Höhe des Ansichtsfensters beträgt.

Hier ist eine Geige.

Wenn Sie unterschiedliche Seitenverhältnisse berücksichtigen müssen, können Sie das Seitenverhältnis @media rules nutzen.

0
Pete