ปรับขนาดภาพให้พอดีกับกรอบขอบ


117

มีวิธีแก้ปัญหาเฉพาะ css ในการปรับขนาดภาพให้เป็นกรอบ (รักษาอัตราส่วน) หรือไม่ วิธีนี้ใช้ได้ผลถ้ารูปภาพใหญ่กว่าคอนเทนเนอร์:

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

ตัวอย่าง:

แต่ฉันต้องการปรับขนาดรูปภาพจนกว่าขนาดจะเท่ากับ 100% ของคอนเทนเนอร์


คุณหมายถึงความสูง: 100% และความกว้าง: 100%? คุณมีมิติข้อมูลที่ต้องการหรือไม่? มิฉะนั้นคุณสามารถยืดภาพและบังคับให้เข้าถึงขนาดเหล่านั้นได้เช่นกัน
mikevoermans

@mikevoermans ดูสองตัวอย่างแรกของฉัน: ฉันต้องการขยายภาพจนกว่าหนึ่งในขนาดจะเป็น 100% และอีกอันคือ <= 100%
Thomas Guillory

@jacktheripper การอนุรักษ์อัตราส่วนภาพแน่นอน ...
Thomas Guillory

@gryzzly ตัวอย่างพูดเพื่อตัวเอง! หากพวกเขาดูตัวอย่างนั่นก็ชัดเจน
Thomas Guillory

@Artimuz ฉันไม่เห็นด้วยอย่างสิ้นเชิง คำตอบสามข้อสำหรับคำถามของคุณ (รวมถึงของฉัน) ชี้ให้เห็นว่ามันไม่ชัดเจน
Khan

คำตอบ:


94

หมายเหตุ: แม้ว่านี่จะเป็นคำตอบที่ยอมรับ แต่คำตอบด้านล่างนี้มีความถูกต้องมากกว่าและในขณะนี้ได้รับการสนับสนุนในทุกเบราว์เซอร์หากคุณมีตัวเลือกในการใช้ภาพพื้นหลัง

ไม่ไม่มี CSS วิธีเดียวที่จะทำได้ทั้งสองทิศทาง คุณสามารถเพิ่ม

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

เพื่อให้องค์ประกอบมีความกว้าง 100% เสมอและปรับขนาดความสูงเป็นอัตราส่วนภาพหรือผกผันโดยอัตโนมัติ:

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

เพื่อปรับขนาดเป็นความสูงสูงสุดและความกว้างสัมพัทธ์เสมอ ในการทำทั้งสองอย่างคุณจะต้องพิจารณาว่าอัตราส่วนกว้างยาวสูงหรือต่ำกว่าคอนเทนเนอร์หรือไม่และ CSS ไม่สามารถทำได้

เหตุผลก็คือ CSS ไม่ทราบว่าหน้าตาเป็นอย่างไร มันตั้งกฎไว้ล่วงหน้า แต่หลังจากนั้นองค์ประกอบจะได้รับการแสดงผลและคุณรู้ว่าคุณกำลังจัดการกับขนาดและอัตราส่วนเท่าใด วิธีเดียวที่จะตรวจจับได้ด้วย JavaScript


แม้ว่าคุณจะไม่ได้มองหาโซลูชัน JS แต่ฉันจะเพิ่มโซลูชันนี้ให้หากมีคนต้องการ วิธีที่ง่ายที่สุดในการจัดการกับ JavaScript คือการเพิ่มคลาสตามความแตกต่างของอัตราส่วน ถ้าอัตราส่วนความกว้างต่อความสูงของกล่องมากกว่ารูปภาพให้เพิ่มคลาส "fillwidth" หรือเพิ่มคลาส "fillheight"


7
จริงๆแล้วมีวิธีแก้ไข: การตั้งค่าขนาดพื้นหลัง CSS3 ให้มี ดูคำตอบของฉัน
Thomas Guillory

คุณพูดถูกทั้งหมด แม้ว่าจะเป็นเวลาหนึ่งปีครึ่งต่อมาแล้วฉันก็แก้ไขโพสต์ของฉัน
Stephan Muller

