先回顾一下CSS1 和 CSS2中都已经定义了哪些布局方面的属性,这样也会增加我们理解弹性布局。   其实我们现在有很多一部分人,你们刚刚接触CSS层叠样式表,或者接触有一段时间了,但是却没有很好的去消化与理解。可能平时你们还一直在使用table,然后通过不断了合并单元格来实现网页布局。希望我今天的这篇文章能彻底改变大家的观念。   ​Q:如何理解盒子模型?

A:​大家可以想一想,在现实生活中,如果我们拿一个盒子来装东西,那么盒子里面的东西是不是跟这个盒子之间会有空隙呢?站在里面物品的角度,则它们之间的间隙距离是不是就可以构成 物品到盒子的外边距。如果站在盒子的角度,则从盒子到物品的距离,是不是可以看出盒子的内边距呢。 当然,盒子还是会有宽和高的。外边距的英文就是margin,内边距的英文是padding,宽是width,高是height。下面是盒子模型的2D图:


​ CSS 1中定义了盒子模型的基本元素,详细属性请看下表:

margin-top

元素顶部外边距

margin-right

元素右侧外边距

margin-bottom

元素底部外边距

margin-left

元素左侧外边距

margin

这是一个复合属性,定义 元素 各个边的外边距, 属性值的顺序是: 上,右,下,左

border-top

元素上边框样式

border-right

元素右边框样式

border-bottom

元素下边框样式

border-left

元素左边框样式

border-width

元素边框宽度

border-top-width

元素上边框宽度

border-right-width

元素右边框宽度

border-bottom-width

元素下边框宽度

border-left-width

元素左边框宽度

border

复合属性,可以同时设置各个边框样式

padding-top

元素上侧内边距

padding-right

元素右侧内边距

padding-bottom

元素下侧内边距

padding-left

元素左侧内边距

padding

复合属性,同时设置各个边框内边距

width

设置元素的宽度

height

设置元素的高度

float

设置元素浮动显示

clear

清除元素的浮动效果

border-color

设置边框颜色

border-style

设置边框样式

CSS 2在以上基础上,又做了一些细化:


border-top-color

元素上边框颜色

border-right-color

元素右边框颜色

border-bottom-color

元素下边框颜色

border-left-color

元素左边框颜色

border-top-style

元素上边框样式

border-right-style

元素右边框样式

border-bottom-style

元素下边框样式

border-left-style

元素左边框样式

  在CSS2的基础上,​CSS3​增加了弹性盒模型布局属性,这为我们开发适合现代移动浏览器提供了便利:

box-align

子元素在盒子内垂直方向上的空间分配

box-pack

子元素在盒子内水平方向的空间分配方式

box-direction

盒子的显示顺序

box-flex

元素在盒子内的自适应尺寸

box-flex-group

自适应子元素群组

box-lines

子元素分列显示

box-ordinal-group

子元素在盒子内的显示位置

box-orient

盒子分布的坐标轴

  下面我将对CSS3中新增的弹性盒模型属性做详细介绍,并通过实际coding来带领大家深刻认识弹性布局的威力。   首先我们先创建一个html页面,代码如下所示:

<!DOCTYPE html>​​<html>​

​<head>​

​<meta charset=”utf-8″>​

​<link rel=”stylesheet” href=”styles.css”>​

​<!-- css3,html5,javascript,jquery,nodejs,extjs,grails -->​

​<title>CSS3弹性布局</title>​

​</head>​

​<body>​

​<div class=”row“>​

​<div class=”sidebar“>​

​我是边栏​

​</div>​

​<div class=”middle“>​

​我是中间内容​

​</div>​

​<div class=”article“>​

​我是页面主体​

​</div>​

​</div>​

​</body>​

​</html>​

接着我们给页面添加上基本的样式,如下所示:

