ऊंचाई बदलते समय छवि पहलू अनुपात बनाए रखें


114

CSS फ्लेक्स बॉक्स मॉडल का उपयोग करके, मैं एक छवि को इसके पहलू अनुपात को बनाए रखने के लिए कैसे मजबूर कर सकता हूं?

जेएस फिडल: http://jsfiddle.net/xLc2Le0k/2/

ध्यान दें कि कंटेनर की चौड़ाई को भरने के लिए चित्र खिंचाव या सिकुड़ते हैं। यह ठीक है, लेकिन क्या हम छवि अनुपात को बनाए रखने के लिए इसे बढ़ा सकते हैं या ऊंचाई को कम कर सकते हैं?

एचटीएमएल

<div class="slider">
    <img src="http://www.placebacon.net/400/300" alt="Bacn">
    <img src="http://www.placebacon.net/400/300" alt="Bacn">
    <img src="http://www.placebacon.net/400/300" alt="Bacn">
    <img src="http://www.placebacon.net/400/300" alt="Bacn">
</div>

सीएसएस

.slider {
    display: flex;
}
.slider img {
    margin: 0 5px;
}

1
जहाँ तक मुझे पता है, सबसे अच्छा समाधान <div>background-image: url(...);background-size:contain; background-repeat:no-repeat
Blazemonger

1
यहाँ कुछ दिलचस्प लीड्स हैं, लेकिन क्या होगा जब इमेज पहले से ही समान अनुपात में नहीं हैं? जोड़ना और 'अतिरिक्त' div, आखिरी चीज है जिसके बारे में हमें चिंता करने की ज़रूरत है। इस तरह के बजाय एक टेस्ट केस का उपयोग क्यों नहीं: jsfiddle.net/sheriffderek/999Lg9qv
sheriffderek

जवाबों:


68

Img टैग के लिए यदि आप एक पक्ष को परिभाषित करते हैं तो पहलू अनुपात रखने के लिए दूसरे पक्ष का आकार बदल दिया जाता है और डिफ़ॉल्ट रूप से उनके मूल आकार में विस्तार होता है।

इस तथ्य का उपयोग करते हुए यदि आप प्रत्येक ईएमजी टैग को div टैग में लपेटते हैं और इसकी चौड़ाई 100% पैरेंट डिव में सेट करते हैं तो ऊंचाई पहलू अनुपात के अनुसार होगी जैसा आप चाहते थे।

http://jsfiddle.net/0o5tpbxg/

* {
    margin: 0;
    padding: 0;
}
.slider {
    display: flex;
}
.slider .slide img {
    width: 100%;
}

2
मुझे पता है कि दो उत्तर हैं जो divs का उपयोग करने का सुझाव देते हैं, लेकिन मैं इस उत्तर को सही चिह्नित कर रहा हूं क्योंकि यह बताता है कि छवि की ऊंचाइयां मेरी अपेक्षा से भिन्न क्यों हैं। वास्तव में, यह सामान्य और सही व्यवहार है, और "फिक्स्ड" होने की संभावना नहीं है, क्योंकि यह बग नहीं है।
कोडरमे

18
लेकिन यह जवाब फ्लेक्सबॉक्स के बारे में कुछ भी बात नहीं करता है, क्योंकि फ्लेक्सबॉक्स कंटेनर के भीतर छवियां अलग तरह से व्यवहार करती हैं। एक पक्ष की स्थापना दूसरे के अनुपात में नहीं होगी। उन्हें नॉन फ्लेक्सबॉक्स कंटेनर में लपेटने से मदद मिलती है लेकिन इससे अनावश्यक मार्कअप जुड़ जाता है जिससे अर्थक्षमता कम हो जाती है।
रॉबर्ट कोरिटनिक

3
ऐसा नहीं लगता है कि आपको यह काम करने के लिए एक रैपिंग डिव की आवश्यकता है: jsfiddle.net/xLc2Le0k/120
रिक स्ट्राल