4
ฉันคิดว่านี่เป็นคำตอบที่ถูกต้องสำหรับคำถามที่ถามนั่นคือ CSS สำหรับแท็ก img คืออะไร สิ่งนี้มีความเกี่ยวข้องเนื่องจากแท็ก img เป็นเนื้อหาตามความหมายรูปภาพที่เป็นพื้นหลังของ div ไม่ใช่ ในขณะที่สถานการณ์บางอย่างทำให้ไม่สามารถใช้งานได้จริง (หากคุณไม่ทราบอัตราส่วนรูปภาพเทียบกับคอนเทนเนอร์) แต่สำหรับบางกรณีก็ถูกต้อง ขอบคุณ
duncanwilcox

173

ขอบคุณ CSS3 มีวิธีแก้ปัญหา!

การแก้ปัญหาคือการวางภาพเป็นbackground-imageจากนั้นตั้งค่าไปbackground-sizecontain

HTML

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

CSS

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

ทดสอบได้ที่นี่: http://www.w3schools.com/cssref/playit.asp?filename=playcss_background-size&preval=contain

เข้ากันได้กับเบราว์เซอร์ล่าสุด: http://caniuse.com/background-img-opts

ในการจัดแนว div ให้อยู่ตรงกลางคุณสามารถใช้รูปแบบนี้:

.bounding-box {
  background-image: url(...);
  background-size: contain;
  position: absolute;
  background-position: center;
  background-repeat: no-repeat;
  height: 100%;
  width: 100%;
}

1
ดีแม้ว่าคำตอบของฉันจะไม่ถูกต้อง (คุณถามเกี่ยวกับ img โดยเฉพาะ) นี่เป็นวิธีแก้ปัญหาที่ยอดเยี่ยมและฉันควรจะคิดอย่างนั้น ปัญหาเดียวคือ IE 8 ยังคงใช้กันอย่างแพร่หลายจนฉันไม่อยากพึ่งพาสิ่งนี้ แต่ก็ยังดี
Stephan Muller

6
ตั้งค่าเป็น "ปก" หากคุณไม่ต้องการให้มี letterboxing: background-size: contain;
arxpoetica

3
มันควรจะตั้งข้อสังเกตว่าคุณสามารถฉีด URL รูปภาพกับ <div class=image style="background-image: url('/images/foo.jpg');"></div>HTML: ควรใช้สไตล์อื่น ๆ ทั้งหมดกับ CSS
Andrey Mikhaylov - lolmaus

14
ฉันจะบอกว่านี่เป็นแนวทางที่แย่มาก การเปลี่ยนเป็นภาพพื้นหลังจะเป็นการลบความหมายของภาพใน HTML
animuson

14
@animuson: มันยังช่วยฉันได้ในขณะที่ฉันใช้ HTML / CSS สำหรับรายงานที่พิมพ์ออกมาและไม่สามารถหลอกลวงเกี่ยวกับความหมายได้ :)
Christian Wattengård

37

นี่คือวิธีแก้ปัญหาแฮ็กที่ฉันค้นพบ:

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

การทำเช่นนี้จะขยายภาพเป็นสิบเท่า แต่ จำกัด ไว้ที่ 10% ของขนาดสุดท้าย - ดังนั้นจึงผูกไว้กับคอนเทนเนอร์

สิ่งbackground-imageนี้จะใช้ได้กับ<video>องค์ประกอบ

ตัวอย่างแบบโต้ตอบ:


1
ฉันชอบวิธีนี้ ไม่เพียง แต่ตอบคำถามได้จริง (ฉันรู้ว่าเป็นความคิด) แต่ยังทำงานได้อย่างสวยงามในเบราว์เซอร์สมัยใหม่ทั้งหมดโดยไม่ต้องใช้ Javascript!
ndm13

2
ฉันชอบที่จะเห็นซอของที่ ในการทดสอบการวาง img ในคอนเทนเนอร์ 400x400 img ก็ถูกตัดเข้ามุม
cyberwombat