*{ /*清除所有元素的默认外边距和内边距*/margin:0;padding:0;} .row{/*设置外围容器样式*/margin:auto;border:1px solid black;width:600px;height:400px;margin-top:50px;} .sidebar{/*给侧边栏添加样式*/ } .middle{/*给中间区域添加样式*/ } .article{/*给主体内容添加样式*/ }

  运行页面,查看一下目前样式的应用效果: ​​    

首先声明:要想运用CSS3的弹性布局,需要将父容器设置为display:box 或 display:inline-box,下面不在赘述。




box-orient 作用: ​box-orient属性规定了子元素应该是水平方向还是垂直方向显示。

box-orient 语法: ​box-orient: horizontal | vertical | inline-axis | block-axis | inherit;

 语法解释: ​horizontal 和 inline-axis 规定了子元素以水平方向显示,两者的显示效果差不多,具体差异不清。vertical 和 block-axis 规定了子元素以垂直方向显示, 两者的显示效果差不多,具体差异不清 。

 注意:​由于此属性还处于测试当中,所以为了兼容webkit核心的浏览器,需要加上​-webkit-​前缀,Mozilla核心的浏览器,需要加上前缀​-moz-​。

 示例:     ​修改样式表文件,添加如下样式代码:


.row{/*设置外围容器样式*/margin:auto;border:1px solid black;width:600px;height:400px;margin-top:50px; 

display:-webkit-box;/*兼容webkit或mozilla核心浏览器,启用弹性盒子模型*/

display:-moz-box;display:box;

 -webkit-box-orient:horizontal;/*水平方向显示,兼容webkit和mozilla核心浏览器*/

-moz-box-orient:horizontal;box-orient:horizontal;

运行demo页面,效果如下: ​​   通过以上效果图,大家可以发现div已经变成了水平布局,且宽度是正好包裹内容, css2.1如果需要实现此效果,就得通过float:left;来实现了。   我们再次修改代码,实现垂直方向上布局:

.row{/*设置外围容器样式*/margin:auto;border:1px solid black;width:600px;height:400px;margin-top:50px; display:-webkit-box;/*兼容webkit或mozilla核心浏览器,启用弹性盒子模型*/display:-moz-box;display:box; -webkit-box-orient:vertical;/*垂直方向显示,兼容webkit和mozilla核心浏览器*/

-moz-box-orient:vertical;

box-orient:vertical;}

运行页面,效果如下图所示: ​​   inline-axis 和 block-axis 运行效果分别与horizontal和vertical一样,这里大家可以自行去测试。

inherit属性值是布局方式继承自父元素,如果父元素是水平的,则它也使用水平布局,​这个大家可以自行去测试。



box-align 作用:​box-align规定了如何在垂直方向上对齐框内的子元素。

box-align 语法:​box-align: start | end | center | baseline | stretch;  

start

对于正常方向的框,每个子元素的上边缘沿着框的顶部放置。对于反方向的框,每个子元素的下边缘沿着框的底部放置。

end

对于正常方向的框,每个子元素的下边缘沿着框的底部放置。对于反方向的框,每个子元素的上边缘沿着矿的顶部放置。

center

均等地分割多余的空间,一半位于子元素之上,一半位于子元素之下。

baseline

如果box-orient是inline-axis或horizontal,所有子元素均与其基线对齐。

stretch

拉伸子元素以填充包含块


注意:​由于此属性还处于测试当中,所以为了兼容webkit核心的浏览器,需要加上​-webkit-​前缀,Mozilla核心的浏览器,需要加上前缀​-moz-​。   示例:       添加start样式,代码如下:

.row{/*设置外围容器样式*/margin:auto;border:1px solid black;width:600px;height:400px;margin-top:50px; display:-webkit-box;/*兼容webkit或mozilla核心浏览器,启用弹性盒子模型*/display:-moz-box;display:box; -webkit-box-orient:horizontal;/*水平方向显示,兼容webkit和mozilla核心浏览器*/

-moz-box-orient:horizontal;

box-orient:horizontal; -webkit-box-align:start;/*正常布局下,吸附在顶端显示,相反布局下,吸附在底部显示*/

-moz-box-align:start;box-align:start;

}

运行效果如下所示: ​​   接着,我们让子元素吸附在底部显示,修改代码如下:

.row{/*设置外围容器样式*/margin:auto;border:1px solid black;width:600px;height:400px;margin-top:50px; display:-webkit-box;/*兼容webkit或mozilla核心浏览器,启用弹性盒子模型*/display:-moz-box;display:box; -webkit-box-orient:horizontal;/*水平方向显示,兼容webkit和mozilla核心浏览器*/-moz-box-orient:horizontal;box-orient:horizontal; -webkit-box-align:end;/*正常布局下,吸附在底部显示,相反布局下,吸附在顶部显示*/

-moz-box-align:end;

box-align:end;}

此时的运行效果如下所示: ​

  center和baseline的功能,大家可以自行测试,这里着重强调一下,如果属性值设为​stretch​,则它会拉伸填充满父元素,其实也就是未设置box-align时候的样式,所以说如果你要设置stretch,那你直接就别设置box-align属性,因为没意义了。   修改属性值为stretch,代码如下:

.row{/*设置外围容器样式*/margin:auto;border:1px solid black;width:600px;height:400px;margin-top:50px; display:-webkit-box;/*兼容webkit或mozilla核心浏览器,启用弹性盒子模型*/display:-moz-box;display:box; -webkit-box-orient:horizontal;/*水平方向显示,兼容webkit和mozilla核心浏览器*/-moz-box-orient:horizontal;box-orient:horizontal; -webkit-box-align:stretch;/*其实此效果就是不设置box-align时候的样式*/

-moz-box-align:stretch;

box-align:stretch;}

效果如下: ​​  

box-pack 作用:​用来规定子元素在盒子内的水平空间分配方式

box-pack 语法:​box-pack: start | end | center | justify;  

start

对于正常方向的框,首个子元素的左边缘吸附在盒子的左边框显示对于相反方向的框,最后子元素的右边缘吸附在盒子的右边框显示

end

对于正常方向的框,最后子元素的右边缘吸附在盒子的右边框显示对于相反方向的框,首个子元素的左边缘吸附在盒子的左边框显示

center

均等分割剩余空间,一半在首个子元素之前,一半在最后子元素之后

justify

首尾子元素分别吸附在左右边框上,中间的子元素分割多余空间


注意:​由于此属性还处于测试当中,所以为了兼容webkit核心的浏览器,需要加上​-webkit-​前缀,Mozilla核心的浏览器,需要加上前缀​-moz-​。  

示例:

     ​ box-pack:start;


​.row{/*设置外围容器样式*/​

​margin:auto;​

​border:1px solid black;​

​width:600px;​

​height:400px;​

​margin-top:50px;​

​display:-webkit-box;/*兼容webkit或mozilla核心浏览器,启用弹性盒子模型*/​

​display:-moz-box;​

​display:box;​

​-webkit-box-orient:horizontal;/*水平方向显示,兼容webkit和mozilla核心浏览器*/​

​-moz-box-orient:horizontal;​

​box-orient:horizontal;​

​-webkit-box-align:center; /*在垂直方向上,居中显示*/​

​-moz-box-align:center;​

​box-align:center;​

-webkit-box-pack:start; /*在水平方向上,正常情况下,从左侧显示。*/​

-moz-box-pack:start;

box-pack:start;

​}​

    运行效果如下: ​

  当然,如果盒子的顺序是从右到做,则上图就会吸附在右侧边框显示。       ​box-pack:end;

​.row{/*设置外围容器样式*/​

​margin:auto;​

​border:1px solid black;​

​width:600px;​

​height:400px;​

​margin-top:50px;​

​display:-webkit-box;/*兼容webkit或mozilla核心浏览器,启用弹性盒子模型*/​

​display:-moz-box;​

​display:box;​

​-webkit-box-orient:horizontal;/*水平方向显示,兼容webkit和mozilla核心浏览器*/​

​-moz-box-orient:horizontal;​

​box-orient:horizontal;​

​-webkit-box-align:center; /*在垂直方向上,居中显示*/​

​-moz-box-align:center;​

​box-align:center;​

​-webkit-box-pack: end; /*在水平方向上,正常情况下,吸附在右侧显示。*/​

​-moz-box-pack: end;​

​box-pack: end;​

​}​

运行效果如下: ​​   注:如果盒子内的显示顺序是相反方向,则它会吸附在左侧边框显示。  

box-pack:center

.row{/*设置外围容器样式*/margin:auto;border:1px solid black;width:600px;height:400px;margin-top:50px; display:-webkit-box;/*兼容webkit或mozilla核心浏览器,启用弹性盒子模型*/display:-moz-box;display:box; -webkit-box-orient:horizontal;/*水平方向显示,兼容webkit和mozilla核心浏览器*/-moz-box-orient:horizontal;box-orient:horizontal; -webkit-box-align:center; /*在垂直方向上,居中显示*/-moz-box-align:center;box-align:center; -webkit-box-pack: center;

-moz-box-pack: center;

box-pack: center;}

    运行效果如下: ​​  

box-pack:justify

​.row{/*设置外围容器样式*/​

​margin:auto;​

​border:1px solid black;​

​width:600px;​

​height:400px;​

​margin-top:50px;​

​display:-webkit-box;/*兼容webkit或mozilla核心浏览器,启用弹性盒子模型*/​

​display:-moz-box;​

​display:box;​

​-webkit-box-orient:horizontal;/*水平方向显示,兼容webkit和mozilla核心浏览器*/​

​-moz-box-orient:horizontal;​

​box-orient:horizontal;​

​-webkit-box-align:center; /*在垂直方向上,居中显示*/​

​-moz-box-align:center;​

​box-align:center;​

​-webkit-box-pack: justify; /*在水平方向上,正常情况下,从左侧显示。*/​

​-moz-box-pack: justify;​

​box-pack: justify;​

​}​

运行效果如下:   ​​    


box-direction​ 作用:box-direction规定了盒子内子元素以什么方向来排列。 box-direction 语法:box-direction: normal | reverse | inherit;  

normal

以默认方式显示子元素

reverse

以相反方向显示子元素

inherit

从父容器继承box-direction


注意:​由于此属性还处于测试当中,所以为了兼容webkit核心的浏览器,需要加上​-webkit-​前缀,Mozilla核心的浏览器,需要加上前缀​-moz-​。   示例:       现在我就基于上面的例子,在样式表文件的 .row 里加上box-direction属性,大家一起观察分别观察它们的区别    

 以水平方向显示子元素 box-orient:horizontal;




normal

.row{/*设置外围容器样式*/… /*此处代码省略*/ -webkit-box-orient:horizontal;/*水平方向显示,兼容webkit和mozilla核心浏览器*/-moz-box-orient:horizontal;box-orient:horizontal; -webkit-box-pack:justify; /*在水平方向上,正常情况下,从左侧显示。*/-moz-box-pack:justify;box-pack:justify; 

-webkit-box-direction:normal; /*以正常方向显示*/

-moz-box-direction:normal;box-direction:normal;

}


大家可以发现显示顺序还是以前默认的显示顺序,

水平方向,就是从左到右

reverse

.row{/*设置外围容器样式*/… /*此处代码省略*/ -webkit-box-orient:horizontal;/*水平方向显示,兼容webkit和mozilla核心浏览器*/-moz-box-orient:horizontal;box-orient:horizontal; -webkit-box-pack:justify; /*在水平方向上,正常情况下,从左侧显示。*/-moz-box-pack:justify;box-pack:justify; 

-webkit-box-direction:reverse; /*以相反方向显示*/

-moz-box-direction: reverse;box-direction: reverse;

}


应用上box-direction:reverse之后,显示方向颠倒了,

以前是从左到右,现在变成从右到左了。



以垂直方向显示子元素 box-orient: vertical;




normal

.row{/*设置外围容器样式*/… /*此处代码省略*/ -webkit-box-orient:vertical;/*垂直方向显示,兼容webkit和mozilla核心浏览器*/-moz-box-orient:vertical;box-orient:vertical; -webkit-box-direction: normal;

-moz-box-direction: normal;

box-direction: normal;}


大家可以发现,当以垂直方向显示子元素时,normal属性采用默认的从上到下显示顺序。

reverse

.row{/*设置外围容器样式*/… /*此处代码省略*/ -webkit-box-orient:vertical;/*垂直方向显示,兼容webkit和mozilla核心浏览器*/-moz-box-orient:vertical;box-orient:vertical; -webkit-box-direction:reverse;-moz-box-direction:reverse;box-direction:reverse;}


应用上box-direction:reverse之后,显示方向颠倒了,

以前是从上到下,现在变成从下到上了。


  从上面的比较,大家可以看出,​box-direction是根据当前子元素的显示方向(水平或垂直)来起作用的​。   box-direction:inherit 这个大家可以私下自行测试。  


box-flex 作用:​box-flex属性规定了盒子内的子元素是否可以自动伸缩其尺寸,只要盒子内对应显示方向上有剩余空间,可伸缩元素就会扩展来填充这些空间。

box-flex 语法:​box-flex: value。  

value

元素的可伸缩值,柔性是相对,例如 box-flex:2.0 的子元素伸缩尺寸两倍于 box-flex:1.0的子元素

注意:​由于此属性还处于测试当中,所以为了兼容webkit核心的浏览器,需要加上​-webkit-​前缀,Mozilla核心的浏览器,需要加上前缀​-moz-​。   示例:       现在我们就来对box-flex的作用通过示例来证明一下:  

对 sidebar 应用样式

.sidebar{/*给侧边栏添加样式*/  /*将应用了此样式的元素都设置为可伸缩元素*/

-webkit-box-flex:1.0; -moz-box-flex:1.0;box-flex:1.0;

} .middle{/*给中间区域添加样式*/ } .article{/*给主体内容添加样式*/ }


从显示效果来看, 这正好证明了, 设置了box-flex的元素是有弹性的,且只要盒子内对应显示方向上有剩余空间, 可伸缩元素就会扩展来填充这些空间。

对sidebar和middle应用样式

.sidebar{/*给侧边栏添加样式*/   /*将应用了此样式的元素都设置为可伸缩元素*/-webkit-box-flex:1.0;-moz-box-flex:1.0;box-flex:1.0;} .middle{/*给中间区域添加样式*/  /*将应用了此样式的元素都设置为可伸缩元素*/

-webkit-box-flex:2.0; -moz-box-flex:2.0;box-flex:2.0;

} .article{/*给主体内容添加样式*/ }


从显示效果可以看出,当 .middle 样式设置了box-flex:2.0时,应用了 .middle 样式的元素也变成了弹性元素,且伸缩尺寸是box-flex:1.0的两倍。

对sidebar,middle和article应用样式

.sidebar{/*给侧边栏添加样式*/  -webkit-box-flex: 1.0

-moz-box-flex:1.0;

box-flex:1.0;

} .middle{/*给中间区域添加样式*/  -webkit-box-flex:2.0

-moz-box-flex:2.0;

box-flex:2.0;

} .article{/*给主体内容添加样式*/  -webkit-box-flex:3.0

-moz-box-flex:3.0;

box-flex:3.0;}


 这里大家得注意一下,大家可能会认为,.article应该占1/2的空间的,怎么看.sidebar和.middle加起来都比.article大的啊 其实这里分配的原则是, 剩余空间按照对应比率来分配。 对sidebar来说,伸缩的空间 = 总剩余空间 *(1.0/6.0);对middle来说,伸缩的空间 = 总剩余空间*(2.0/6.0) ;对article来说,伸缩的空间 = 总剩余空间 * (3.0/6.0);



box-flex-group 作用: 一组设置了box-flex-group元素当中,值最小的,占用全部剩余空间;值最小且相等,则平均分配剩余空间。


.sidebar{/*给侧边栏添加样式*/  -webkit-box-flex:1.0

-moz-box-flex:1.0;

box-flex:1.0

-webkit-box-flex-group:1; -moz-box-flex-group:1;box-flex-group:1;

} .middle{/*给中间区域添加样式*/  -webkit-box-flex:2.0; -moz-box-flex:2.0;box-flex:2.0; 

-webkit-box-flex-group:2; -moz-box-flex-group:2;box-flex-group:2;

} .article{/*给主体内容添加样式*/  -webkit-box-flex:2.0

-moz-box-flex:2.0;

box-flex:2.0

-webkit-box-flex-group:1; -moz-box-flex-group:1;box-flex-group:1;

}


大家从效果图应该可以看出, 如果box-flex-group的值较大,则它只分配实际空间,剩余空间分配给最小的一组 按比率分配。 这句话到底啥意思呢?我们从代码中可以看到:sidebar的box-flex-group为1,article的box-flex-group也为1,所以 sidebar和article分配剩余的空间。 但是article的box-flex两倍于sidebar的box-flex,所以剩余空间,article伸缩的空间 应该是 sidebar伸缩空间的两倍。



box-ordinal-group 作用:box-ordinal-group属性可以使我们定义子元素的显示顺序,值小的排在前,值大的排在后。  

注意:​由于此属性还处于测试当中,所以为了兼容webkit核心的浏览器,需要加上​-webkit-​前缀,Mozilla核心的浏览器,需要加上前缀​-moz-​。   示例:   我们先看一下,没有运用box-ordinal-group属性时的运行效果,样式代码如下:

.sidebar{/*给侧边栏添加样式*/  -webkit-box-flex:2.0; -moz-box-flex:2.0;box-flex:2.0;} .middle{/*给中间区域添加样式*/  -webkit-box-flex:2.0; -moz-box-flex:2.0;box-flex:2.0;} .article{/*给主体内容添加样式*/  -webkit-box-flex:2.0; -moz-box-flex:2.0;box-flex:2.0;}

此时运行页面,效果如下: ​

    根据上面页面,​当前的显示顺序是 sidebar -> middle -> article

  现在我们给这些子元素应用box-ordinal-group,且相应值 ​middle < article < sidebar,​则我们期待的显示顺序应该是,​ middle -> article -> sidebar

  样式代码如下:

.sidebar{/*给侧边栏添加样式*/  -webkit-box-flex:2.0; -moz-box-flex:2.0;box-flex:2.0; 

-webkit-box-ordinal-group:4;-moz-box-ordinal-group:4;box-ordinal-group:4;

} .middle{/*给中间区域添加样式*/  -webkit-box-flex:2.0; -moz-box-flex:2.0;box-flex:2.0; 

-webkit-box-ordinal-group:2;-moz-box-ordinal-group:2;box-ordinal-group:2;

} .article{/*给主体内容添加样式*/  -webkit-box-flex:2.0; -moz-box-flex:2.0;box-flex:2.0; 

-webkit-box-ordinal-group:3;-moz-box-ordinal-group:3;box-ordinal-group:3;

}

运行页面,效果如下: ​

    从效果图来看,的确是按照我们所期待的顺序显示的(​ middle -> article -> sidebar​)。   至此,CSS3新增弹性盒模型属性就讲完了,本节内容还是比较多的,但是它给了我们很多惊喜,让我们在页面布局方面更加收放自如。