CSS弹性盒布局
Flexible Box Layout
一、Flex布局概述
Flex,即Flexible Box, 意为"弹性盒",用于为盒装模型提供最大的灵活性。
任何一个容器都可以指定为Flex布局。
块级元素可设置display:flex; 行内元素可设置display:inline-flex。
webkit内核的浏览器(Chrome,Safari),需加上-webkit前缀,即-webkit-flex,-webkit-inline-flex。
设为flex布局后,元素的float、clear、vertial-align属性将失效。
1. Flex容器和Flex项目:
- Flex容器(flex container): 采用Flex布局的元素。
- Flex项目(flex item): Flex容器的所有子元素。
2. 容器的两根轴及相关位置、尺寸
- 主轴(main axis):容器的水平轴
- 交叉轴(cross axis): 容器的垂直轴
- main start:主轴的开始位置,即与边框的交叉点
- main end:主轴的结束位置
- cross start: 交叉轴的开始位置
- cross end:交叉轴的结束位置
- main size: 单个项目占据的主轴空间尺寸(项目默认沿主轴排列)
- cross size: 单个项目占据的交叉轴空间尺寸
如下图:

二、Flex容器属性
Flex容器有6个属性:
- flex-direction
- flex-wrap
- flex-flow (flex-derection和flex-wrap的简写)
- justify-content
- align-items
- align-content
1. flex-direction
决定主轴的方向。
.container {
    flex-direction: row | row-reverse | column | column-reverse
}
flex-direction属性可能值:
- row(default):主轴为水平方向,起点在左端。
- row-reverse:主轴为水平方向,起点在右端。
- column:主轴为垂直方向,起点在上端。
- column-reverse:主轴为垂直方向,起点在下端。
2. flex-wrap
规定项目在一条轴线上排不下的时候,如何换行。
.container {
    flex-wrap: nowrap | wrap | wrap-reverse
}
flex-wrap属性可能值:
- nowrap(default):不换行
- wrap:换行,第一行在上方
- wrap-reverse:换行,第一行在下方
3. flex-flow (简写属性)
是flex-direction和flex-wrap的简写形式。默认为flex-flow: row nowrap
.container {
    flex-flow: <flex-direction>|<flex-wrap>
}
4. justify-content
定义项目在主轴方向上的对齐方式。
.container {
    justify-content: flex-start | flex-end | center | space-between | space-around;
}
其具体对齐方式与主轴的方向有关,默认主轴方向是row,在此情况下:
- flex-start(default):左对齐
- flex-end:右对齐
- center: 居中
- space-between: 两端对齐,项目之间的间隔都相等
- space-around: 每个项目两侧的间隔相等,那么项目之间的间隔是项目与边框的间隔的两倍
如下图所示:

5. align-items
定义项目在交叉轴方向上的对齐方式(项目可能还是沿主轴排列的)。
.container {
    align-items: flex-start | flex-end | center | baseline | stretch;
}
其具体的对齐方式与交叉轴的方向有关。这里假设交叉轴是垂直方向。
- stretch(default):如果项目未设置高度或高度为auto,则将占满整个容器的高度
- flex-start: 上对齐
- flex-end: 下对齐
- center: 垂直居中对齐
- baseline: 项目的第一行文字的baseline(基线)对齐
如下图所示:

6. align-content
定义多行主轴的对齐方式。如果项目只有一行主轴,则该属性不起作用。
.container {
    align-content: flex-start | flex-end | center | space-between | space-around | stretch;
}
align-content属性可能值:
- stretch(default):轴线占满整个交叉轴。
- flex-start:与交叉轴的起点对齐。
- flex-end:与交叉轴的终点对齐。
- center:与交叉轴的中点对齐。
- space-between:与交叉轴两端对齐,轴线之间的间隔平均分布。
- space-around:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。
如下图所示:

三、Flex项目属性
flex项目也有6个属性:
- order
- flex-grow
- flex-shrink
- flex-basis
- flex (flex-grow、flex-shrink、flex-basis的简写)
- align-self
1. order
定义项目的排列顺序索引。
.item {
  order: 0|1|2|-1|999
}
order属性可能值:所有interger
- 默认为0。
- 可以为负。
- 数值越小排列越靠前。
- order属性值相等的项目按照书写顺序排列。
如下图所示:

2. flex-grow
定义如果存在剩余空间的时候,项目的放大倍数。
.item { 
  flex-grow: 0|1|2|1.2
}
可能值:number,不能为负。
- 默认为0。即即使存在剩余空间,也不放大。
- 如果所有项目的flex-grow都为1,则它们将等分剩余空间。
- 如果一个项目的flex-grow为2,其他项目的flex-grow都为1,则前者占据的剩余空间是后者的2倍
如下图所示:

3. flex-shrink
定义如果所有项目的默认宽度之和大于容器的时候,项目的缩小比例。
.item {
    flex-shrink: 0|1|2|1.2
}
可能值: number,不能为负。
- 默认为1。即如果空间不足,项目将缩小。
- 如果所有项目的flex-shrink都为1,则当空间不足时它们都将等比例缩小。
- 如果一个项目的flex-shrink为0,其他项目的flex-shrink都为1,则当空间不足时前者不缩小,后者缩小。
4. flex-basis
定义了项目在主轴方向的初始大小。如果不使用 box-sizing 来改变盒模型的话,那么这个属性就决定了 flex 元素的内容盒(content-box)的宽或者高(取决于主轴的方向)的尺寸大小。浏览器会根据这个属性,计算主轴是否有多余空间。
.item {
    flex-basis: auto|10em|3px|content|fill|max-content|min-content|fit-content;
}
flex-basis属性可能值:length
- auto(default):项目的本来大小
- 可以设为和width或height属性一样的值,这样项目将占据固定空间。
5. flex (简写属性)
是flex-grow、flex-shrink、flex-basis的简写形式。后两个属性可选。
可能值:
- 默认为0 1 auto。
- auto: 1 1 auto
- none: 0 0 auto
6. align-self
定义单个项目在交叉轴的对齐方式,它可以覆盖容器元素的align-items属性。即该属性允许单个项目有与其他项目不一样的交叉轴对齐方式。
.item {
    align-self: auto | flex-start| flex-end | center | baseline | stretch ;
}
可能值:
- auto(default): 即与父元素的align-items一致。如果没有父元素,则等同于stretch
- flex-start| flex-end | center | baseline | stretch: 与align-items属性完全一致。
四、我的实践
.toprecommend-part {
  box-sizing: content-box;
	background-color: #f2e5da;
	padding-top: 8px;
	min-height: 96px;
	@media only screen and (min-width: 980px){ 
		margin-top:-30px;
	}
	//height: 300px;
	margin-bottom: 30px;
}
.toprecommend-container {
	//position: relative;
	margin:0 auto;
	min-width: 240px;
	max-width: 1220px;
	padding: 0 20px;	
}
.toprecommend-title {
	//font-family: MetricWeb, sans-serif;
	font-size: 16px;
	line-height: 20px;
	margin-top: 0px;
	margin-bottom: 8px;
	padding-bottom: 8px;
	border-bottom: 1px solid #ccc1b7;
	font-weight: 600;
  //position: relative;
  a {
    color: #000;
    text-decoration: none;
    cursor: pointer;
  }
}
.toprecommend-list { //flex容器
	margin-top: 8px;
	margin-bottom: 0px;
	display: flex;//容器中的直系子元素都会变为 flex 元素
  flex-wrap: wrap;
  /* 指定flex元素单行显示还是多行显示:
   * nowrap: flex元素被摆放到一行
   * wrap: flex元素被打断到多个行中
   * wrap-reverse: 和 wrap 的行为一样,但是 cross-start 和 cross-end 互换。
  */
	zoom:1;
	clear: both;
	@media (min-width: 740px) {
	  margin-left: -20px;
	}
}
.toprecommend-item {//flex元素
	display: block;
  flex-basis: 25%;//指定了 flex 元素在主轴方向上的初始大小。如果不使用 box-sizing 来改变盒模型的话,那么这个属性就决定了 flex 元素的内容盒(content-box)的宽或者高(取决于主轴的方向)的尺寸大小。
  /*
	min-width: 25%;
	max-width: 25%;
  width: 25%;
  */
  padding-left: 20px;
  flex: 1 1 0%;
  /** 规定了弹flex元素如何伸长或缩短以适应flex容器中的可用空间。它是一个简写属性,可以同时设置flex-grow, flex-shrink与flex-basis。
  * flex-grow:拉伸因子,为正整数
  * flex-shrink:收缩因子,flex 元素仅在默认宽度之和大于容器的时候才会发生收缩
  */
  -webkit-flex: 1 1 0%;
  -ms-flex: 1 1 0%;
  
  @media (min-width: 740px) {
    padding-left: 20px;
    -webkit-flex: 0 0 0%; //0,0才是不拉伸也不收缩
    flex-basis: 33.33333%;
  }
  @media (min-width: 980px) {// M
    flex-basis: 25%;
  }
}
.toprecommend-item-content {
	padding-bottom: 12px;
	display: flex;
	font-size: 14px;
	line-height: 16px;
	position: relative;
	width: 100%;
	text-rendering: optimizeLegibility;
	-webkit-font-smoothing: antialiased;
}
.toprecommend-item-title {
	-webkit-box-flex: 1;
	-webkit-flex: 1 0 0%;
	-ms-flex: 1 0 0%;
	flex: 1 0 0%;
	-webkit-box-ordinal-group: 3;
	-webkit-order: 2;
	-ms-flex-order: 2;
	order: 2;
	a {
    font-size: 14px;
    line-height: 16px;
    font-weight: 600;
    color: #000;
    &:visited {
      color: #66605c;
    }
    &:hover {
      color: #736c67;
    }
  }
}
.toprecommend-item-image {
   @media (max-width:1220px) {
    display: none;
  }
  width: 30%;
  -webkit-flex-shrink: 0;
  -ms-flex-negative: 0;
  flex-shrink: 0;
  padding: 4px 10px 0 0;
  img {
   display: block;
  }
  a {
    display: block;
    text-decoration: none;
    cursor: pointer;
  }
}
<div class="toprecommend-part">
    <div class="toprecommend-container">
        <h2 class="toprecommend-title">
            <a class="list-link" href="#">为您推荐</a>
        </h2>
        <ul id="story-recommend-top" class="toprecommend-list">
          <li class="toprecommend-item">
            <div class="toprecommend-item-content">
                <div class="toprecommend-item-title">
                    <a href="/story/001063419?tcode=smartrecommend&ulu-rcmd=undefined">
                        并不风光的中产阶级
                    </a>
                </div>
                <div class="toprecommend-item-image">
                    <a href="/story/001063419?tcode=smartrecommend&ulu-rcmd=undefined">
                        <img src="http://i.ftimg.net/picture/6/000054146_piclink.jpg">
                    </a>
                </div>
            </div>
        </li>
        <li class="toprecommend-item">
            <div class="toprecommend-item-content">
                <div class="toprecommend-item-title">
                    <a href="/story/001062572?tcode=smartrecommend&ulu-rcmd=undefined">
                        新加坡吸引绿地FDI全球居首
                    </a>
                </div>
                <div class="toprecommend-item-image">
                    <a href="/story/001062572?tcode=smartrecommend&ulu-rcmd=undefined">
                        <img src="http://i.ftimg.net/picture/4/000037714_piclink_272_153.jpg">
                    </a>
                </div>
            </div>
        </li>
        <li class="toprecommend-item">
            <div class="toprecommend-item-content">
                <div class="toprecommend-item-title">
                    <a href="/story/001063662?tcode=smartrecommend&ulu-rcmd=undefined">
                        中国经济疲弱对全球影响甚微
                    </a>
                </div>
                <div class="toprecommend-item-image">
                    <a href="/story/001063662?tcode=smartrecommend&ulu-rcmd=undefined">
                        <img src="http://i.ftimg.net/picture/1/000054411_piclink.jpg">
                    </a>
                </div>
            </div>
        </li>
        <li class="toprecommend-item">
            <div class="toprecommend-item-content">
                <div class="toprecommend-item-title">
                    <a href="/story/001060926?tcode=smartrecommend&ulu-rcmd=undefined">
                        “奇怪”的中印增长数据
                    </a>
                </div>
                <div class="toprecommend-item-image">
                    <a href="/story/001060926?tcode=smartrecommend&ulu-rcmd=undefined">
                        <img src="http://i.ftimg.net/picture/5/000050235_piclink.jpg">
                    </a>
                </div>
            </div>
        </li>
      </ul>
    </div>
</div>
参考资料
https://developer.mozilla.org/en-US/docs/Glossary/Flex
https://developer.mozilla.org/en-US/docs/Web/CSS/display
Flex布局教程:实例篇(内含骰子布局、网格布局、圣杯布局)
 
                     
                    
                 
                    
                 
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号