3
คำตอบที่ดี! @Yashua คุณต้องเพิ่มtransform-origin: top leftเพื่อหยุดการครอบตัด / Zombie
XwipeoutX

สุกใส ข้อกังวลเดียวของฉันคือการสูญเสียคุณภาพของภาพที่เป็นไปได้ในเบราว์เซอร์ที่เข้ารหัสไม่ดี แต่ในทางทฤษฎีมันควรจะใช้งานได้ดี
Codemonkey

น่าสนใจ แต่ใช้ไม่ได้กับ Chrome ผลลัพธ์ในแถวที่ครอบตัดของรูปภาพ
MattK

23

วันนี้แค่พูดว่า object-fit: contain การสนับสนุนเป็นทุกอย่างยกเว้น IE: http://caniuse.com/#feat=object-fit


3
IE มีส่วนแบ่งตลาดเพียง 16% ในขณะที่เขียนสิ่งนี้ (09/12/2559 10:56 น.) และยังคงลดน้อยลงดังนั้นนี่คือคำตอบที่ดีที่สุดสำหรับฉัน: D
Zhang

8
อย่าแก้ไขคำตอบของผู้อื่นเพื่อแก้ไขสิ่งอื่นนอกเหนือจากการพิมพ์ผิดหรือลิงก์เสีย ฉันจะไม่พูดอะไรที่ดูเด็ก ๆ เช่น "มีโพลีฟิลสำหรับเบราว์เซอร์อึ" ในคำตอบ SO และฉันไม่ชอบที่คำตอบของฉันจะถูกแก้ไขเพื่อให้ดูเหมือนว่าฉันพูดแบบนั้น หากคุณต้องการใช้คำของคุณให้ใส่คำตอบของคุณเอง
Glenn Maynard

ฉันจะบอกว่าไม่ใช่ IE ที่เป็นปัญหา แต่เป็น Edge ตามที่ Caniuse object-fitยังอยู่ระหว่างการพัฒนา
BairDev

นี่ควรเป็นหนึ่งในคำตอบที่ได้รับการโหวตสูงสุดในปี 2017 เป็นต้นไป ... ตามลิงค์ caniuse ด้านบนตอนนี้ 90% ของผู้ใช้ทั่วโลกใช้เบราว์เซอร์ที่รองรับสิ่งนี้
fgblomqvist

ฉันเพิ่งโพสต์คำตอบที่ใช้ได้กับและไม่ใช้object-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;*/
}

5

คุณสามารถทำสิ่งนี้ได้ด้วย CSS บริสุทธิ์และการสนับสนุนเบราว์เซอร์ที่สมบูรณ์ทั้งสำหรับภาพแนวตั้งยาวและแนวนอนในเวลาเดียวกัน

นี่คือตัวอย่างข้อมูลที่ใช้งานได้ใน Chrome, Firefox และ Safari (ทั้งแบบใช้object-fit: scale-downและไม่ใช้):

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>


2

อีกวิธีหนึ่งที่ไม่มีภาพพื้นหลังและไม่จำเป็นต้องใช้คอนเทนเนอร์ (แม้ว่าจะต้องทราบขนาดสูงสุดของกล่องล้อมรอบก็ตาม):

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


หากจำเป็นต้องใช้ภาชนะสามารถตั้งค่าความกว้างสูงสุดและความสูงสูงสุดเป็น 100%:

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

สำหรับสิ่งนี้คุณจะมีสิ่งที่ต้องการ:

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

1

ตัวอย่างนี้เพื่อยืดภาพตามสัดส่วนเพื่อให้พอดีกับหน้าต่างทั้งหมด การปรับแต่งโค้ดที่ถูกต้องด้านบนคือการเพิ่ม$( 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();
});

