C3:使用flex彈性佈局

NO IMAGE

垂直居中

相信我們大多數人都是從static,浮動,定位這三種佈局方式來開始製作網頁的。在大多數的業務需求下,浮動和定位都能夠很好的滿足我們的開發需要。即使是在響應式設計中,浮動和定位配合百分比,rem,媒體查詢都能夠解決大多數的問題。但是如果你只使用浮動和定位的話,碰到以下的場景你就會發現不是那麼好用。

clipboard.png

黃色背景的段落在背景色#ccc的寬高不定的父容器中水平和垂直居中。如果只用浮動和定位的話,貌似很困難。我們得設定p段落相對於父容器絕對定位,left和top都為50%,在使用translate往左往上各移動-50%.

.wrap{
position:relative;
background-color:#ccc;
width:50%;
height:60%;
}
p{
position:absolute;
top:50%;
left:50%;
transform:translate(-50%,-50%);
width:100px;
}

其中的原理是p的left和top的百分比是相對於.wrap 父容器的寬高,而translate的百分比是相對於自身的寬高的。這樣子也能做到元素在寬高不定的容器的垂直水平居中。但是,這不夠優雅和實用,並且累贅

而使用flex的話就比較簡單了。

.wrap{
width:50%;
height:50%
background-color:#ccc;
display:flex;
justify-content:center;
align-items:center;
}

flex的出現,可以讓我們非常輕鬆地解決類似居中的問題。flex是彈性的意思,顧名思義,彈性才是flex的精髓所在。網上已經有很多篇介紹flex的專業文章了。諸如:
Flex 佈局教程:語法篇
Flex 佈局教程:例項篇
一勞永逸的搞定 flex 佈局

flex的12個相關屬性和主軸,交叉軸的概念

對於flex最重要的就是知道其中的12個屬性以及主軸交叉軸的概念。上面三篇文章已經詳盡地解釋了這些概念和屬性的用法。總結出來就是一張圖:

clipboard.png

flex-basis:該值決定了元素在主軸方向上的初始大小.當分配給這個元素的寬度小於這個值的時候,flex父容器內的元素開始拉伸或者縮小.預設取值auto,即是按照元素的width/height屬性來決定的.可取的其他的值是px,rem,百分比.
flex-direction:定義主軸的方向.可選的取值有row,columns,row-reverse,columns-reverse.
flex-grow:flex元素拉伸的比例,
flex-shrink:flex元素壓縮的比例.
justify-content:作用與父容器,定義主軸上的元素的排列方式.可選的值有:flex-start,flex-end,center,space-around,space-between.
align-items:作用於父容器,定義交叉軸上的元素的排列方式,取值和意義同justify-content一樣.
align-self:作用於子容器,子元素自己定義自己在交叉軸上的排列方式.優先順序比父元素指定的高.取值和意義同align-items.
flex:flex-grow,flex-shrink,flex-basis的簡寫.
flex-wrap:定義父容器是否換行.預設不換行.如果該元素取值為wrap.那麼父容器中一行的長度不夠容納的時候,就換行顯示,如果子容器的flex-basis 計算寬度/高度 大於 父容器的寬度/高度,就會壓縮.否則就拉伸.
flex-flow:flex-direction,flex-wrap的簡寫.
order:作用於子容器,定義在主軸上的順序.預設為0,最高.相同的order的情況下,按照在html的順序來決定.

相容性

flex的相容性:IE10以下不支援。IE11以下需要加-ms-字首。android4.4以下需要加-webkit-字首

佈局例項

假設我們的設計稿如下:

clipboard.png

分為兩步:
1.將圖片的父容器設為display:flex;設定文字區域盒子為flex:1;

clipboard.png

2.設定文字區域盒子的display:flex;並且設定主軸向下:flex-direction:columns;
clipboard.png

完整程式碼

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name='viewport' content="width=device-width,initial-scale=1.0,user-scalable=no">
<title>flex 用於產品列表佈局</title>
<style>
*{
padding:0;
margin:0;
border:none;
}
.list{
display:flex;
flex-direction:column;
max-width:640px;
min-width:320px;
width:100%;
margin:0 auto;
}
.item{
border-bottom:1px solid #e0e0e0;
padding:20px;
display:flex;
flex-wrap:wrap;
}
.item .img-con{
width:100px;
height:100px;
position:relative;
overflow:hidden;
}
.item .img-con img{
width:100%;
position:absolute;
top:50%;
left:50%;
transform:translate(-50%,-50%);
}
.item .text-con{
font-size:14px;
flex:1;
margin-left:15px;
/*background-color:#fccf00;*/
align-self:stretch;
display:flex;
flex-direction:column;
justify-content:space-around;
}
.item .text-con h4{
max-height:34px;
overflow:hidden;
font-size:15px;
line-height:1.066667;
}
.item .text-con strong{
font-weight:normal;
color:red;
font-size:16px;
line-height:1.625;
}
</style>
</head>
<body>
<ul class="list">
<li class="item">
<div class="img-con">
<img src="./nature1.jpg" alt="product image" >
</div>
<!--產品文字資訊-->
<div class="text-con">
<h4>上海品圖包裝設計/包裝盒設計/精裝紙盒設計上海品圖包裝設計</h4>
<strong>1.5元/張</strong>
<span>99℃</span>
</div>
</li>
<li class="item">
<div class="img-con">
<img src="./nature1.jpg" alt="product image" >
</div>
<!--產品文字資訊-->
<div class="text-con">
<h4>上海品圖包裝設計/包裝盒設計/精裝紙盒設計上海品圖包裝設計</h4>
<strong>1.5元/張</strong>
<span>99℃</span>
</div>
</li>
<li class="item">
<div class="img-con">
<img src="./nature1.jpg" alt="product image" >
</div>
<!--產品文字資訊-->
<div class="text-con">
<h4>上海品圖包裝設計/包裝盒設計/精裝紙盒設計上海品圖包裝設計</h4>
<strong>1.5元/張</strong>
<span>99℃</span>
</div>
</li>
<li class="item">
<div class="img-con">
<img src="./nature1.jpg" alt="product image" >
</div>
<!--產品文字資訊-->
<div class="text-con">
<h4>上海品圖包裝設計/包裝盒設計/精裝紙盒設計上海品圖包裝設計</h4>
<strong>1.5元/張</strong>
<span>99℃</span>
</div>
</li>
</ul>
</body>
</html>