Skalieren Sie das Bild so, dass es in einen Begrenzungsrahmen passt

117

Gibt es eine reine CSS-Lösung, um ein Bild in einen Begrenzungsrahmen zu skalieren (wobei das Seitenverhältnis beibehalten wird)? Dies funktioniert, wenn das Bild größer als der Container ist:

img {
  max-width: 100%;
  max-height: 100%;
}

Beispiel:

Aber ich möchte das Bild vergrößern, bis eine Dimension 100% des Containers beträgt.

Thomas Guillory
quelle
Meinst du wie Höhe: 100% und Breite: 100%? Haben Sie eine gewünschte Dimension, die Sie erreichen möchten? Andernfalls können Sie das Bild auch dehnen und erzwingen, dass es auch diese Abmessungen erreicht.
Mikevoermans
@ Mikevoermans Schauen Sie sich meine beiden ersten Beispiele an: Ich möchte das Bild strecken, bis eine der Dimensionen 100% und die andere <= 100% ist
Thomas Guillory
@ Jacktheripper Natürlich Seitenverhältnis bewahren ...
Thomas Guillory
@gryzzly Die Beispiele sprechen für sich! Wenn sie sich die Beispiele angesehen hatten, war das offensichtlich.
Thomas Guillory
@ Artimuz Ich bin völlig anderer Meinung. Drei der Antworten auf Ihre Fragen (einschließlich meiner) deuten darauf hin, dass dies NICHT offensichtlich war.
Khan

Antworten:

94

Hinweis: Obwohl dies die akzeptierte Antwort ist, ist die folgende Antwort genauer und wird derzeit in allen Browsern unterstützt, wenn Sie die Möglichkeit haben, ein Hintergrundbild zu verwenden.

Nein, es gibt keine CSS-Möglichkeit, dies in beide Richtungen zu tun. Sie könnten hinzufügen

.fillwidth {
    min-width: 100%;
    height: auto;
}

Damit das Element immer 100% breit ist und die Höhe automatisch auf das Seitenverhältnis oder umgekehrt skaliert :

.fillheight {
    min-height: 100%; 
    width: auto;
}

immer auf maximale Höhe und relative Breite skalieren. Um beides zu tun, müssen Sie feststellen, ob das Seitenverhältnis höher oder niedriger als der Container ist, und CSS kann dies nicht.

Der Grund ist, dass CSS nicht weiß, wie die Seite aussieht. Es legt vorher Regeln fest, aber erst danach werden die Elemente gerendert und Sie wissen genau, mit welchen Größen und Verhältnissen Sie es zu tun haben. Dies lässt sich nur mit JavaScript erkennen.


Obwohl Sie nicht nach einer JS-Lösung suchen, werde ich trotzdem eine hinzufügen, wenn jemand sie benötigt. Der einfachste Weg, dies mit JavaScript zu handhaben, besteht darin, eine Klasse hinzuzufügen, die auf dem Unterschied im Verhältnis basiert. Wenn das Verhältnis von Breite zu Höhe des Felds größer als das des Bildes ist, fügen Sie die Klasse "Füllbreite" hinzu, andernfalls die Klasse "Füllhöhe".

Stephan Müller
quelle
7
Tatsächlich gibt es eine Lösung: Festlegen der CSS3-Hintergrundgröße. Siehe meine Antwort.
Thomas Guillory
Du hast vollkommen recht. Obwohl es jetzt eineinhalb Jahre später ist, habe ich meinen Beitrag bearbeitet.
Stephan Müller
4
Ich würde davon ausgehen, dass dies die richtige Antwort auf die gestellte Frage ist. Dies ist das CSS für das img-Tag. Dies ist relevant, da das img-Tag semantisch Inhalt ist und das Bild als Hintergrund für ein div nicht. Während einige Umstände dies unpraktisch machen (wenn Sie das Verhältnis von Bild zu Container nicht kennen), ist es für andere genau richtig. Vielen Dank.
Duncanwilcox
173

Dank CSS3 gibt es eine Lösung!

Die Lösung besteht darin, das Bild als zu setzen background-imageund dann auf background-sizezu setzencontain .

HTML

<div class='bounding-box'>
</div>

CSS

.bounding-box {
  background-image: url(...);
  background-repeat: no-repeat;
  background-size: contain;
}

Testen Sie es hier: http://www.w3schools.com/cssref/playit.asp?filename=playcss_background-size&preval=contain

