写在前面
最近看到《图解CSS3》的布局部分,结合本身之前阅读过的一些布局方面的知识,这里进行一次基于CSS二、3的各类布局的方法总结。css
在拿到设计稿时,做为一个前端人员,咱们首先会作的应该是为设计图大体地划分区域,而后选择一种最合理的,结构清晰的布局。下面我先根据一些典型的网站案例列举一下几种常见的页面布局。html
这个是咱们比较常见的布局,其页面的顶部通常放置横网站的标志或Banner广告,下方左侧是导航栏菜单,下方右侧则用于放置网页正文等主要内容。
Segmentfault的主页就是T型布局的。因为网页太长了。。没有截取底部。前端
国字型布局下最上面是网站的标题以及横幅广告条,接下来是网站的主要内寄,左右分列一些小条内容,中问是主要部分,与左右一块儿罗列到底,最下方是网站的一些基本信息、联系方式、版权声明等。
案例图片来自腾讯11年的一道前段笔试题,有兴趣的同窗能够去看一下。2011腾讯前端面试稿css3
POP布局指页面布局像一张宣传海报,以一张精美图片做为页面的设计中心。经常使用于时尚类站点。优势显而易见:漂亮吸引人。缺点就是速度慢。
人大的主页就相似这种布局。面试
顾名思义,就是网页主体分为左右两大块,多见为后台管理系统页面。通常左右布局型的页面须要作到两列等高。shell
如:ide
参见苹果的官网,相似于整屏显示的网页都为上下布局。布局
关于布局的类型就先说这么多,下面来总结一下上述的布局怎么来实现。下面提一下你们应该都很熟悉的两大布局方法。圣杯布局和双飞燕布局。其实这两种方法通常多用国字型布局上。就是针对三行三列布局的。进行相应的改造也能够用在T字型布局上。用这两种方法能够很好地解决主体部分优先加载的问题。测试
基础布局:flex
<div id="header"></div> <div id="main"></div> <div id="footer"></div>
重点来看main部分的代码
<style type="text/css"> #main { overflow: hidden; /*修整由子元素浮动引发的高度塌陷问题*/ zoom: 1;/*低版本ie下:触发haslayout属性,修整由子元素浮动引发的高度塌陷问题*/ /*将主体部分左右侧预留出左右边栏大小的空白位置*/ padding: 0 300px 0 220px; } .m_content, .m_leftside, .m_rightside { float: left; /*目的是将左右侧边栏拉回*/ position: relative; } .m_content { width: 100%; } .m_leftside { width: 220px; /*因为m_content占据了100%空间,因此须要用负的margin值将左边栏拉回*/ margin-left: -100%; /*将主体部分预留的左侧补白区域填充满*/ left: -220px; } .m_rightside { width: 300px; /*用负的margin值将右边栏拉回自身大小个像素单位*/ margin-left: -300px; /*将主体部分预留的右侧补白区域填充满*/ left: 300px; } </style> <div id="main"> <div class="m_content">这里是主体</div> <div class="m_leftside">这是左侧边栏</div> <div class="m_rightside">这是右侧边栏</div> </div>
以上就是圣杯布局方法,基本思路是运用浮动加定位的方法,缺点是代码较复杂,不能模拟三栏等高效果。
布局的效果跟圣杯的同样,代码有所不一样。双飞燕布局的代码更加简单,只是多加了一个div用来布局。
基础布局部分代码同样。
main部分:
<style> #main {overflow: hidden;zoom: 1;}/*这里不须要加padding了*/ .m_content, .m_leftside, .m_rightside {float: left;} .m_content {width: 100%;} /*用左右边距将左右边栏的位置预留出来*/ .m_c_wrap {margin-left: 220px;margin-right:300px;} .m_leftside {width: 220px;margin-left: -100%;} .m_rightside {width: 300px;margin-left: -300px;} </style> <div id="main"> <div class="m_content"> <!--正真的主体开始--> <div class="m_c_wrap">这里是主体</div> </div> <div class="m_leftside">这是左侧边栏</div> <div class="m_rightside">这是右侧边栏</div> </div>
了解了以上两种布局的方法后,不少布局都能写得驾轻就熟了。可是应对多栏等高布局还有点欠缺。那么如今来谈谈多栏等高布局的方法。
这里详细总结了等高布局的八大方法 Click,我再谈谈实际项目中比较经常使用的,或者说比较简单的三种方法。
好比咱们须要作一个上图的布局,那么须要截取这样一个侧边的小图片对侧边和内容部分包裹的元素进行背景平铺,用来模拟出侧边栏的高度跟内容高度一致的视觉效果。
只须要将须要等高的若干栏设置display
属性为table-cell
;若其中一列但愿是自适应宽度,还需将父元素的display
设置成table
,width
为100%
。
代码以下:
<style> #main {display: table;width: 100%} .m_content {display: table-cell;width: auto;} .m_rightside {display: table-cell;width: 200px;} </style> <div id="main"> <div class="m_content"></div> <div class="m_rightside"></div> </div>
这是前不久在网上看到的一种办法,实质就是为栏目添加一个足够大的padding-bottom
值,将栏目撑开,而后再添加相同大小的负的margin-bottom
值将内容移动回来。注意要在负盒子上加上overflow: hidden
的属性。
代码以下:
<style> #main {width: 100%;overflow: hidden;} .m_content {width: auto;float:left;} .m_rightside {width: 200px;padding-bottom: 10000px;margin-bottom: 10000px;float:left;} </style> <div id="main"> <div class="m_content"></div> <div class="m_rightside"></div> </div>
CSS2的布局方法总结获得这里就告一段落了。如今来看看CSS3新增的布局方法。
由于书面上的解释比较抽象,我这里就尽可能说得简单通俗一点。
要进行flex布局,须要定义一个flex容器,而后再处理其子项目。只要一个容器被定义为flex容器,那么其子元素都称做它的子项目。
flex布局的基本思想是经过flex容器来伸缩控制子项目的宽度和高度,以此来彻底填充flex容器的可用空间。子项目的宽高、排列方式等都是经过设置相关属性改变的。那么以这种方式布局上述几种布局就简单多了。子项目默认的排列方式与浮动布局略为类似。
flex容器的定义方式:
div{display:flex}
flex容器分为主轴和侧轴。主轴决定容器子项的排列方向。侧轴与主轴相互垂直。主轴可有垂直和水平两个方向。
flex容器可对子项进行的操控有:(即设置在容器的属性。这个很重要!)
子项目的排列方向(也就是刚刚说的定义主轴)—— flex-direction
子项目的换行方式(就是超出flex容器跨度时换不换行=。=怎么换) —— flex-wrap
同时进行子项目排列方向和换行方式的设定 —— flex-flow
子项目在主轴的对齐方式(想象成文字的对齐方式就容易理解了) —— justify-content
子项目在侧轴的对齐方式 —— align-items
同时进行子项目主轴和侧轴对齐方式的设定 —— align-content
下面来看看每个属性的取值和实现效果
flex-direction:
div{ flex-direction: row /*水平排列,默认*/ <row-reverse> /*水平排列,但子项目从右侧开始排列*/ <column> /*垂直排列*/ <column-reverse>; /*垂直排列,但子项目从下侧开始排列*/ }
测试中我令flex容器的宽度为100px,高为200px,定义了5个未定义宽高的子项目,演示了上述的四种排列状况。效果:
这里须要说明的是:在未定义子项目的伸缩方式时,默认是按子项目自己大小渲染的。
flex-wrap
div{ flex-direction: nowrap /*当子项目在主轴上的总跨度大于主轴长度时,不进行换行,而是缩小每一个子项目的跨度。默认*/ <wrap> /*---同上---进行换行显示*/ <wrap-reverse> /*从侧轴的末端进行换行(在主轴的排列方向不变)。实际不经常使用*/ }
测试中我定义了每一个子项目的宽度为30px,flex容器仍是原来的100px宽。效果:
因为这里设定的是子项目宽度,因此对于主轴为垂直方向的容器子项没什么影响。
flex-flow
div{ flex-flow: <flex-direction> || <flex-wrap>; /*就是上述两个属性的结合简写 默认:flex-flow:row nowrap*/ }
justify-content
div{ justify-content: flex-start /*以项目开始进行排列的那端进行对齐,默认左对齐*/ <flex-end> /*以项目结束排列的那端进行对齐,默认右对齐*/ <center> /*居中对齐,默认水平居中*/ /*两端对齐且项目之间的间隔都相等(贴边显示)*/ <space-between> /*第一个元素前的空间以及最后一个元素后的空间为其余空白空间的一半下平均分布*/ <space-around> }
测试时我设定了flex容器宽高都为200px,子项没有设定宽高。 效果:
主轴为水平方向时:
主轴为水平垂直时:
align-items
div{ align-items: flex-start /*侧轴起始点对齐*/ <flex-end> /*侧轴终止点对齐*/ <center> /*侧轴中点点对齐*/ /*项目的第一行文字的基线对齐*/ <baseline> /*默认值,若是项目未设定宽(高度),则占满整个容器侧轴跨度*/ <stretch> }
最后的baseline看起来跟flex-start没啥区别,由于我给每一个子项设置高度。设置高度后:
align-content
div{ align-content: flex-start /*与侧轴起始点对齐*/ <flex-end> /*与侧轴终止点对齐*/ <center> /*与侧轴中点点对齐*/ /*与侧轴两端对齐,各子项在各轴上的间距相等*/ <space-between> /*各子项在各轴上的间距相等,项目间距比边距间距大一倍*/ <space-around> /*项目占满整个侧轴*/ <stretch> }
上面已提到过,对于单轴线的子项来讲,本属性不起做用。可是默认状况下是只有子项目是一根轴线的(flex-wrap
默认是nowrap
),因此要使这个属性看到效果,必须设置flex-wrap
。
已下是flex-wrap
为wrap
的几种状况。
如下这些属性设置在子项上。
子项自身的操控有
子项目的排列顺序 —— order
子项目的放大比例 —— flex-grow
默认为0,即若是主轴上有剩余空间,也不放大子项。
子项目的缩小比例 —— flex-shrink
默认为1,即若是主轴空间不足,即缩小子项。
同时设定前三者 —— flex
设定单个项目其自身在侧轴的对齐方式 —— align-self
那么分别来看看每一个属性的取值和实现效果()
order
利用这个属性能够解决某个区块优先加载可是在页面上的显示较靠后的问题。
div .item {order:<integer>} /*数值越大,排列越靠后。默认为0*/
这里我设置了第一个子项的order为1。
flex-grow
若是全部项目的flex-grow属性都为1,则它们将等分剩余空间(若是有的话)。若是一个项目的flex-grow属性为2,其余项目都为1,则前者占据的空间将比其余项多一倍。
div .item {flex-grow:<number>}
设置flex-grow前:
设置后:
第二个项目的flex-grow为2,其余为0:
<注意这个时候就不须要给子项设置宽度了>
flex-shrink
若是全部项目的flex-shrink属性都为1,当空间不足时,都将等比例缩小。若是一个项目的flex-shrink属性为0,其余项目都为1,则空间不足时,前者不缩小。
div .item {flex-shrink:<number>}
我给每一个子项设定了200px的宽度,而flex容器宽度为500px,这时候若不设置flex-shrink,则每一个项目都会以相同比例缩小自身大小来适应容器。
此时我给第二个项目设置了flex-shrink: 0;
该项目大小不变。
flex-basis
这个属性设置子项在主轴上的跨度,简单地说就是设置宽高。
div .item {flex-basis:<length> | auto/*auto是默认值,就是项目自己大小*/}
flex
这个就是把flex-grow、flew-shrink、flex-basis结合一块儿的写法啦=。=
div .item {flex:none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]}
flex-grow必须。默认为0 1 auto。
align-self
这个属性用来单独设定某个子项目在侧轴的对齐方式。
div .item {align-self:flex-start|flex-end|center|baseline|stretch}
有关flex布局的方法就总结和介绍到这里了。有兴趣看能够看一下下面大大们写的相关方面的文章。
Flex布局教程——阮一峰 传送门
A Complete Guide to Flexbox 传送门2
一个完整的Flexbox指南 传送门3
下边把利用flex布局实现上述几种布局的代码贴出来(可有多种实现方法)。
T布局
<!--css--> <style type="text/css"> *{margin: 0;padding: 0;} header, footer {background: sandybrown;height: 50px;} section {display: flex;align-items: flex-start;height: 500px;} article {order: 1;flex: 3;align-self: stretch;background: wheat;} aside {flex: 1;background: seashell;height: 100px;} </style> <!--html--> <header></header> <section> <article></article> <aside></aside> </section> <footer></footer>
国字型布局
<!--css--> <style type="text/css"> *{margin: 0;padding: 0;} header, footer {background: sandybrown;height: 50px;} section {display: flex;align-items: flex-start;height: 500px;} article {order: 1;flex: 3;align-self: stretch;background: wheat;} aside {flex: 1;background: seashell;height: 100px;} section.sidebar {order: 2;flex: 1;height: 100px;background: seashell;} </style> <!--html--> <header></header> <section> <article></article> <aside></aside> <section class="sidebar"></section> </section> <footer></footer>
等高布局
真心简单。
<!--css--> <style type="text/css"> *{margin: 0;padding: 0;} html,body {height: 100%;} section {display: flex;height: 100%;} article {order: 1;flex: 3;background: wheat;} aside {flex: 1;background: seashell;} </style> <!--html--> <header></header> <section> <article></article> <aside></aside> <section class="sidebar"></section> </section> <footer></footer>
拖了半个多月的博文。。也算是写完了,感谢你们阅读。