Aitter's Blog

Flex布局应用

CSS3为我们提供了一种可伸缩的灵活的web页面布局方式-flexbox布局,它具有很强大的功能,可以很轻松实现很多复杂布局。然而Flex属性较多,不便于记忆,而在项目中,布局使用频繁,那么可以将flex抽离为一个布局工具类,简化使用方式,快速应用于项目,减少记忆成本。

Flex介绍

Flex布局,可以简便、完整、响应式地实现各种页面布局。目前,它已经得到了所有浏览器的支持。
Flex是 Flexible Box 的缩写,意为”弹性布局”,用来为盒状模型提供最大的灵活性。

基本概念

采用Flex布局的元素为,称为 Flex容器,容器的直接子元素称为 Flex项目,容器默认有两个轴心线,用于项目的对齐与排列,水平主轴为 main axis,垂直主轴为 cross axis,主轴的开始位置为 start, 结束位置为 end

主轴和交叉轴的判定:如果flex-direction为row,则主轴是水平方向,如果是column,则主轴是垂直方向

CSS属性说明

将任意元素的 display 属性设置为 flex,可将其转换为Flex容器
设为Flex容器后,子元素的 floatclearvertical-align 属性将失效

Flex容器属性

主轴方向:水平排列(默认) | 水平反向排列 | 垂直排列 | 垂直反向排列
flex-direction: row | row-reverse | column | column-reverse;
换行:不换行(默认) | 换行 | 反向换行(第一行在最后面)
flex-wrap: nowrap | wrap | wrap-reverse;
flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap
flex-flow: <flex-direction> || <flex-wrap>;
主轴对齐方式:起点对齐(默认) | 终点对齐 | 居中对齐 | 两端对齐 | 分散对齐
justify-content: flex-start | flex-end | center | space-between | space-around;
交叉轴对齐方式:起点对齐(默认) | 终点对齐 | 居中对齐 | 第一行文字的基线对齐 | 拉伸对齐
align-items: flex-start | flex-end | center | baseline | stretch;
多根轴线对齐方式:起点对齐(默认) | 终点对齐 | 居中对齐 | 两端对齐 | 分散对齐 | 拉伸对齐
align-content: flex-start | flex-end | center | space-between | space-around | stretch;

Flex项目属性

顺序:数值越小越靠前,默认为0
order: <number>;
放大比例:默认为0,如果有剩余空间也不放大,值为1则放大,2是1的双倍大小,以此类推
flex-grow: <number>;
缩小比例:默认为1,如果空间不足则会缩小,值为0不缩小
flex-shrink: <number>;
项目自身大小:默认auto,为原来的大小,可设置固定值 50px/50%
flex-basis: <length> | auto;
flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto
两个快捷值:auto (1 1 auto) 和 none (0 0 auto)
flex:none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
项目自身对齐:继承父元素(默认) | 起点对齐 | 终点对齐 | 居中对齐 | 基线对齐 | 拉伸对齐
align-self: auto | flex-start | flex-end | center | baseline | stretch;

flex.css的使用

使用data属性来设置css样式,便于兼容现有的项目,避免样式重名。

Flex容器配置项

标签属性使用方式: data-flex="xxx xxx xxx"

配置项

排列形式: row | column
间距: gutter
内容水平垂直居中: center
可换行: wrap
主轴对齐方式: main-start | main-center | main-end | main-between | main-around
交叉轴对齐方式: cross-start | cross-center | cross-end | cross-baseline | cross-stretch
多轴对齐方式: start | end | center | between | around | stretch
响应式: full

Flex项目的配置项

标签属性使用方式: data-cell="xxx xxx xxx"

配置项

元素自身对齐方式: start | end | center | baseline | stretch
固定宽度: 1/2 | 1/3 | 1/4 | 1/5 | 1/6
排序: order[1-10]

使用

基础栅格系统

每项宽度相同,自然平分,高度默认都相同

<div data-flex="gutter">
<div data-cell><div class="item">auto</div></div>
<div data-cell><div class="item">auto</div></div>
<div data-cell><div class="item">auto</div></div>
<div data-cell><div class="item">auto</div></div>
<div data-cell><div class="item">auto</div></div>
</div>

相对的固定宽度与自适应宽度

<div data-flex="gutter row">
<div data-cell="1/2"><div class="item">1/2</div></div>
<div data-cell><div class="item">auto</div></div>
<div data-cell><div class="item">auto</div></div>
</div>

响应式

响应式栅格系统通过添加媒体查询到栅格元素或栅格容器来实现。
当满足媒体查询的条件时,栅格系统就能自动调整。

<div data-flex="full gutter">
<div data-cell><div class="item">full/auto</div></div>
<div data-cell><div class="item">full/auto</div></div>
<div data-cell><div class="item">full/auto</div></div>
</div>

项目对齐