Volle Kompatibilität mit den neuesten Browsern: http://caniuse.com/background-img-opts

Um das Div in der Mitte auszurichten, können Sie diese Variante verwenden:

.bounding-box {
  background-image: url(...);
  background-size: contain;
  position: absolute;
  background-position: center;
  background-repeat: no-repeat;
  height: 100%;
  width: 100%;
}
Thomas Guillory
quelle
1
Schön, obwohl meine Antwort nicht falsch ist (Sie haben speziell nach dem IMG gefragt), ist dies eine großartige Lösung, und ich hätte darüber nachdenken sollen. Das einzige Problem ist, dass IE 8 immer noch so weit verbreitet ist, dass ich mich noch nicht darauf verlassen möchte, aber trotzdem ein guter Fang.
Stephan Müller
6
Setzen Sie es auf "cover", wenn Sie kein Letterboxing möchten: Hintergrundgröße: enthalten;
Arxpoetica
3
Es ist zu beachten, dass Sie Bild-URLs mit HTML einfügen können : <div class=image style="background-image: url('/images/foo.jpg');"></div>. Alle anderen Stile sollten mit CSS angewendet werden.
Andrey Mikhaylov - lolmaus
14
Ich würde sagen, das ist ein schrecklicher Ansatz. Indem Sie es in ein Hintergrundbild ändern, entfernen Sie die semantische Bedeutung des Bildes im HTML.
Animuson
14
@animuson: Es hat mir immer noch geholfen, da ich HTML / CSS für gedruckte Berichte verwende und keinen Quacksalber über Semantik geben kann :)
Christian Wattengård
37

Hier ist eine hackige Lösung, die ich entdeckt habe:

#image {
    max-width: 10%;
    max-height: 10%;
    transform: scale(10);
}

Dadurch wird das Bild verzehnfacht, aber auf 10% seiner endgültigen Größe beschränkt, wodurch es an den Container gebunden wird.

Im Gegensatz zur background-imageLösung funktioniert dies auch mit <video>Elementen.

Interaktives Beispiel:

Vladimir Panteleev
quelle
1
Ich liebe diese Lösung. Es beantwortet nicht nur die Frage (ich weiß, was für ein Gedanke), es funktioniert auch wunderbar in allen modernen Browsern, ohne auf Javascript zurückgreifen zu müssen!
ndm13
2
Ich würde gerne eine Geige davon sehen. In meinem Test, ein IMG in einen 400x400-Container zu legen, wird das IMG gerade in der Ecke abgeschnitten
Cyberwombat
3
Gute Antwort! @Yashua Sie müssen hinzufügen transform-origin: top left, um das Zuschneiden zu stoppen. / Zombie
XwipeoutX
Brillant. Meine einzige Sorge wäre ein möglicher Verlust der Bildqualität in einem schlecht codierten Browser, aber theoretisch sollte es gut funktionieren!
Codemonkey
Interessant, funktioniert aber nicht in Chrome. Das Ergebnis ist eine beschnittene Bildzeile.
MattK
23

Sagen Sie heute einfach Objektanpassung: enthalten. Support ist alles andere als IE: http://caniuse.com/#feat=object-fit

Glenn Maynard
quelle
3
IE hat zum Zeitpunkt des Schreibens dieses Artikels (12.09.2016, 10:56 Uhr) nur noch etwa 16% Marktanteil und schwindet weiter, daher ist dies die beste Antwort für mich: D
Zhang
8
Bearbeiten Sie die Antworten anderer Personen nicht, um andere Probleme als Tippfehler oder fehlerhafte Links zu beheben. Ich würde in einer SO-Antwort nicht etwas Kindliches wie "Es gibt eine Polyfüllung für Mistbrowser" sagen, und ich schätze es nicht, dass meine Antwort so bearbeitet wird, dass sie so aussieht, wie ich das gesagt habe. Wenn Sie Ihre Wörter verwenden möchten, geben Sie sie in Ihre eigene Antwort ein.
Glenn Maynard
Ich würde sagen, dass nicht IE das Problem ist, sondern Edge. Laut caniuse object-fitist dafür noch in der Entwicklung.
BairDev
Dies sollte eine der am häufigsten gewählten Antworten ab 2017 sein ... Laut dem obigen Caniuse-Link verwenden 90% aller Benutzer weltweit jetzt einen Browser, der dies unterstützt
fgblomqvist
Ich habe gerade eine Antwort gepostet, die mit und ohne funktioniertobject-fit : stackoverflow.com/a/46456673/474031
gabrielmaldi
8