4
लेकिन, इससे क्या? jsfiddle.net/xLc2Le0k/15 मुझे लगता है कि यह समाधान एक अस्थायी है जो केवल काम करता है क्योंकि चित्र सभी समान अनुपात में हैं। साइड नोट: पोजिशनिंग के लिए / विशेष रूप से उत्तरदायी छवियों से निपटने के दौरान एक छवि को किसी div में रखकर खो दिया गया कोई भी 'शब्दार्थ' नहीं है।
शेरिफडेरेक

1
गंभीरता से सबसे साफ समाधान और यह तस्वीर के साथ काम करता है!
shanonabike

64

एक फ्लेक्स पैरेंट के अंदर किसी भी एक्सिस में स्ट्रेचिंग से इमेज रखने के लिए मुझे कुछ सॉल्यूशन मिले हैं।

आप छवि पर ऑब्जेक्ट-फिट का उपयोग करने की कोशिश कर सकते हैं, जैसे

object-fit: contain;

http://jsfiddle.net/ykw3sfjd/

या आप फ्लेक्स-विशिष्ट नियम जोड़ सकते हैं जो कुछ मामलों में बेहतर काम कर सकते हैं।

align-self: center;
flex: 0 0 auto;

4
ऑब्जेक्ट-फिट एक अच्छा समाधान हो सकता है क्या यह IE में समर्थन और एज 14 तक भी गायब नहीं था
डेनियल


मैं खुद उस कमबैक का उपयोग कर रहा हूं, बहुत अच्छी तरह से काम करता है।
मत्ती बलाम

1
@daniels Edge अब विकास में ऑब्जेक्ट-फिट है: developer.microsoft.com/en-us/microsoft-edge/platform/status/…
AMDG 15'17

1
object-fit: contain;मेरे लिए चाल चली, जब मुझे केवल क्रोम में समस्या थी, एफएफ ठीक था।
बेंजामिन पीटर

53

एक युक्त div जोड़ने की जरूरत नहीं है।

सीएसएस "संरेखित-आइटम" संपत्ति के लिए डिफ़ॉल्ट "खिंचाव" है जो कि आपकी छवियों को इसकी पूरी मूल ऊंचाई तक ले जाने का कारण है। "फ्लेक्स-स्टार्ट" के लिए सीएसएस "संरेखित-आइटम" संपत्ति सेट करना आपके मुद्दे को ठीक करता है।

.slider {
    display: flex;
    align-items: flex-start;  /* ADD THIS! */
}

3
आह ... वास्तव में समर्थित तरीके से काम करने के लिए धन्यवाद। मैं उस जवाब को पढ़ रहा था जब तक कि एक और विश्वास नहीं कर सकता था कि हम सब गंदे हैक्स थे ..
Félix Gagnon-Grenier

35

आंतरिक आयामों के साथ अधिकांश छवियां , जो एक प्राकृतिक आकार है, एक jpegछवि की तरह । यदि निर्दिष्ट आकार चौड़ाई और ऊंचाई दोनों में से एक को परिभाषित करता है, तो लापता मूल्य को आंतरिक अनुपात का उपयोग करके निर्धारित किया जाता है ... - MDN देखें ।

लेकिन यह उम्मीद के मुताबिक काम नहीं करता है , जब तक कि वर्तमान लचीले बॉक्स लेआउट मॉड्यूल स्तर 1 के साथ प्रत्यक्ष फ्लेक्स आइटम के रूप में सेट की जा रही छवियां , जहां तक ​​मुझे पता है।

इन चर्चाओं और बग रिपोर्ट से संबंधित देखें:

  • फ्लेक्सबग्स # 14 - क्रोम / फ्लेक्सबॉक्स आंतरिक आकार सही ढंग से लागू नहीं किया गया।
  • फ़ायरफ़ॉक्स बग 972595 - फ्लेक्स कंटेनरों को फ्लेक्स आइटम के आंतरिक चौड़ाई की गणना के लिए "चौड़ाई" के बजाय "फ्लेक्स-बेस" का उपयोग करना चाहिए
  • क्रोमियम इश्यू 249112 - फ्लेक्सबॉक्स में, मुख्य आकार की गणना को सूचित करने के लिए आंतरिक पहलू अनुपात की अनुमति दें।

