一、布局回顾
布局从无到有经历了几个阶段:
1)无布局:html和web的出现源于科学文献的交流,当时人们更注重的是文字的传达,这一时期人们注重的是文字、文本的排版,比如说单个文字的粗细、斜体,段落、标题、列表如何排列等等。
2)Table布局:最基本的就是行与列,我们首先要考虑的是Table布局有多少行,然后列数最多的行有多少列,所有的行都有最多的列数。Table布局有两个问题:
- 行列合并:不管怎么合并,同一列上的内容宽度基本上都是一致的,无法有错落相交的感觉
- 表格嵌套:整体页面的复杂度会变高,不好控制
3)框架布局:分为框架集和内联框架。
框架集,即frame、frameset已经在h5的时代被淘汰了,因为它需要在框架内部嵌入新的网页,它对资源的消耗非常大。比如,做一个上左右的框架结构,我们需要嵌套三个网页,加上整体的网页,我们需要四个网页。
内联框架现在还无法逃脱,即iframe。
4)DIV+CSS:在栅格系统出现之前,出现了很多布局,比如blueprint、960gird,但是它没有考虑移动设备的应用。
5)栅格系统:以bootstrap、ElementUI为代表,提出了移动设备优先(Mobile First)、响应式布局(Responsive,根据不同的分辨率改变自己的样式),但是它们有一些共同的特点:
- 它们通过浮动进行布局,一个行可以把多个div横着排起来,它会带来一些影响,而且复杂度也会变高
6)Flex:弹性盒子
在这个过程中,有些技术一直在使用,一方面是浮动,一方面是定位。定位中的常用技术有:
- relative:相对定位
- absolute:绝对定位
- fixed:固定的
我们常用的布局有两栏或三栏自适应、圣杯布局、垂直水平方向都居中
做一个布局的举例,这个布局倾向于局部布局:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>form布局</title>
<link rel="stylesheet" href="../../../../plugin/bootstrap-3.3.7/css/bootstrap.css">
</head>
<body>
<div class="container">
<div class="row">
<form class="form-horizontal">
<div class="form-group">
<div class="col-md-5">
<div class="input-group">
<span class="input-group-addon">编号</span>
<input class="form-control"/>
</div>
</div>
<div class="col-md-5">
<div class="input-group">
<span class="input-group-addon">姓名</span>
<input class="form-control"/>
</div>
</div>
</div>
<div class="form-group">
<label class="control-label col-md-1">编号</label>
<div class="col-md-4">
<input class="form-control"/>
</div>
<label class="control-label col-md-1">姓名</label>
<div class="col-md-4">
<input class="form-control"/>
</div>
</div>
<div class="form-group">
<label class="control-label col-md-1">职位</label>
<div class="col-md-4">
<div class="col-md-6">
<select class="form-control"></select>
</div>
<div class="col-md-6">
<select class="form-control"></select>
</div>
</div>
</div>
</form>
<div class="row">
<table class="table table-bordered">
<thead>
<tr>
<th>编号</th>
<th>姓名</th>
<th>年龄</th>
<th>性别</th>
<th>部门</th>
<th>职位</th>
</tr>
</thead>
</table>
</div>
</div>
</div>
</body>
</html>
效果图为:
通过这段代码,说明form表单对齐方式的几个问题:
- 把form-group看成行,通过栅格系统进行行内划分。
- input、select等不能单独地直接参与布局,需要加div进行控制。
- 如果想让两个select在一行中,就需要进行行内嵌套。或者通过input-group进行改变外在的表现形式。
- 使用横向排列方式form-horizontal,而不是使用form-inline。
二、弹性布局
1、基本概念
与之前的布局观念有所不同,之前,大部分布局使用table布局,是容器、行、列三层的结构。如今,采用 Flex 布局的元素,称为 Flex 容器(flex container),简称"容器"。它的所有子元素自动成为容器成员,称为 Flex 项目(flex item),简称"项目"。
容器默认存在两根轴:水平的主轴(main axis)和垂直的交叉轴(cross axis)。主轴的开始位置(与边框的交叉点)叫做main start,结束位置叫做main end;交叉轴的开始位置叫做cross start,结束位置叫做cross end。
项目默认沿主轴排列。单个项目占据的主轴空间叫做main size,占据的交叉轴空间叫做cross size。
2、容器的属性
以下6个属性设置在容器上:
- flex-direction
- flex-wrap
- flex-flow
- justify-content
- align-items
- align-content
flex-direction属性
决定主轴的方向(即项目的排列方向)。
<!DOCTYPE html>
<html lang="en">
<style>
.container{
display: flex;
/**
*flex-direction:
*1.row 横向排列
*2. row-reverse
*3、column 纵向排列
*4、column-reverse
*/
flex-direction:column;
}
</style>
<head>
<meta charset="UTF-8">
<title>flex-direction</title>
</head>
<body>
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
</div>
</body>
</html>
效果图为:
它的四个常用值是:
- row(默认值):主轴为水平方向,起点在左端。
- row-reverse:主轴为水平方向,起点在右端。
- column:主轴为垂直方向,起点在上沿。
- column-reverse:主轴为垂直方向,起点在下沿。
flex-wrap属性
默认情况下,项目都排在一条线(又称"轴线")上。flex-wrap属性定义,如果一条轴线排不下,如何换行。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>flex-wrap(换行)</title>
<style>
.container{
display: flex;
width:300px;
height:50px;
border:1px solid;
/**
*flex-wrap:
*1、nowrap
*2、wrap
*3、wrap-reverse
*/
flex-wrap:wrap-reverse;
}
.item{
width:120px;
height:50px;
border:1px solid;
}
</style>
</head>
<body>
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
</div>
</body>
</html>
效果图为:
它的三个常用值是:
- nowrap(默认):不换行
- wrap:换行,第一行在上方
- wrap-reverse:换行,第一行在下方
flex-flow属性
是flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap。
.box {
flex-flow: <flex-direction> || <flex-wrap>;
}
justify-content属性
定义了项目在主轴上的对齐方式。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>justify-content</title>
</head>
<style>
.container{
display:flex;
/**
justify-content:
1、flex-start
2、flex-end
3、center
4、space-between
5、space-around
*/
justify-content:space-around;
}
</style>
<body>
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
</div>
</body>
</html>
效果图为:
它有五个常用值,具体对齐方式与轴的方向有关。下面假设主轴为从左到右。
- flex-start(默认值):左对齐
- flex-end:总对齐
- center:居中
- space-between:两端对齐,项目之间的间隔都相等
- space-around:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。
align-items属性
定义项目在交叉轴上如何对齐。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>align-items</title>
</head>
<style>
.item{
width:50px;
border:1px solid;
margin:10px;
}
.item-s{
width:120px;
border:1px solid;
margin:10px;
}
.item-x{
width:50px;
border:1px solid;
margin:10px;
}
.box{
width:600px;
display:flex;
height:300px;
border:1px solid;
flex-direction:row;
/**
align-items:
1、flex-start
2、flex-end
3、center
4、baseline
5、stretch
*/
align-items:stretch;
}
</style>
<body>
<div class="box">
<div class="item">1</div>
<div class="item-s">2</div>
<div class="item-x">3</div>
</div>
</body>
</html>
效果图为:
它有五个常用值。具体的对齐方式与交叉轴的方向有关,下面假设交叉轴从上到下。
- flex-start:交叉轴的起点对齐。
- flex-end:交叉轴的终点对齐。
- center:交叉轴的中点对齐。
- baseline:项目的第一行文字的基线对齐。
- stretch(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度。
align-content属性
定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>align-content</title>
</head>
<style>
.item{
width:50px;
border:1px solid;
margin:10px;
}
.item-s{
width:120px;
border:1px solid;
margin:10px;
}
.item-x{
width:50px;
border:1px solid;
margin:10px;
}
.box {
width: 600px;
display: flex;
height: 300px;
border: 1px solid;
flex-direction: row;
/**
align-content:
1、flex-start
2、flex-end
3、center
4、space-between
5、space-around
6、stretch
*/
flex-wrap:wrap;
align-content: stretch;
}
</style>
<body>
<div class="box">
<div class="item">1</div>
<div class="item-s">2</div>
<div class="item-x">3</div>
<div class="item">4</div>
<div class="item-s">5</div>
<div class="item-x">6</div>
<div class="item">7</div>
<div class="item-s">8</div>
<div class="item-x">9</div>
</div>
</body>
</html>
效果图为:
该属性有6个常用值:
- flex-start:与交叉轴的起点对齐。
- flex-end:与交叉轴的终点对齐。
- center:与交叉轴的中点对齐。
- space-between:与交叉轴两端对齐,轴线之间的间隔平均分布。
- space-around:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。
- stretch(默认值):轴线占满整个交叉轴。
我们利用骰子的单个项目布局来回顾一下以上的语法:
首先我们设定固定的html模板
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>骰子</title>
<style>
.box{
width:200px;
height:200px;
border:1px solid;
border-radius: 25px;
position:relative;
left:500px;
top:300px;
}
.dot{
width:50px;
height:50px;
background-color: black;
border-radius:60px;
}
/**
在这里填写代码
*/
</style>
</head>
<body>
<div class="box">
<div class="dot"></div>
</div>
</body>
</html>
之后我们将flex布局填进去:
.box {
display: flex;
}
效果图为:
.box {
display: flex;
justify-content: center;
}
效果图为:
.box {
display: flex;
justify-content: flex-end;
}
效果图为:
.box {
display: flex;
align-items: center;
}
效果图为:
.box {
display: flex;
justify-content: center;
align-items: center;
}
效果图为:
.box {
display: flex;
justify-content: center;
align-items: flex-end;
}
.box {
display: flex;
justify-content: flex-end;
align-items: flex-end;
}
效果图为:
参考文献:
http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html
http://www.ruanyifeng.com/blog/2015/07/flex-examples.html