html:

    <div class="container">
      <img class="flowerImg" src="flower.jpg">
    </div>

CSS:

.container{
  width: 100px;
  height: 100px;
}


.flowerImg{
  width: 100px;
  height: 100px;
  object-fit: cover;
  /*object-fit: contain;
  object-fit: scale-down;
  object-position: -10% 0;
  object-fit: none;
  object-fit: fill;*/
}
Deke
quelle
5

Sie können dies mit reinem CSS und vollständiger Browserunterstützung erreichen, sowohl für vertikal lange als auch für horizontal lange Bilder gleichzeitig.

Hier ist ein Ausschnitt, der in Chrome, Firefox und Safari funktioniert (sowohl mit object-fit: scale-downals auch ohne Verwendung):

figure {
  margin: 0;
}

.container {
  display: table-cell;
  vertical-align: middle;
  width: 80px;
  height: 80px;
  border: 1px solid #aaa;
}

.container_image {
  display: block;
  max-width: 100%;
  max-height: 100%;
  margin-left: auto;
  margin-right: auto;
}

.container2_image2 {
  width: 80px;
  height: 80px;
  object-fit: scale-down;
  border: 1px solid #aaa;
}
Without `object-fit: scale-down`:

<br>
<br>

<figure class="container">
  <img class="container_image" src="https://i.imgur.com/EQgexUd.jpg">
</figure>

<br>

<figure class="container">
  <img class="container_image" src="https://i.imgur.com/ptO8pGi.jpg">
</figure>

<br> Using `object-fit: scale-down`:

<br>
<br>

<figure>
  <img class="container2_image2" src="https://i.imgur.com/EQgexUd.jpg">
</figure>

<br>

<figure>
  <img class="container2_image2" src="https://i.imgur.com/ptO8pGi.jpg">
</figure>

gabrielmaldi
quelle
2

Eine andere Lösung ohne Hintergrundbild und ohne Container (obwohl die maximale Größe des Begrenzungsrahmens bekannt sein muss):

img{
  max-height: 100px;
  max-width: 100px;
  width: auto;    /* These two are added only for clarity, */
  height: auto;   /* as the default is auto anyway */
}


Wenn die Verwendung eines Containers erforderlich ist, können die maximale Breite und Höhe auf 100% eingestellt werden:

img {
    max-height: 100%;
    max-width: 100%;
    width: auto; /* These two are added only for clarity, */
    height: auto; /* as the default is auto anyway */
}

div.container {
    width: 100px;
    height: 100px;
}

Dafür hätten Sie so etwas wie:

<table>
    <tr>
        <td>Lorem</td>
        <td>Ipsum<br />dolor</td>
        <td>
            <div class="container"><img src="image5.png" /></div>
        </td>
    </tr>
</table>
xerxeArt
quelle
1

In diesem Beispiel wird das Bild proportional gedehnt, um es an das gesamte Fenster anzupassen. Eine Improvisation zum obigen korrekten Code ist hinzuzufügen$( window ).resize(function(){});

function stretchImg(){
    $('div').each(function() {
      ($(this).height() > $(this).find('img').height()) 
        ? $(this).find('img').removeClass('fillwidth').addClass('fillheight')
        : '';
      ($(this).width() > $(this).find('img').width()) 
        ? $(this).find('img').removeClass('fillheight').addClass('fillwidth')
        : '';
    });
}
stretchImg();

$( window ).resize(function() {
    strechImg();
});

Es gibt zwei if-Bedingungen. Der erste prüft ständig, ob die Bildhöhe kleiner als der div ist, und wendet die .fillheightKlasse an, während der nächste die Breite prüft und die .fillwidthKlasse anwendet . In beiden Fällen wird die andere Klasse mit entfernt.removeClass()

Hier ist das CSS

.fillwidth { 
   width: 100%;
   max-width: none;
   height: auto; 
}
.fillheight { 
   height: 100vh;
   max-width: none;
   width: auto; 
}

Sie können ersetzen 100vhdurch , 100%wenn Sie mit in einem div um das Bild zu strecken. In diesem Beispiel wird das Bild proportional gedehnt, um es an das gesamte Fenster anzupassen.

Herr JCRP
quelle
OP forderte ausdrücklich einen Nur-CSS-Ansatz.
Colt McCormack
0

Möchten Sie nach oben, aber nicht nach unten skalieren?

div {
    border: solid 1px green;
    width: 60px;
    height: 70px;
}