वर्कअराउंड के रूप में, आप प्रत्येक <img>को एक <div>या एक के साथ लपेट सकते हैं <span>, या तो।

jsFiddle

.slider {
  display: flex;
}

.slider>div {
  min-width: 0; /* why? see below. */
}

.slider>div>img {
  max-width: 100%;
  height: auto;
}
<div class="slider">
  <div><img src="https://picsum.photos/400/300?image=0" /></div>
  <div><img src="https://picsum.photos/400/300?image=1" /></div>
  <div><img src="https://picsum.photos/400/300?image=2" /></div>
  <div><img src="https://picsum.photos/400/300?image=3" /></div>
</div>

4.5 फ्लेक्स आइटमों का न्यूनतम आकार

फ्लेक्स आइटम के लिए अधिक उचित डिफ़ॉल्ट न्यूनतम आकार प्रदान करने के लिए , यह विनिर्देश सीएसएस 2.1 में परिभाषित न्यूनतम चौड़ाई और न्यूनतम ऊंचाई गुणों के प्रारंभिक मूल्य के रूप में एक नया ऑटो मूल्य पेश करता है ।


वैकल्पिक रूप से, आप tableइसके बजाय CSS लेआउट का उपयोग कर सकते हैं , जिसके परिणामस्वरूप आपको समान परिणाम मिलेंगे flexbox, यह IE8 के लिए और भी ब्राउज़रों पर काम करेगा।

jsFiddle

.slider {
  display: table;
  width: 100%;
  table-layout: fixed;
  border-collapse: collapse;
}

.slider>div {
  display: table-cell;
  vertical-align: top;
}

.slider>div>img {
  max-width: 100%;
  height: auto;
}
<div class="slider">
  <div><img src="https://picsum.photos/400/300?image=0" /></div>
  <div><img src="https://picsum.photos/400/300?image=1" /></div>
  <div><img src="https://picsum.photos/400/300?image=2" /></div>
  <div><img src="https://picsum.photos/400/300?image=3" /></div>
</div>


पहले स्निपेट को .slider > div{min-width:0}समर्थन करने वाले नए ब्राउज़रों की आवश्यकता है min-width: auto
ओरोल

3
फ्लेक्सबॉक्स कल्पना ने ( और पहले यह था ) के autoलिए डिफ़ॉल्ट मान के रूप में एक नया मूल्य पेश किया । क्रोम इसे अभी तक लागू नहीं करता है, इसलिए आपका पहला स्निपेट काम करता है। लेकिन नए ब्राउज़रों को छवियों की डिफ़ॉल्ट चौड़ाई की तुलना में फ्लेक्स आइटम को छोटा करने की अनुमति देने के लिए इसकी आवश्यकता होती है। min-widthmin-height0
ओरियल

2
+1 यह उत्तर स्वीकार किया जाना चाहिए क्योंकि यह फ्लेक्सबॉक्स मॉडल में छवियों के बारे में बात करता है जो इस मामले में मूल समस्या है ...
रॉबर्ट कोरिटनिक

यदि आपका लेआउट विभिन्न विराम बिंदुओं पर परिवर्तित नहीं होता है, तो तालिका बहुत बढ़िया है, लेकिन इन दिनों इसकी संभावना नहीं है।
sheriffderek

1
जब सभी समान अनुपात में चित्र नहीं होते हैं तो क्या होता है? jsfiddle.net/sheriffderek/5u7y21we
sheriffderek

6

मैं हाल ही में फ्लेक्सबॉक्स के आसपास खेल रहा हूं और मैं इसके लिए प्रयोग और निम्नलिखित तर्क के माध्यम से समाधान के लिए आया हूं। हालांकि, वास्तव में मुझे यकीन नहीं है कि अगर वास्तव में ऐसा होता है।

यदि वास्तविक चौड़ाई फ्लेक्स सिस्टम से प्रभावित होती है। इसलिए तत्वों की चौड़ाई के बाद अधिकतम चौड़ाई में वे हिट करते हैं, वे css में सेट की गई अतिरिक्त चौड़ाई को नजरअंदाज कर देते हैं। फिर चौड़ाई को 100% पर सेट करना सुरक्षित है।