置顶对齐
项目默认是置顶对齐的,手动添加可以使用 cross-start

<div data-flex="gutter">
<div data-cell> <div class="item">置顶对齐</div></div>
<div data-cell> <div class="item">Pellentesque sagittis vel erat ac laoreet. Phasellus ac aliquet enim, eu aliquet sem.</div></div>
<div data-cell> <div class="item">置顶对齐</div></div>
</div>

置底对齐

<div data-flex="gutter cross-end">
<div data-cell> <div class="item">置底对齐</div></div>
<div data-cell> <div class="item">Pellentesque sagittis vel erat ac laoreet. Phasellus ac aliquet enim, eu aliquet sem.</div></div>
<div data-cell> <div class="item">置底对齐</div></div>
</div>

垂直居中对齐

<div data-flex="gutter cross-center">
<div data-cell> <div class="item">居中对齐</div></div>
<div data-cell> <div class="item">Pellentesque sagittis vel erat ac laoreet. Phasellus ac aliquet enim, eu aliquet sem.</div></div>
<div data-cell> <div class="item">居中对齐</div></div>
</div>

混合对齐
为个别项目自身设置独立的对齐方式

<div data-flex="gutter">
<div data-cell="start"> <div class="item">居顶对齐</div></div>
<div data-cell="start"> <div class="item">Pellentesque sagittis vel erat ac laoreet. Phasellus ac aliquet enim, eu aliquet sem.</div></div>
<div data-cell="center"> <div class="item">居中对齐</div></div>
<div data-cell="end"> <div class="item">居底对齐</div></div>
</div>

主轴起点对齐

<div data-flex="gutter main-start">
<div data-cell="1/5"> <div class="item">居左对齐</div></div>
</div>
<div data-flex="gutter main-center">
<div data-cell="1/5"> <div class="item">居中对齐</div></div>
</div>
<div data-flex="gutter main-end">
<div data-cell="1/5"> <div class="item">居右对齐</div></div>
</div>

主轴两端对齐

<h5>两端对齐</h5>
<div data-flex="gutter main-between">
<div data-cell="1/5"> <div class="item">两端对齐</div></div>
<div data-cell="1/5"> <div class="item">两端对齐</div></div>
<div data-cell="1/5"> <div class="item">两端对齐</div></div>
</div>

主轴分散对齐

<h5>分散对齐</h5>
<div data-flex="gutter main-around">
<div data-cell="1/5"> <div class="item">分散对齐</div></div>
<div data-cell="1/5"> <div class="item">分散对齐</div></div>
<div data-cell="1/5"> <div class="item">分散对齐</div></div>
</div>

无限嵌套

栅格可以无限嵌套在另一个栅格中

<div data-flex="gutter">
<div data-cell>
<div class="item">
<div data-flex="gutter">
<div data-cell><div class="item">1</div></div>
<div data-cell>
<div class="item">
<div data-flex="gutter">
<div data-cell><div class="item">2</div></div>
<div data-cell><div class="item">2</div></div>
</div>
</div>
</div>
</div>
</div>
</div>
<div data-cell="1/4"><div class="item">1/4</div></div>
</div>

自定义顺序

<div data-flex="gutter">
<div data-cell="order5"><div class="item">1</div></div>
<div data-cell="order3"><div class="item">2</div></div>
<div data-cell="order2"><div class="item">3</div></div>
<div data-cell="order1"><div class="item">4</div></div>
<div data-cell="order4"><div class="item">5</div></div>
</div>

兼容性

flex在演化过程有三个版本,旧版本 display:box | inline-box, 混合版本 display:flexbox | inline-flexbox, 新版本 display: flex | inline-flex

.box{
display: -webkit-box; /* 老版本语法: Safari, iOS, Android browser, older WebKit browsers. */
display: -moz-box; /* 老版本语法: Firefox (buggy) */
display: -ms-flexbox; /* 混合版本语法: IE 10 */
display: -webkit-flex; /* 新版本语法: Chrome 21+ */
display: flex; /* 新版本语法: Opera 12.1, Firefox 22+ */
}

旧版相对于新版的主要区别:flex项目必须是block,没有换行设置,没有反向设置,主轴没有space-around,顺序值从1开始

关于新旧版的详情对比可参考下面两篇

这里我们使用 postcss 插件 autoprefixer 来自动处理新旧版的兼容,配置如下:

autoprefixer({
browsers: [
'ie >= 8',
'ie_mob >= 10',
'ff >= 26',
'chrome >= 30',
'safari >= 6',
'opera >= 23',
'ios >= 5',
'android >= 2.3',
'bb >= 10'
]
})

这里只做了语法上的兼容,但是旧版所没有的特性仍然要警慎使用,参考上面的区别,相信以后随着浏览器的升级,差别会越来越小

示例

flex.css 的具体源码,请参考示例

参考阅读