們在日常使用移動APP的時候,特別是一些資訊類的APP,都會有圖片展示的相關(guān)UI,例如APP的單大圖和三圖模式,如下圖:單圖:
三圖:
或者是類似微博或者朋友圈這種9宮格的圖片展示效果,如下圖:
對于這些圖片,如果你單純的以為直接用幾個<img>,配置一下src地址,然后渲染在頁面上,那就大錯特錯了
對于這種類型的UI展示,我們需要明確下面幾點:
大家可以看下面這幾張圖,紅色的是圖片本身,虛線框就是展示出來的區(qū)域,便于理解:寬圖:
長圖:
CSS的background-size:
單獨使用CSS的話,我們可以輕松的實現(xiàn)上面這個效果,主要利用到的屬性就是background-size這個屬性,可以先從概念上了解一下這個屬性:
background-size: length|percentage|cover|contain
我們可以采用background-size:cover;比較合適,在保證縱橫比的情況下,如果圖片超過背景區(qū)域,將多余部分隱藏即可,同時設(shè)置background-position: center center;將主要內(nèi)容居中顯示。
CSS的object-fit:
HTML5新增的<img />標(biāo)簽的屬性object-fit也可滿足需求,但是要注意兼容性。
object-fit: fill|contain|cover|scale-down|none|initial|inherit;
主要用到以下屬性:
如果是一個單大圖,我們可以直接給一個div設(shè)置background-image,然后設(shè)置background-image即可,代碼如下:
<div class="one-img"></div>
.one-img {
width: 100%;
padding-top: 50%;
background-image: url('https://gpic.qpic.cn/gbar_pic/osL7w6JTehzgKuaKrPEJ8V3lia1zoLaPShY05MdBofOpBye0yNpRXYA/');
background-size: cover;
background-position: center center;
}
效果如下圖:
代碼中圖片來源于網(wǎng)絡(luò)
這里有一個知識點,我們?nèi)绻胍獙崿F(xiàn)屏幕的適配,div的長寬是絕不可以寫成固定值px的,所以寬度可以設(shè)置成100%,這樣如果在大屏幕下,圖片自身會變大,但是高度我們是無法設(shè)置一個合適的百分比的,這里我們借助了padding-top屬性,將padding-top設(shè)置成百分比,可以讓一個div的高度被撐開,具體的值依據(jù)寬度的值,即50%表示是寬度(width:100%)的50%。
三張連續(xù)圖,代碼如下:
<div class="three-img-other-wrap">
<div class="three-img-other-1 img-1"></div>
<div class="three-img-other-2 img-2"></div>
<div class="three-img-other-3 img-3"></div>
</div>
.three-img-wrap {
margin-top: 5px;
width: 100%;
overflow: hidden;
}
.three-img {
float: left;
width: 33.3333%;
padding-top: 33.3333%;
border-right: 1px solid #fff;
background-size: cover;
background-position: center center;
box-sizing: border-box;
}
效果如下:
每個div,設(shè)置float:left來實現(xiàn)橫向平鋪,注意一下這里不建議使用display:inline-block,會出現(xiàn)都得空隙,如果想要實現(xiàn)9宮格,將這3個復(fù)制2份即可。
或者是另外一種3+2+1顯示方式圖,代碼如下:
.three-img-other-wrap {
margin-top: 5px;
width: 100%;
overflow: hidden;
}
.three-img-other-1 {
width: 66.6666%;
padding-top: 66.6666%;
float: left;
border-right: 1px solid #fff;
background-size: cover;
background-position: center center;
box-sizing: border-box;
}
.three-img-other-2 {
width: 33.3333%;
padding-top: 33.3333%;
float: left;
border-bottom: 1px solid #fff;
background-size: cover;
background-position: center center;
box-sizing: border-box;
}
.three-img-other-3 {
width: 33.3333%;
padding-top: 33.3333%;
float: left;
background-size: cover;
background-position: center center;
box-sizing: border-box;
}
<div class="three-img-other-wrap">
<div class="three-img-other-1 img-1"></div>
<div class="three-img-other-2 img-2"></div>
<div class="three-img-other-3 img-3"></div>
</div>
效果如下:
從上面的效果圖來看,每張圖片之間都有一定的間距(一般是1px-3px之間),在這里我們?nèi)绻褂胢argin來實現(xiàn)的話,我們是無法設(shè)置一個具體的數(shù)值的,因為我們的長寬都是采用百分比,margin也必須采用百分比,否則會出現(xiàn)錯亂,但是在此場景下margin不適合采用百分比,所以我們采用border邊框來模擬這個間距:
border-right: 1px solid #fff;
box-sizing: border-box;
需要注意box-sizing: border-box;,這樣border將的長度將會計算在整個寬度里面,即border+width等于具體的設(shè)置的百分比。
其實從代碼的優(yōu)雅程度上來說,采用我們上面講解的純Css的方法是比較好的一種方法,但是也有弊端:1. 無法監(jiān)聽圖片的加載成功和失敗事件,例如onerror或者onload。這會導(dǎo)致我們無法給加載失敗的圖片一個默認的顯示圖。2. 我們在實現(xiàn)圖片懶加載的邏輯時,div+background-image這種方式相交于<img>方式需要寫更多的邏輯。
在這里給大家介紹一下div+background-image和<img>之間的區(qū)別:
在網(wǎng)頁加載的過程中,以css背景圖存在的圖片background-image會等到結(jié)構(gòu)加載完成(網(wǎng)頁的內(nèi)容全部顯示以后)才開始加載,而html中的標(biāo)簽img是網(wǎng)頁結(jié)構(gòu)(內(nèi)容)的一部分會在加載結(jié)構(gòu)的過程中加載,換句話講,網(wǎng)頁會先加載標(biāo)簽<img>的內(nèi)容,再加載背景圖片background-image,如果你用引入了一個很大的圖片,那么在這個圖片下載完成之前,<img>后的內(nèi)容都不會顯示。而如果用css來引入同樣的圖片,網(wǎng)頁結(jié)構(gòu)和內(nèi)容加載完成之后,才開始加載背景圖片,不會影響你瀏覽網(wǎng)頁內(nèi)容。
如果我們想要用JavaScript加<img>,來實現(xiàn)這種效果,基本邏輯是:
這里的核心是如何根據(jù)外框的寬高來動態(tài)計算出圖片的位移,我們可以封裝一個方法來計算,具體的邏輯可以看注釋:
getImagePosition(img, cW, cH) {
// cW為外框?qū)挾龋?/ cW為外框高度,
img.marginTop = img.marginLeft = 0;
// img.h表示圖片本身高度,img.height表示計算設(shè)置之后的高度
// img.w表示圖片本身高度,img.width表示計算設(shè)置之后的高度
img.width = cW;
img.height = cH;
// 長圖 優(yōu)先設(shè)置寬度,然后長圖居中
if (img.h * cW / img.w > cH) {
img.height = img.h * cW / img.w;
img.marginTop = (cH - img.height) * 0.5 // 0.5表示居中
} else {// 寬圖 優(yōu)先設(shè)置高度度,然后寬圖居中
img.width = img.w * cH / img.h;
img.marginLeft = (cW - img.width) * 0.5 // 0.5表示居中
}
return img;
}
在計算出圖片位移后,外框的寬高也可以使用JavaScript來動態(tài)設(shè)置,例如屏幕寬度的三分之一或者是圖片寬度的三分之二,代碼如下:
document.body.clientWidth * 0.5
document.body.clientWidth * 2 / 3
在眾多的移動web技能中,圖片居中處理是一個非常重要的技能,也是用的比較多的一種技能,當(dāng)然還有一些極端情況例如遇到面條圖,或者是長寬小于10px的這種非常小的圖片,可能需要單獨特殊邏輯處理了。
白郁悶的找到老朱說道:“朱哥,我想讓一個塊容器在一個容器里面垂直居中怎么這么難啊!”
老朱:“你是怎么實現(xiàn)的?”
小白說:“比如一個容器的高度是400px,子容器的高度是300px,我就把子容器CSS上邊距設(shè)置成50px。”
“那要是父容器高度發(fā)生變化你的子容器豈不是很麻煩”
小白郁悶的說道:“你可說吧!頭疼的很!怎么才能輕松的設(shè)置垂直居中啊?”
老朱說:“如果一個容器只有一行文字和圖片,我們可以設(shè)置容器的高度和line-height一致就可以保證文字和圖片居中,但是多行圖片,或者容器里面嵌套了其他塊元素就很麻煩了。還有一種情況就像你剛剛兩個div嵌套,子容器也是個塊元素,垂直居中直接用CSS會很麻煩,正好今天想跟你說說怎么給jQuery添加擴展方法,索性咱就以這個為例子進行討論吧!”
小白高興的說道:“又有新知識學(xué)了,什么事給jQuery添加擴展方法呢?”
“我們使用$(選擇器)生成的對象有很多默認jQuery方法,你應(yīng)該知道吧?”
小白說道:“知道啊!獲取和修改容器html內(nèi)容的html()方法、獲取和修改屬性的attr()方法、修改元素css樣式的css()方法、獲取元素高度的height()方法、還有控制容器顯示的show()方法……”
“停~!差不多了,這些都是jQuery自帶的方法,假如我們想自己增加一個方法可以用$.fn添加。我現(xiàn)在給你寫一個能夠輸出當(dāng)前容器高度和父容器高度的方法你看看!”
“子容器和父容器的高度在CSS中都有過設(shè)定,因此我通過$.fn添加mid方法以后,再通過選擇器找到sun容器就可以直接使用mid方法了。”
小白突然靈光一現(xiàn),說道:“朱哥我知道怎么設(shè)置一個讓塊容器基于父容器垂直居中了,你稍等我一會,我再你的代碼基礎(chǔ)上改一下!”
也就兩分鐘的時間,小白就把代碼拿到了老朱面前,“你看,我寫好了!”
“現(xiàn)在我想讓sun容器基于main垂直居中只需要使用一下$("#sun").mid()就可以實現(xiàn)了,以后父容器不管怎么變化,它都是基于父容器居中的。”
老朱說道:“如果有多行塊容器,或者多行文本、圖片怎么辦?”
小白說道:“那就給他們外面再嵌套一個塊容器就可以了么!對不對啊?”
“不錯,通過給他們嵌套一個塊容器,然后再讓這個塊容器基于父容器垂直居中就可以了!小白我相信你還能再寫一個基于底部對齊的方法吧?”
小白自信的說道:“再這個方法上改一下就可以了,稍等~”
“嗯,不錯,如果你發(fā)現(xiàn)以后經(jīng)常會用到這兩種居中方式,可以把他們放到一個js文件里面,以后用的時候把這個js文件引入,就可以直接使用mid和bottom方法了。”
“$.fn確實是個好東西!看來我以后得經(jīng)常添加自己的方法了,哈哈,我去練習(xí)了~”
想學(xué)H5的朋友可以關(guān)注老爐,您的關(guān)注是我持續(xù)更新《小白HTML5成長之路》的動力!
平居中方案:
水平居中設(shè)置
1、行內(nèi)元素
設(shè)置 text-align:center
2、定寬塊狀元素
設(shè)置 左右 margin 值為 auto
3、不定寬塊狀元素
a:在元素外加入 table 標(biāo)簽(完整的,包括 table、tbody、tr、td),該元素寫在 td 內(nèi),然后設(shè)置 margin 的值為 auto
b:給該元素設(shè)置 displa:inine 方法
c:父元素設(shè)置 position:relative 和 left:50%,子元素設(shè)置 position:relative 和 left:50%
垂直居中設(shè)置
1、父元素高度確定的單行文本
設(shè)置 height = line-height
2、父元素高度確定的多行文本
a:插入 table (插入方法和水平居中一樣),然后設(shè)置 vertical-align:middle
b:先設(shè)置 display:table-cell 再設(shè)置 vertical-align:middle
在前端面試中,大都會問你div居中的方法:
文筆不好,就隨便寥寥幾句話概括了,希望大家能夠輕拍
不過以后文筆肯定會變得更好一些的。
開始這些東西之前也可以測試一下你對html了解多少,讓我們測試一下吧,小測驗:你對HTML5了解有多少?
今天我們就細數(shù)一下幾種方法:
1,使用position:absolute,設(shè)置left、top、margin-left、margin-top的屬性
.one{
position:absolute;
width:200px;
height:200px;
top:50%;
left:50%;
margin-top:-100px;
margin-left:-100px;
background:red;
}
這種方法基本瀏覽器都能夠兼容,不足之處就是需要固定寬高。
2,使用position:fixed,同樣設(shè)置left、top、margin-left、margin-top的屬性
.two{
position:fixed;
width:180px;
height:180px;
margin-top:-90px;
margin-left:-90px;
background:orange;
}
大家都知道的position:fixed,IE是不支持這個屬性的
3,利用position:fixed屬性,margin:auto這個必須不要忘記了。
.three{
position:fixed;
width:160px;
height:160px;
top:0;
right:0;
bottom:0;
left:0;
margin:auto;
background:pink;
}
4,利用position:absolute屬性,設(shè)置top/bottom/right/left
.four{
position:absolute;
width:140px;
height:140px;
background:black;
}
5,利用display:table-cell屬性使內(nèi)容垂直居中
.five{
display:table-cell;
vertical-align:middle;
text-align:center;
width:120px;
height:120px;
background:purple;
}
6,最簡單的一種使行內(nèi)元素居中的方法,使用line-height屬性
.six{
width:100px;
height:100px;
line-height:100px;
text-align:center;
background:gray;
}
這種方法也很實用,比如使文字垂直居中對齊
7,使用css3的display:-webkit-box屬性,再設(shè)置-webkit-box-pack:center/-webkit-box-align:center
.seven{
width:90px;
height:90px;
display:-webkit-box;
-webkit-box-pack:center;
-webkit-box-align:center;
background:yellow;
color:black;
}
8,使用css3的新屬性transform:translate(x,y)屬性
.eight{
position:absolute;
width:80px;
height:80px;
transform:translate(-50%,-50%);
-webkit-transform:translate(-50%,-50%);
-moz-transform:translate(-50%,-50%);
-ms-transform:translate(-50%,-50%);
background:green;
}
這個方法可以不需要設(shè)定固定的寬高,在移動端用的會比較多,在移動端css3兼容的比較好
9、最高大上的一種,使用:before元素
.nine{
position:fixed;
display:block;
background:rgba(0,0,0,.5);
}
.nine:before{
content:'';
display:inline-block;
vertical-align:middle;
height:100%;
}
.nine .content{
width:60px;
height:60px;
line-height:60px;
color:red;
總而言之所有的居中的方法就是你必須要掌握css屬性的這個概念HTML DIV+CSS,你掌握了就可以好好的運用這些居中的東西了
限時!!免費送Dreamweaver、js等前端教程
↓↓↓
*請認真填寫需求信息,我們會在24小時內(nèi)與您取得聯(lián)系。