標籤:

不用vh,vw,vmin,vmax,rem,em單位,不用js,如何獲得一個鎖定高寬比的響應式盒子?

這是一個實際應用場景中碰到的問題。不能用js;因為外層容器和設備高度、寬度不線性相關,所以vh、vw也不能用;無法控制html根字體,所以rem也不能用;em能鎖定高寬比但是不能根據外層容器的寬度用css設置出來,所以em也不能用。目前唯一想到的方法是在盒子里放一張圖片,圖片設置width:100%,height:auto,這樣把盒子撐起來,外層容器寬度怎麼變化,盒子都會維持圖片的高寬比。求問還有沒有更好更簡單的方法


謝邀!

下面截取部分文檔放這,看看是否有幫助。

----------------- 此處分割線 ---------------

固定縱橫比例

在保持背景圖片的縱橫比例,關鍵之處是是讓背景圖片垂直居中。而其中主要是基於寬度的百分比來設置內距padding的百分比值。這種技術早前在創建視頻縱橫比例一文中有介紹,而這種技術也適用於其他的任何元素。

假設我們有一張700像素寬和467像素高的圖像。當寬度改變時,我們需要維護其縱橫向比例是「16:9」。下面有一個示例,我們使用像素為單位,當然也可以使用em為單位,但我們的結構和前面示例一樣:

&
&
&& &

Lo, the robot walks& & &

一般情況之下,我們知道圖片的尺寸大小,根據縱橫比例,我們可以通過下面的公式計算出內距padding-top或padding-bottom的百分比值:

padding-top或padding-bottom = (背景圖片高度 / 背景圖片寬度) * 100%

根據這個公式,可以輕鬆計算出:

padding-top(或padding-bottom) = 467 / 700 = 0.667142857 = 66.7142857%

如此一來,我們可以將前面的示例調整為:

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

效果如下:

DEMO地址: A Pen by Airen

自適應縱橫比例

在固定縱橫比例的基礎之上,做進一步的調整。假設我們在寬屏的PC上顯示大的圖片,而在移動設備上,我們不想使用相同的縱橫比或圖像變得太小。當然我們也不想使用完全相同的高度或讓圖像變得太高。我們更希望當寬度變小時,其高度也變得更小。而我們也把這種稱為流體縱橫比例。

這種效果我們可以給元素設置一個高度,來減少padding-top或者padding-bottom的百分比值。假設我們的大圖尺寸是700像素寬度和267像素高,而我們決定顯示的圖片尺寸是在300像素寬度和167像素的高度。現在我們需要計算高度height和內距padding-top或padding-bottom的值:

上圖顯示了兩個維度之間的關係。斜線的坡度對應於內距padding-top或padding-bottom的屬性值。開始高度的值代表元素的高度height的屬性值。

我們可以根據上圖所示的公式計算出背景圖像縱橫比例。基於固定縱橫比例的示例之上,將上面的示例修改成流體縱橫比例:

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

效果如下所示:

DEMO: http://codepen.io/airen/pen/EBwfD

註:由於示例圖片尺寸比例不夠標準,此處想要表達的意思是:假設原圖的比例是4:1(比如背景圖片尺寸是800px寬,200px高);自適應後比例為2:1,(背景圖片尺寸變為300px的寬和150px的高)。換句話說就是從4:1比例的800200的圖片變成比例為2:1的300150的圖片。

特別聲明:以上方法以及思咱來自於Rolf Timmermans的Responsive background images with fixed or fluid aspect ratios一文。

上面兩種方案主要是根據背景圖片的縱橫比例來實現圖像的自適應效果。但在Necolas在Flexible CSS cover images一文中提供另一種以縱橫比實現圖像自適應的效果。

他的特徵同樣是依靠覆蓋背景圖像的縱橫比例來實現,假設我們的比例為:

覆蓋背景圖像的縱橫比例必須得滿足以下幾個條件:

  • 呈現一個固定的縱橫比例,除非特定的最大尺寸超過圖像寬度
  • 支持不同的縱橫比例
  • 支持最大高度max-height和最大寬度max-width
  • 支持不同的背景圖像
  • 背景圖像填充整個容器
  • 背景圖像居中顯示

先來看一個簡單的模板:

&&

對應的樣式代碼:

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

其效果如下:

DEMO: A Pen by Airen

使用背景圖像的方案存在一個問題,不管是固定縱橫比例還是流體縱橫比例,我們都離不開background-size屬性,而此值是CSS3的一個屬性,僅有現代瀏覽器支持。如果要兼容低版本的IE還需要另尋他法。比如說backgroundSize.js、BACKSTRETCH、jQuery Easy Background Resize等插件。Michael Bester在The Flexible Scalable Background Image, Redux一文中也做過這方面的介紹。

其他方案

除了上述的幾種方案之外,其實還有其他的一些解決方案,比如@張鑫旭在其博客《熱門:響應圖片(Responsive Images)技術簡介》一文中就介紹了如何使用「Cookie+Server」、「使用noscript標籤創建」等其他方法。Andy Shora在《Sizing Fluid Image Containers with a Little CSS Padding Hack》還介紹了一種老方案——內距和絕對定位實現圖片自適應。當然除了這些還有其他的。Sherri Alexander特意為解決響應式設計的圖片問題,在《Choosing A Responsive Image Solution》一文中搜集了很多個JavaScript解決方案。感興趣的同學,可以仔細研究研究。

--------------------- 截取內容到此結束 -------------------

如果有幫助,可以看看原文:Flexible Images_Flexible Image, Responsive 教程_w3cplus


給個提示:padding-top/bottom 的百分比值是根據寬度計算的。


一直用這個自己寫的Sass mixin:

@mixin heightRelativeToWidth($percentage: 100%, $pos: "after") {
:#{$pos} {
content: " ";
display: block;
height: 0;
padding-bottom: $percentage;
@content;
}
}

要用的時候就include一下就好了。原理跟大家說的一樣,就是用偽元素+垂直方向上的padding實現。偽元素默認為:after,如果:after已被佔用,可以給$pos傳入"before"。$percentage為高/寬的百分比,默認為百分百,也就是正方形。

這樣用:

.box {
width: 100%;
@include heightRelativeToWidth(75%); //高是寬的75%
}


/* 核心樣式 */

.box-warp{ position:relative; display:inline-block; }

.box-warp:before{ content:""; display:block; margin-top:100%}

.box { position:absolute; top:0; left:0; bottom:0; right:0; }

/* 補充樣式 */

.box-warp{ width:50%; text-align:center; }

.box{background:#f1f1f1}

結構代碼

&

&1:1大小的div。&

&

margin-top:100% 這個是比例。

原理很簡單,利用為元素的margin-top撐開div。然後設置一個絕對定位的子元素=父元素大小。


padding-bottom啊,ie6時代就有解決方案了

可以看一下我的這篇博文,https://github.com/xieranmaya/blog/issues/4,裡面就用到了這個技巧來實現寬高比鎖定的容器,然後把圖片放裡面


基本點就是 padding 你需要的百分比


舉例: 鎖定 寬度:高 為 5:2

設置padding-top:40%即可,然後給個子元素定位寬高100%

另外padding-top,padding-bottom,margin-top,margin-bottom 這幾個百分比,都是相對自身的寬度計算的


推薦閱讀:

二八原則中的css?
輸入框里那個一閃一閃的游標如何改變樣式?
如何加入w3c小組?
類似angularJS里的路由,有沒有類似的前端路由框架,我想實現左側導航不刷新,只刷新右側內容的界面?
自學 HTML 和 CSS,有哪些好的教材和網站教程推薦?

TAG:CSS | HTML5 |