चूंकि img टैग की ऊंचाई छवि से ली गई है, इसलिए ऊंचाई 0% तक सेट करना कुछ कर सकता है। (यह वह जगह है जहां मैं स्पष्ट नहीं हूं कि क्या है ... लेकिन यह मेरे लिए समझ में आया कि इसे ठीक करना चाहिए)

डेमो

(पहले इसे यहाँ देखा याद है!)

.slider {
    display: flex;
}
.slider img {
    height: 0%;
    width: 100%;
    margin: 0 5px;
}

अभी तक केवल क्रोम में काम करता है


दिलचस्प है, लेकिन यह एक बग लगता है। युक्ति के अनुसार , " प्रतिशत की गणना उत्पन्न बॉक्स की ऊंचाई के संबंध में की जाती है। यदि ब्लॉक की ऊंचाई स्पष्ट रूप से निर्दिष्ट नहीं है (यानी, यह सामग्री की ऊँचाई पर निर्भर करता है), और यह तत्व पूरी तरह से तैनात नहीं है मान की गणना करता हैauto "। यही फ़ायरफ़ॉक्स पर होता है।
ओरोल

jsfiddle.net/xLc2Le0k/8 ff और क्रोम में अंतर समझाएं। इसके लिए
मुहम्मद उमर

चौड़ाई एफएफ में कर रही है लगता है कि क्रोम में ऊंचाई क्या कर रही है।
मुहम्मद उमर

यह दिलचस्प है, लेकिन मुझे डर है कि एक्स-ब्राउज़र-केवल समाधान वास्तव में समाधान नहीं हैं। आपकी टिप्पणी की गई फ़िडल, यहाँ: jsfiddle.net/xLc2Le0k/8 बिल्कुल आकर्षक है , हालाँकि, FF में। ऐसा प्रतीत होता है कि FF छवि की ऊंचाई को "आनुपातिक" बना रही है यदि यह वास्तव में 100% थी। दूसरे शब्दों में, img कंटेनर के डिस्प्ले के बारे में "नहीं जानता": फ्लेक्स। यह बताता है कि, FF में, यदि आप img की चौड़ाई को 100% पर सेट करते हैं, तो यदि आप ऑटो को चौड़ाई सेट करते हैं, तो छवि इससे अधिक लंबी है।
कोडरएम

यह थोड़े करीब है ... लेकिन केवल क्रोम में काम करता है: jsfiddle.net/sheriffderek/xLc2Le0k/270
sheriffderek

2

यह व्यवहार अपेक्षित है। फ्लेक्स कंटेनर होगा खिंचाव डिफ़ॉल्ट रूप से अपने सभी बच्चों को। छवि का कोई अपवाद नहीं है। (यानी, माता-पिता के पास align-items: stretchसंपत्ति होगी )

पहलू अनुपात रखने के लिए हमारे पास दो समाधान हैं:

  1. या तो डिफ़ॉल्ट align-items: stretchसंपत्ति को align-items: flex-startया align-self: centerआदि से बदलें , http://jsfiddle.net/e394Lqnt/3/

या

  1. संरेखित गुण को केवल बच्चे के लिए सेट करें: जैसे, align-self: centerया align-self: flex-startआदि http://jsfiddle.net/e394Lqnt/2/

-1

वास्तव में मुझे पता चला कि छवि के कंटेनर को छवि के अनुपात को बनाए रखने के लिए ऊंचाई की आवश्यकता होती है। उदाहरण के लिए>

.container{display:flex; height:100%;} img{width:100%;height:auto;}

तब आपके html में आपका कंटेनर टैग इमेज को लपेट देगा

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

IE और अन्य ब्राउज़रों के लिए यह काम करता है


-1

मेरा बस यही मुद्दा था। अपने तत्वों को केंद्रित करने के लिए फ्लेक्स संरेखित का उपयोग करें। आपको align-items: centerइसके बजाय उपयोग करने की आवश्यकता है align-content: center। यह पहलू अनुपात को बनाए रखेगा, जबकि संरेखित-सामग्री पहलू अनुपात को नहीं रखेगी।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.