Der folgende Beitrag ist ein Gastbeitrag von Parker Bennett, in dem er verschiedene Ansätze für das Verhalten von flüssigen und responsiven Bildern untersucht.
Manchmal möchten Sie, dass sich ein Bild responsiv vergrößert, aber seine Höhe einschränkt – und es dann zuschneidet, wenn es breiter wird. Hier untersuchen wir drei Optionen mit verschiedenen Kompromissen.
background-position: center bottom.Option Eins: background-image
Hier erstellen wir anstelle eines <img> einen Div mit einem background-image und verwenden das schicke neue background-size: cover von CSS3, um es proportional zu skalieren. Als Bonus können wir es mit background-position einfach von oben, Mitte oder unten zuschneiden.
Ein potenzielles Problem ist, dass wir eine Höhe für den div angeben müssen, damit er angezeigt wird. Dies gibt ihm eine feste Höhe, die nicht proportional skaliert (zumindest nicht ohne CSS-Medienabfragen). Wenn er schmal genug wird, beginnen die Seiten abzuschneiden (dies könnte bevorzugt werden, es kommt darauf an).
Außerdem zeigt ein schneller Check auf caniuse.com, dass dies in IE8 auffällig fehlschlagen wird (das Bild wird in voller Größe angezeigt), aber dank Louis-Rémi Babé gibt es einen Hintergrundgrößen-Polyfill-Workaround (obwohl er eine relative oder feste Position und einen z-Index erfordert). IE8 benötigt auch ein Polyfill für CSS-Medienabfragen. Es gibt ein paar Optionen.
.bg-image {
/* image specified in separate class below */
height: 240px;
width: 100%;
}
.bg-image-wedding {
background-image: url(img/photo-wedding_1200x800.jpg);
/* lt ie8 */
-ms-background-position-x: center;
-ms-background-position-y: bottom;
background-position: center bottom;
/* scale bg image proportionately */
background-size: cover;
/* ie8 workaround - http://louisremi.github.io/background-size-polyfill/ */
-ms-behavior: url(/backgroundsize.min.htc);
/* prevent scaling past src width (or not) */
/* max-width: 1200px; */
}
/* example media queries */
@media only screen and (min-width : 768px) {
.bg-image { height: 320px; }
}
@media only screen and (min-width : 1200px) {
.bg-image { height: 400px; }
}
background-position: center center.Eine Anmerkung: background-size: cover skaliert leicht über die native Größe des Quellbildes hinaus (oder nicht, wenn Sie eine max-width festlegen).*
Dennoch gibt es einige Nachteile bei der Verwendung eines background-image. Es ist nicht so semantisch oder modular wie ein img, daher ist es weniger einfach zu warten. Sie scheinen an eine feste Höhe oder umständliche CSS-Medienabfragen gebunden zu sein. Außerdem können Benutzer das Bild nicht so einfach speichern (manchmal bevorzugt).
Option Zwei: img mit einem Dreh
Hier verwenden wir ein img mit max-width auf einen Prozentsatz des enthaltenden Elements eingestellt, damit es responsiv skaliert, und verpacken es dann in einen Div mit overflow: hidden und einer bestimmten Höhe oder max-height.
.crop-height {
/* max-width: 1200px; /* img src width (if known) */
max-height: 320px;
overflow: hidden;
}
img.scale {
/* corrects inline gap in enclosing div */
display: block;
max-width: 100%;
/* just in case, to force correct aspect ratio */
height: auto !important;
width: auto\9; /* ie8+9 */
/* lt ie8 */
-ms-interpolation-mode: bicubic;
}
Wie Sie sehen können, wird der untere Teil des Bildes nun abgeschnitten, wenn es breiter wird. Aber was ist, wenn Sie möchten, dass es von oben abgeschnitten wird? Überraschenderweise können Sie das – mit CSS3s transform:rotate() fügen wir sowohl img.scale als auch div.crop-height eine "Flip"-Klasse hinzu – und drehen das Bild komplett.
/* apply to both img.scale and div.crop-height */
.flip {
-webkit-transform: rotate(180deg);
-moz-transform: rotate(180deg);
-ms-transform: rotate(180deg);
-o-transform: rotate(180deg);
transform: rotate(180deg);
/* needed? not sure */
zoom: 1;
}
img.flip {
/* if native or declared width of img.scale
is less than div.crop-height, this will
flipped img left */
float: right;
/* add clearfix if needed */
}
Novell, aber auf das Zuschneiden von oben beschränkt. Und wie Sie vielleicht erwarten, funktioniert dies auch nicht in IE8 – vielleicht weniger auffällig fehlschlagend (es wird einfach wie zuvor von unten abgeschnitten). Die schlechte Nachricht ist, dass ich keine Polyfill- Optionen gefunden habe, die funktionieren, da sie eine bestimmte Höhe und Breite benötigen.
Option Drei: Hybrider Ansatz
Was wäre, wenn wir die Vorteile der Angabe eines img hätten (z. B. Verwendung von max-height, sodass wir eine proportionale vertikale Skalierung unterhalb einer bestimmten Höhe erhalten), aber auch die flexible Zuschneide- und IE8-Polyfill-Unterstützung eines background-image? Das können wir!
visibility: hidden, das background-image hat background-position: center center.Der Trick besteht darin, das responsiv skalierende img *unsichtbar* zu machen. Mit visibility: hidden behält es das Layout, sodass wir das background-image dahinter sehen. (Da es sich um dieselbe Bildquelle handelt, sollte es nicht zweimal heruntergeladen werden.) Wenn Sie benutzerfreundlichen Zugriff wünschen, könnten Sie stattdessen opacity: 0 verwenden. Jetzt können Benutzer das Bild ziehen oder mit der rechten Maustaste speichern. (Opacity und background-size benötigen einige zusätzliche IE8-Workaround-Bits.)
opacity: 0. Ein Hintergrundbild, das Sie ziehen oder mit der rechten Maustaste speichern können. Funktioniert in IE8 (mit Hilfe).Ein weiterer Gedanke ist, ein komprimierteres Proxy-img zu verwenden und CSS-Medienabfragen zu verwenden, um bei Bedarf ein hochauflösenderes background-image bereitzustellen. Dieses Bild könnte sogar eine proportional kleinere Größe haben (z. B. passend zu Ihrer max-height) oder mit einem Wasserzeichen versehen sein. Schauen Sie sich diesen CSS-Tricks-Beitrag zu Medienabfragen und diesen hilfreichen Auflösungs-Mixin für Sass an.
img den Platz für das höherauflösende background-image..crop-height {
/* max-width: 1200px; /* img src width (if known) */
max-height: 320px;
overflow: hidden; }
.bg-image-wedding {
/* for small devices */
background-image: url(img/photo-wedding_1200x800.jpg);
/* lt ie8 */
-ms-background-position-x: center;
-ms-background-position-y: bottom;
background-position: center bottom;
/* scale bg image proportionately */
background-size: cover;
/* ie8 workaround - http://louisremi.github.io/background-size-polyfill/ */
-ms-behavior: url(/backgroundsize.min.htc);
*/ prevent scaling past src width (or not) */
/* max-width: 1200px; */ }
.invisible {
visibility: hidden; }
.transparent {
/* trigger hasLayout for IE filters below */
zoom: 1;
/* 0 opacity in filters still displays layout */
-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
filter: alpha(opacity=10);
opacity: 0; }
/* example media query for smaller non-retina devices */
@media
only screen and (max-device-width : 600px) and (-webkit-max-device-pixel-ratio: 1),
only screen and (max-device-width : 600px) and ( max-device-pixel-ratio: 1) {
.bg-image-wedding {
background-image: url(img/photo-wedding_600x400.jpg);
}
}
/* example media query for retina ipad and up */
@media
only screen and (min-device-width : 768px) and (-webkit-min-device-pixel-ratio: 1.5),
only screen and (min-device-width : 768px) and ( min-device-pixel-ratio: 1.5) {
.bg-image-wedding {
background-image: url(img/[email protected]);
}
}
Zusammenfassend
Bis zu dem Tag, an dem CSS3s object-fit unterstützt wird, was noch eine Weile dauern kann, scheint dieser hybride Ansatz meiner Meinung nach der beste Weg zu sein. Dennoch ist es schön, Optionen zu haben. Ich hoffe, Sie haben etwas aus meiner viel zu gründlichen Untersuchung mitgenommen. Sie können sich den Quellcode für weitere Informationen ansehen (Option Eins, Zwei oder Drei) oder die Beispieldateien hier herunterladen. Wenn Sie Fragen, Kommentare oder Korrekturen haben, schreiben Sie mir: parker@parkerbennett.com.
* Sie können ein Bild wie ein Hintergrundbild skalieren, wenn Sie möchten. Sie müssen es nur "vorab vergrößern" und dem Bildelement selbst eine proportional größere Breite und Höhe hinzufügen: <img width="2400px" height="1600px" src="img/photo-wedding_1200x800.jpg /> (auf CodePen bearbeiten).
Sieht aus, als würde jemand im Hintergrund zu Tode geprügelt :S
LOL! Gut erkannt :)
Hat mich dazu gebracht, mir das Bild genauer anzusehen. Auch ein paar andere interessante Leute dort.
Hätte gerne eine Sekunde später den Schnappschuss gesehen…
Hallo Parker,
Guter Beitrag! Ich verfolge diese Website in meinem Feed-Reader und mag sie sehr.
Zu deinem Beitrag
Was ist mit der Verwendung von background-size:100% und background-position:bottom center?
<< div style=”display:block; width:100%; height:300px; background-image:url(http://cdn.css-tricks.com/wp-content/uploads/2013/06/photo-wedding_1200x800.jpg); background-position:bottom center; background-size:100%;”>
http://jsfiddle.net/gomidefabio/BVXGj/1/
Danke, Fabio! Du siehst, wie sich
background-size:100%unterscheidet, wenn du das Fenster kleiner als das Seitenverhältnis des Bildes machst. In deinem Beispiel wiederholt sich das Bild vertikal. Wir könnenbackground-repeat: no-repeathinzufügen, aber mit dem Bild unten in der Mitte sehen wir oben eine Lücke, da der Div 300px hoch bleibt, während das Bild kleiner wird. Mitbackground-size:coverfüllt das Bild diese Lücke, schneidet aber an den Seiten ab.Danke für diesen großartigen Beitrag. Ich baue gerade etwas und mit nur einer Zeile deines Beispiels hast du etwa 5 Probleme für mich gelöst. Toller Beitrag.
Toller Artikel über CSS, qualitativ hochwertige Inhalte für Front-End-Ingenieure!!!
Gibt es eine einfache Möglichkeit, dieses Bild mit der Maus zu verschieben (um den Rest des Fotos zu sehen)?
Oder du kannst den Padding-Trick verwenden, um ein responsives Seitenverhältnis beizubehalten und das Bild darin zu zentrieren.
Danke, Corey! Ich habe diesen "Padding-Trick" zum CodePen für Option Eins zur Veranschaulichung hinzugefügt.
Das Problem damit ist, dass es die Höhe des Bildes nicht begrenzt, was der Grund war, warum ich mich damit beschäftigt habe (ich hatte einen Kunden, der wollte, dass die Dinge "über dem Falz" sind). Es verhält sich ähnlich wie
max-width:100%auf einem img, außer dass Sie einige Zuschneideflexibilität durch die Verwendung vonbackground-positionund Variation despadding-bottomhaben.^ das.
Das können Sie sogar auf dem img-Element selbst tun, um einen zusätzlichen Wrapper-DIV zu vermeiden.
img {height: 0; padding: 0 0 40%; background: url(img/photo-wedding_1200x800.jpg) center bottom;}Und wie wäre es, die img src in der hybriden Option durch ein inline 1x1px großes transparentes Bild zu ersetzen, um das Laden beider zu vermeiden http://parkerbennett.com/croptop/img/photo-wedding_1200x800.jpg und http://parkerbennett.com/croptop/img/photo-wedding_600x400.jpg beim Start (Chrome lädt beide Bilder). Es ist vielleicht nicht sehr semantisch freundlich, reduziert aber eine Anfrage.
Das können Sie – und Sie können die HTTP-Anfrage ganz vermeiden, indem Sie das 1-Pixel-GIF als Daten-URI codieren
img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"Aber abgesehen davon, dass es weniger semantisch und benutzerfreundlich ist, funktioniert es nicht, ein Seitenverhältnis durch Angabe von Höhe und Breite festzulegen – wenn sich Ihr Bild verkleinert, wird es zu einem Quadrat. Ich habe den CodePen für Option Drei angehängt, um dies zu demonstrieren. (Sie könnten ein transparentes GIF mit einem übereinstimmenden Seitenverhältnis erstellen, z. B. 3px mal 2px, wenn das Beibehalten wichtig ist.)
Hallo Parker,
Sie haben Recht. Ich habe das ein paar Sekunden, nachdem ich die E-Mail gesendet habe, bemerkt. Entschuldigen Sie das. Ich habe also sofort einen JSFIDDLE-Test erstellt und ihn hier gepostet, aber aus irgendeinem Grund wurde die letzte Version des Codes nicht gespeichert. Ich habe sie wieder dort platziert, falls Sie einen Blick darauf werfen möchten. Diese Korrektur ist jedoch nur geeignet, wenn die Bilder, die in diesen Feldern verwendet werden, ein bestimmtes Seitenverhältnis beibehalten.
Ps.: Ich bin mir nicht sicher, ob Sie wollten, dass jemand Ihren Kommentarbereich mit zusätzlichen Ideen füllt (wie ich es tue), aber mir gefiel die Frage im Zusammenhang mit Ihrem Beitrag, also habe ich versucht zu sehen, wie ich sie selbst machen würde. Vielleicht kann jemand den von mir gegebenen Ansatz zur Frage verbessern.
http://jsfiddle.net/gomidefabio/BVXGj/15/
Hey, das ist großartig, Fabio – das ist genau die Art von Ideenaustausch, auf die ich gehofft hatte!
Zusammenfassend schlug Fabio eine Verfeinerung von Option Eins vor: Wenn die Bildbreite im Verhältnis zur deklarierten Höhe steht, verwenden Sie eine Medienabfrage, um die Höhe auf auto umzuschalten. Nun wird sich das Bild weiterhin proportional skalieren. Schlau!
Ah. Ich sollte klarstellen, Fabio. Ihr Ansatz funktioniert, aber er dupliziert im Grunde das, was
max-height:500pxtun würde, ohne dass eine Medienabfrage benötigt wird. Das ist der Vorteil der Verwendung eines transparenten Platzhalter-img – es liefert die Höhe, die wir sonst für die Anzeige des Hintergrundbildes angeben müssten, und wir können es mit min-width, max-width, min-height oder max-height einschränken.Toller Beitrag Chris – er kam genau zur richtigen Zeit, da ich an etwas Ähnlichem arbeitete. Ich gebe es zu, ich werde den Code stehlen, aber die Ehre gebührt, wo sie fällig ist :-)
Hey, ich habe vergessen zu erwähnen, dass Sie das Zuschneiden mit
background-positionmit Prozentsätzen feinabstimmen können, z. B.background-position: 30% 60%. Ich habe den CodePen zu Option Drei überarbeitet, um dies zu demonstrieren.Oh Mann! Vielen Dank für diesen Beitrag! Er hat mir eine Menge Arbeit erspart. Die Eigenschaft
background-size:coverist großartig. Nochmals vielen Dank!