假設(shè)我們有一個(gè)兩欄自適應(yīng)的布局坠非,在主內(nèi)容中應(yīng)用了一個(gè)圖片纲仍,其結(jié)構(gòu)如下:
<div class="figure">
<div class="inner">

<p class="figcaption">Lo, the robot walks</p>
</div>
</div>
這是一個(gè)很常見(jiàn)的結(jié)構(gòu),其效果就是一張圖片初厚,圖片下面有一個(gè)簡(jiǎn)單的文本描述件蚕。在整個(gè)效果中,針對(duì)figure
內(nèi)元素寫(xiě)了一點(diǎn)樣式
//SCSS
.figure {
float: right;
margin: 0.5em 0;
margin-left: 1.9672131%; //12px/610px
width: 45.9016393%; // 280px/610px
.inner {
border: 10px solid hsla(333,50%,60%,.8);
border-radius: 10px;
}
img {
vertical-align: top;
}
p {
background-color: hsla(333,50%,60%,.8);
padding: 10px 10px 0; color: #fff; }
}
從上面的代碼中我們可以想像出我們要的效果,figure占整個(gè)容器.content寬度的"45.9016393%"
也就是"280px/610px"排作。雖然整個(gè)布局是自適應(yīng)布局牵啦,但圖片依舊撐破容器:
這并不是我們想要我效果,我們真正想要達(dá)到的效果應(yīng)該是這樣的纽绍,換句話說(shuō)理想中要的將是下圖的效果:
那接下來(lái)蕾久,我們觀注的就是势似,如何讓我們的效果達(dá)到上圖所示的效果拌夏。
方案一:max-width
在介紹響應(yīng)式設(shè)計(jì)的文章中,為了解決圖片的自適應(yīng)問(wèn)題履因,都會(huì)提到使用max-width
障簿。Richard Rutter設(shè)計(jì)首先提出使用max-width的方案:
img { max-width: 100%; }
在上面的示例基礎(chǔ)上,我們?yōu)閕mg添加max-width值為“100%”:
更重要的是栅迄,在現(xiàn)代瀏覽器中發(fā)展到可以自動(dòng)調(diào)整圖像的比例站故,可以根據(jù)容器的大小縮放或者放大圖像,并且圖像的寬高比保持不變毅舆。
max-width:100%
除了可以應(yīng)用于自適應(yīng)元素容器上之外也可以應(yīng)用于固定元素容器上西篓。而且可以應(yīng)用于視頻和其他富媒體上也具有同等的效果。img, embed, object, video { max-width: 100%; }
不幸的是憋活,max-width屬性在IE7以及其以下版本并無(wú)法支持岂津。
另外一點(diǎn),在一些瀏覽器中僅指定圖片的寬度悦即,可能會(huì)導(dǎo)致瀏覽器重新處理布局吮成,調(diào)整頁(yè)面的時(shí)間周期會(huì)增加兩到三倍,雖然周期不到一毫秒辜梳,但是累積起來(lái)粱甫,尤其是頁(yè)面上有很多個(gè)這樣的元素的時(shí)候,還是或多或少會(huì)影響頁(yè)面的性能作瞄。為了解決這個(gè)問(wèn)題茶宵,可以顯式的指定圖片的height值為auto
img { max-width: 100%; height: auto; }
方案二:background-image
在響應(yīng)式設(shè)計(jì)中實(shí)現(xiàn)圖片自適應(yīng)另一種方案可以采用background-image。因?yàn)樵?a target="_blank" rel="nofollow">CSS3有一個(gè)background-size
屬性可以讓我們的背景圖片適應(yīng)容器大小宗挥。
先簡(jiǎn)單的來(lái)模擬一個(gè)效果乌庶,基于上例的基礎(chǔ)上,我們將模板結(jié)構(gòu)做一下調(diào)整:
<div class="figure"> <div class="inner"> <div class="image-wrapper"></div> <p class="figcaption">Lo, the robot walks</p> </div> </div>
將圖片變成背景圖片應(yīng)用于image-wrapper容器之上属韧。
//SCSS
.figure {
float: right;
margin: 0.5em 0;
margin-left: 1.9672131%; //12px/610px
width: 45.9016393%; // 280px/610
.inner {
border: 10px solid hsla(333,50%,60%,.8);
border-radius: 10px;
}
.image-wrapper {
width: 100%;
background: url("http://w3cplus-cdn2.u.qiniudn.com/sites/default/files/blogs/2014/1401/flexible-image.jpg") no-repeat center;
min-height: 100px;
background-size: cover;
}
p {
background-color: hsla(333,50%,60%,.8);
padding: 10px 10px 0;
color: #fff;
}
}
可以清楚的看到安拟,在<code>.image-wrapper</code>應(yīng)用了背景圖片,并且配合了<code>background-size:cover</code>一起使用:
<code>
.image-wrapper {
width: 100%;
background: url("http://w3cplus-cdn2.u.qiniudn.com/sites/default/files/blogs/2014/1401/flexible-image.jpg") no-repeat center;
min-height: 100px;
background-size: cover;
}
</code>
不過(guò)這里讓你為難的是,在<code>.image-wrapper</code>容器中沒(méi)有任何內(nèi)容宵喂,以至于無(wú)法撐開(kāi)容器的高度糠赦,因此想正常的顯示出圖片,那必須給容器指一個(gè)準(zhǔn)確的高度或一個(gè)最小高度,言外之意拙泽,我們寬度可以自適應(yīng)淌山,但比例不會(huì)根據(jù)圖片的寬高比例來(lái)定,另外圖片會(huì)進(jìn)行截取顾瞻,如示例所示:
<p>很顯然泼疑,這樣的效果不理想,不是我們所需要的效果荷荤。那有什么方法可以讓背景圖片根據(jù)自身的比例來(lái)自適應(yīng)呢退渗?</p>
<p>在響應(yīng)式設(shè)計(jì)中,布局可以根據(jù)設(shè)備調(diào)整寬度蕴纳。就算是用百分比調(diào)整寬度会油,也會(huì)自動(dòng)按比例調(diào)整元素的高度。換句話說(shuō)古毛,其寬度比例保持不變來(lái)調(diào)整大小翻翩。如果我們要使背景圖片達(dá)到同等的效果,我們就必須得知道如何保持任何HTML元素的縱橫比例稻薇。</p>
<p>針對(duì)這個(gè)問(wèn)題嫂冻,Rolf Timmermans 寫(xiě)了一篇文章<a >Responsive background images with fixed or fluid aspect ratios</a>,文章中介紹了如何解決背景圖像的固定和流體的縱橫比例。接下來(lái)我們一起來(lái)看看Rolf Timmermans是如何實(shí)現(xiàn)的塞椎。</p>
<h3>
固定縱橫比例</h3>
<p>在保持背景圖片的縱橫比例桨仿,關(guān)鍵之處是是讓背景圖片垂直居中。而其中主要是基于寬度的百分比來(lái)設(shè)置內(nèi)距<code>padding</code>的百分比值忱屑。這種技術(shù)早前在<a >創(chuàng)建視頻縱橫比例</a>一文中有介紹蹬敲,而這種技術(shù)也適用于其他的任何元素。</p>
<p>假設(shè)我們有一張700像素寬和467像素高的圖像莺戒。當(dāng)寬度改變時(shí)伴嗡,我們需要維護(hù)其縱橫向比例是“16:9”。下面有一個(gè)示例从铲,我們使用像素為單位瘪校,當(dāng)然也可以使用<code>em</code>為單位,但我們的結(jié)構(gòu)和前面示例一樣:</p>
<pre>
<code><div class="figure">
<div class="inner">
<div class="image-wrapper"></div>
<p class="figcaption">Lo, the robot walks</p>
</div>
</div>
</code></pre>
<p>一般情況之下名段,我們知道圖片的尺寸大小阱扬,根據(jù)縱橫比例,我們可以通過(guò)下面的公式計(jì)算出內(nèi)距<code>padding-top</code>或<code>padding-bottom</code>的百分比值:</p>
<pre>
<code>padding-top或padding-bottom = (背景圖片高度 / 背景圖片寬度) * 100%
</code></pre>
<p>根據(jù)這個(gè)公式伸辟,可以輕松計(jì)算出:</p>
<pre>
<code>padding-top(或padding-bottom) = 467 / 700 = 0.667142857 = 66.7142857%
</code></pre>
<p>如此一來(lái)麻惶,我們可以將前面的示例調(diào)整為:</p>
<code>//SCSS
.figure {
margin: .5em;
//背景圖像寬度必須寬度為700px
max-width: 700px; //圖片的寬度
.inner {
border: 10px solid hsla(333,50%,60%,.8);
border-radius: 10px;
}
.image-wrapper {
background: url("http://w3cplus-cdn2.u.qiniudn.com/sites/default/files/blogs/2014/1401/flexible-image.jpg") no-repeat center;
background-size: cover;
padding-top:66.7142857%; // 467px / 700px = 0.667142857
}
p {
background-color: hsla(333,50%,60%,.8);
padding: 10px 10px 0;
color: #fff;
}
}
</code></pre>
<p>效果如下:</p>
<h3>
自適應(yīng)縱橫比例</h3>
<p>在固定縱橫比例的基礎(chǔ)之上,做進(jìn)一步的調(diào)整信夫。假設(shè)我們?cè)趯捚恋腜C上顯示大的圖片窃蹋,而在移動(dòng)設(shè)備上卡啰,我們不想使用相同的縱橫比或圖像變得太小。當(dāng)然我們也不想使用完全相同的高度或讓圖像變得太高警没。我們更希望當(dāng)寬度變小時(shí)匈辱,其高度也變得更小。而我們也把這種稱(chēng)為流體縱橫比例杀迹。</p>
<p>這種效果我們可以給元素設(shè)置一個(gè)高度亡脸,來(lái)減少<code>padding-top</code>或者<code>padding-bottom</code>的百分比值。假設(shè)我們的大圖尺寸是700像素寬度和267像素高树酪,而我們決定顯示的圖片尺寸是在300像素寬度和167像素的高度∏衬耄現(xiàn)在我們需要計(jì)算高度<code>height</code>和內(nèi)距<code>padding-top</code>或<code>padding-bottom</code>的值:</p>
<p>上圖顯示了兩個(gè)維度之間的關(guān)系。斜線的坡度對(duì)應(yīng)于內(nèi)距<code>padding-top</code>或<code>padding-bottom</code>的屬性值嗅回。開(kāi)始高度的值代表元素的高度<code>height</code>的屬性值及穗。</p>
我們可以根據(jù)上圖所示的公式計(jì)算出背景圖像縱橫比例∶嘣兀基于固定縱橫比例的示例之上,將上面的示例修改成流體縱橫比例:
<code>.figure {
margin: .5em;
//背景圖像的寬度為700px
max-width: 700px;
.inner {
border: 10px solid hsla(333,50%,60%,.8);
border-radius: 10px;
}
.image-wrapper {
background: url("http://w3cplus-cdn2.u.qiniudn.com/sites/default/files/blogs/2014/1401/flexible-image.jpg") no-repeat center;
background-size: cover;
height: 92px;
padding-top:25%;
}
p {
background-color: hsla(333,50%,60%,.8);
padding: 10px 10px 0;
color: #fff;
}
}
</code>
<p>效果如下所示:</p>
<p><strong>注:由于示例圖片尺寸比例不夠標(biāo)準(zhǔn)苛白,此處想要表達(dá)的意思是:假設(shè)原圖的比例是4:1(比如背景圖片尺寸是800px寬娃豹,200px高);自適應(yīng)后比例為2:1购裙,(背景圖片尺寸變?yōu)?00px的寬和150px的高)懂版。換句話說(shuō)就是從4:1比例的800<em>200的圖片變成比例為2:1的300</em>150的圖片。</strong></p>
<p><strong>特別聲明:</strong>以上方法以及思咱來(lái)自于Rolf Timmermans的<a >Responsive background images with fixed or fluid aspect ratios</a>一文躏率。</p>
<p>上面兩種方案主要是根據(jù)背景圖片的縱橫比例來(lái)實(shí)現(xiàn)圖像的自適應(yīng)效果躯畴。但在<a >Necolas</a>在<a >Flexible CSS cover images</a>一文中提供另一種以縱橫比實(shí)現(xiàn)圖像自適應(yīng)的效果。</p>
<p>他的特征同樣是依靠覆蓋背景圖像的縱橫比例來(lái)實(shí)現(xiàn)薇芝,假設(shè)我們的比例為:</p>
<p>覆蓋背景圖像的縱橫比例必須得滿足以下幾個(gè)條件:</p>
<ul><li>呈現(xiàn)一個(gè)固定的縱橫比例蓬抄,除非特定的最大尺寸超過(guò)圖像寬度</li>
<li>支持不同的縱橫比例</li>
<li>支持最大高度<code>max-height</code>和最大寬度<code>max-width</code></li>
<li>支持不同的背景圖像</li>
<li>背景圖像填充整個(gè)容器</li>
<li>背景圖像居中顯示</li>
</ul><p>先來(lái)看一個(gè)簡(jiǎn)單的模板:</p>
<pre>
<code><div class="CoverImage FlexEmbed FlexEmbed--3by1"></div>
</code></pre>
<p>對(duì)應(yīng)的樣式代碼:</p>
<code>//SCSS
.CoverImage {
border: 5px solid green;
margin: .5em auto;
background: url("http://w3cplus-cdn2.u.qiniudn.com/sites/default/files/blogs/2014/1401/flexible-image.jpg") no-repeat center;
background-size: cover;
max-height: 700px;
max-width: 467px;
}
.FlexEmbed {
display: block;
overflow: hidden;
position: relative;
&:before {
content: "";
display: block;
width: 100%;
}
}
.FlexEmbed--3by1:before {
padding-bottom: 33.33333%;
}
.FlexEmbed--2by1:before {
padding-bottom: 50%;
}
.FlexEmbed--16by9:before {
padding-bottom: 56.25%;
}
.FlexEmbed--4by3:before {
padding-bottom: 75%;
}
</code>
<p>其效果如下:</p>
<p>使用背景圖像的方案存在一個(gè)問(wèn)題,不管是固定縱橫比例還是流體縱橫比例夯到,我們都離不開(kāi)<code>background-size</code>屬性嚷缭,而此值是CSS3的一個(gè)屬性,僅有現(xiàn)代瀏覽器支持耍贾。如果要兼容低版本的IE還需要另尋他法阅爽。比如說(shuō)<a >backgroundSize.js</a>、<a >BACKSTRETCH</a>荐开、<a >jQuery Easy Background Resize</a>等插件付翁。<a >Michael Bester</a>在<a >The Flexible Scalable Background Image, Redux</a>一文中也做過(guò)這方面的介紹。</p>
<h2>
方案三:Object-fit</h2>
<p><a >Object-fit</a>是CSS3的一個(gè)新屬性晃听,到目前為止僅在Chrome32+版本上可以正常運(yùn)行百侧。這個(gè)屬性可以說(shuō)就是為自適圖片尺寸而生着帽,特別適合于響應(yīng)式設(shè)計(jì)中圖片以及其他富媒體的自適尺寸的處理。</p>
<p>使用<code>Object-fit</code>屬性有一個(gè)受限條件移层,需要在樣式中顯示的設(shè)置圖片的尺寸仍翰。然后通過(guò)其屬性值<code>fill</code>、<code>cover</code>或<code>contain</code>值來(lái)控制圖像顯錄的縱橫比例观话。在此并不建議使用予借,不過(guò)當(dāng)作興趣愛(ài)好,可以深入了解他频蛔。如果你對(duì)此屬性感興趣灵迫,可以閱讀《<a >CSS3 Object-fit和Object-position</a>》一文,文中詳細(xì)介紹了<code>object-fit</code>屬性的具體使用晦溪。</p>
<h2>
其他方案</h2>
<p>除了上述的幾種方案之外瀑粥,其實(shí)還有其他的一些解決方案,比如<a >@張?chǎng)涡?lt;/a>在其博客《<a >熱門(mén):響應(yīng)圖片(Responsive Images)技術(shù)簡(jiǎn)介</a>》一文中就介紹了如何使用“Cookie+Server”三圆、“使用<code>noscript</code>標(biāo)簽創(chuàng)建”等其他方法狞换。<a >Andy Shora</a>在《<a >Sizing Fluid Image Containers with a Little CSS Padding Hack</a>》還介紹了一種老方案——<strong>內(nèi)距和絕對(duì)定位實(shí)現(xiàn)圖片自適應(yīng)</strong>。當(dāng)然除了這些還有其他的舟肉。<a >Sherri Alexander</a>特意為解決響應(yīng)式設(shè)計(jì)的圖片問(wèn)題修噪,在《<a >Choosing A Responsive Image Solution</a>》一文中搜集了很多個(gè)JavaScript解決方案。感興趣的同學(xué)路媚,可以仔細(xì)研究研究黄琼。</p>
<h2>
擴(kuò)展閱讀</h2>
<ul><li><a >Flexible CSS cover images</a></li>
<li><a >Fluid Images</a></li>
<li><a >CSS Fluid Image Techniques for Responsive Site Design</a></li>
<li><a >FLUID IMAGES</a></li>
<li><a >Responsive background images with fixed or fluid aspect ratios</a></li>
<li><a >How To Create Flexible Images And Media In CSS Layouts</a></li>
<li><a >Different ways of making images flexible in responsive web design</a></li>
<li><a >Adaptive Images for Responsive Designs</a></li>
<li><a >Responsive Images: How they Almost Worked and What We Need</a></li>
<li><a >熱門(mén):響應(yīng)圖片(Responsive Images)技術(shù)簡(jiǎn)介</a></li>
<li><a >Overflow Image with vertical centering for Responsive Web Design</a></li>
<li><a >Sizing Fluid Image Containers with a Little CSS Padding Hack</a></li>
<li><a >The Flexible Scalable Background Image, Redux</a></li>
<li><a >Choosing A Responsive Image Solution</a></li>
</ul><h2>
總結(jié)</h2>
<p>上面介紹了使用不同方案來(lái)解決圖片自適應(yīng)在Web頁(yè)面設(shè)計(jì)中的問(wèn)題。不管哪種方案整慎,都有自己的優(yōu)勢(shì)與不足脏款。拋開(kāi)JavaScript的解決方案,不管是<code>max-width</code>裤园、<code>background-image</code>還是<code>object-fit</code>都避免不了瀏覽器的兼容性問(wèn)題撤师,特別是<code>object-fit</code>尤為突出。在實(shí)際應(yīng)用中比然,個(gè)人更趨向于方案二丈氓,因?yàn)槠淇梢园凑請(qǐng)D片縱橫向比例顯示,不過(guò)這種方案比較麻煩的是强法,需要使用背景圖片万俗。</p>
<p>當(dāng)然,大家可以根據(jù)自己的項(xiàng)目需求去考慮使用什么方案解決問(wèn)題饮怯,在這里只是自己一點(diǎn)總結(jié)闰歪。如果您對(duì)自適應(yīng)圖片的處理有更好的解決經(jīng)驗(yàn),歡迎一起分享蓖墅。</p>
<p>如需轉(zhuǎn)載库倘,煩請(qǐng)注明出處:<a >http://www.w3cplus.com/css/flexible-images.html</a></p>