div img {
    width: 100%;
    height: 100%;
    min-height: 500px;
    min-width: 500px;
    outline: solid 1px red;
}

Dies sperrt jedoch nicht das Seitenverhältnis.

ericosg
quelle
5
Versuchen Sie, Ihre Erwartungen ein wenig klarer zu formulieren, bevor Sie die Antwort einer anderen Person ablehnen. Besonders wenn sie Ihre Frage beantwortet haben, bevor Sie Ihre Frage mit Änderungen geklärt haben.
Khan
2
Versuchen Sie auch, höflicher zu sein. Niemand wird dir helfen, wenn du so redest.
Mischa Reyzlin
@Artimuz Ich entschuldige mich, wenn ich Sie falsch geführt habe, aber es schien mir unklar, dass Sie das Seitenverhältnis beibehalten wollten, weshalb ich dies ausdrücklich kommentierte. Außerdem werden Sie feststellen, dass ich einen Ausschnitt Ihres Codes aus den Beispielen eingefügt habe. Ich glaube, die Höhe zu halten: auto; erledigt das für Sie, wenn Sie eine Breite angeben.
Ericosg
0

Ich habe Tabelle verwendet, um Bild in der Box zu zentrieren. Es behält das Seitenverhältnis bei und skaliert das Bild so, dass es sich vollständig in der Box befindet. Wenn das Bild kleiner als das Feld ist, wird es so angezeigt, wie es sich in der Mitte befindet. Der folgende Code verwendet ein Feld mit einer Breite von 40 Pixel und einer Höhe von 40 Pixel. (Ich bin mir nicht ganz sicher, wie gut es funktioniert, da ich es aus einem anderen komplexeren Code entfernt und ein wenig vereinfacht habe.)

CSS:

.SmallThumbnailContainer
{
    display: inline-block; position: relative;
    float: left;    
    width: 40px;
    height: 40px;
    border: 1px solid #ccc;
    margin: 0px; padding: 0px;
}
.SmallThumbnailContainer { width: 40px; margin: 0px 10px 0px 0px; } 
.SmallThumbnailContainer tr { height: 40px; text-align: center; }
.SmallThumbnailContainer tr td { vertical-align: middle; position: relative; width: 40px;  }
.SmallThumbnailContainer tr td img { overflow: hidden; max-height: 40px; max-width: 40px; vertical-align: middle; margin: -1px -1px 1px -1px; }

HTML:

<table class="SmallThumbnailContainer" cellpadding="0" cellspacing="0">
    <tr><td>
        <img src="thumbnail.jpg" alt="alternative text"/>
    </td></tr>
    </table>
Antti
quelle
0

Der sauberste und einfachste Weg, dies zu tun:

Zuerst etwas CSS:

div.image-wrapper {
    height: 230px; /* Suggestive number; pick your own height as desired */
    position: relative;
    overflow: hidden; /* This will do the magic */
    width: 300px; /* Pick an appropriate width as desired, unless you already use a grid, in that case use 100% */
}
img {
    width: 100%;
    position: absolute;
    left: 0;
    top: 0;
    height: auto;
}

Der HTML:

<div class="image-wrapper">
  <img src="yourSource.jpg">
</div>

Dies sollte den Trick machen!

Robert Eetheart
quelle
0

Das hat mir geholfen:

.img-class {
  width: <img width>;
  height: <img height>;
  content: url('/path/to/img.png');
}

Dann auf dem Element (Sie können Javascript oder Medienabfragen verwenden, um die Reaktionsfähigkeit zu erhöhen):

<div class='img-class' style='transform: scale(X);'></div>

Hoffe das hilft!

bman93
quelle
-3
.boundingbox {
    width: 400px;
    height: 500px;
    border: 2px solid #F63;
}
img{
    width:400px;
    max-height: 500px;
    height:auto;
}

Ich bearbeite meine Antwort, um meine Lösung weiter zu erläutern, da ich eine Abwertung habe.

Mit den oben in CSS gezeigten Stilen zeigt das folgende HTML-Div nun, dass das Bild immer in der Breite passt, und passt das Seitenverhältnis der Höhe zur Breite an. Somit wird das Bild so skaliert, dass es zu einem Begrenzungsrahmen passt, wie in der Frage gestellt.

<div class="boundingbox"><img src="image.jpg"/></div>
Zeeawan
quelle
Diese Antwort funktioniert nur, wenn die Box größer als breit ist.
XwipeoutX