มีสองเงื่อนไข if อันแรกจะตรวจสอบว่าความสูงของภาพน้อยกว่า div หรือไม่และใช้.fillheightคลาสในขณะที่การตรวจสอบความกว้างและใช้.fillwidthคลาสถัดไป ในทั้งสองกรณีคลาสอื่น ๆ จะถูกลบออกโดยใช้.removeClass()

นี่คือ CSS

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

คุณสามารถแทนที่ได้100vhโดย100%ถ้าคุณต้องการยืดภาพด้วย div ตัวอย่างนี้เพื่อยืดภาพตามสัดส่วนเพื่อให้พอดีกับหน้าต่างทั้งหมด


OP ถามเป็นพิเศษสำหรับแนวทาง css เท่านั้น
Colt McCormack

0

คุณต้องการขยายขนาดขึ้น แต่ไม่ลง?

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

อย่างไรก็ตามสิ่งนี้ไม่ได้ล็อกอัตราส่วนภาพ


5
พยายามทำให้ชัดเจนขึ้นเล็กน้อยกับความคาดหวังของคุณก่อนที่จะลงคะแนนคำตอบของใครบางคน โดยเฉพาะอย่างยิ่งเมื่อพวกเขาตอบคำถามของคุณก่อนที่คุณจะเคลียร์คำถามของคุณด้วยการแก้ไข
Khan

2
นอกจากนี้พยายามสุภาพมากขึ้น ไม่มีใครจะช่วยคุณถ้าคุณพูดแบบนั้น
Misha Reyzlin

@ Artimuz ขอโทษของฉันถ้าฉันแนะนำคุณผิด แต่ดูเหมือนจะไม่ชัดเจนสำหรับฉันที่คุณต้องการคงอัตราส่วนไว้ซึ่งเป็นสาเหตุที่ฉันแสดงความคิดเห็นเกี่ยวกับเรื่องนี้โดยเฉพาะ นอกจากนี้คุณจะสังเกตเห็นว่าฉันวางข้อมูลโค้ดของคุณจากตัวอย่าง ฉันเชื่อว่าการรักษาความสูง: อัตโนมัติ; จะทำให้คุณถ้าคุณระบุความกว้าง
ericosg

0

ฉันใช้ตารางเป็นภาพกลางในกล่อง จะรักษาอัตราส่วนและปรับขนาดภาพในลักษณะที่อยู่ภายในกล่องโดยสิ้นเชิง หากภาพมีขนาดเล็กกว่ากล่องจะแสดงตามที่อยู่ตรงกลาง โค้ดด้านล่างใช้ช่องกว้าง 40px และสูง 40px (ไม่ค่อยแน่ใจว่ามันทำงานได้ดีแค่ไหนเพราะฉันลบมันออกจากโค้ดอื่นที่ซับซ้อนกว่านี้และทำให้มันง่ายขึ้นเล็กน้อย)

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>

0

วิธีที่สะอาดและง่ายที่สุดในการทำสิ่งนี้:

ก่อนอื่น 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;
}

HTML:

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

นี่ควรทำเคล็ดลับ!


0

สิ่งนี้ช่วยฉัน:

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

จากนั้นในองค์ประกอบ (คุณสามารถใช้จาวาสคริปต์หรือคิวรีสื่อเพื่อเพิ่มการตอบสนอง):

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

หวังว่านี่จะช่วยได้!


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

ฉันกำลังแก้ไขคำตอบเพื่ออธิบายโซลูตันของฉันเพิ่มเติมเนื่องจากฉันได้รับการโหวตลง

ด้วยสไตล์ที่กำหนดดังที่แสดงไว้ด้านบนใน css ตอนนี้ html div ต่อไปนี้จะแสดงภาพให้พอดีกับความกว้างเสมอและจะปรับอัตราส่วนความสูงเป็นความกว้าง ดังนั้นภาพจะปรับขนาดให้พอดีกับกรอบล้อมรอบตามที่ถามในคำถาม

<div class="boundingbox"><img src="image.jpg"/></div>

คำตอบนี้ใช้ได้เฉพาะเมื่อกล่องมีความสูงมากกว่าความกว้าง
XwipeoutX
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.