标题严格遵照了新广告法,你再不爽,我也没犯法呀!话很少说,直入正题。css
所谓布局,其实包含两个含义:尺寸与定位。也就是说,全部与尺寸和定位相关的属性,均可以用来布局。html
大致上,布局中会用到的有:尺寸相关的盒子模型,普通流、浮动、绝对定位三种定位机制,CSS3中的transform、弹性盒子模块、试验中的grid模块。逛园子的时候常常能够看到浮动布局,inline-block布局,弹性盒布局这几个名词。如今对布局也算有一点了解,作个总结巩固一下。若是你也看了不少资料,可是实际动手时对布局仍是无从下手的话,但愿本文能够帮你理清思路。css3
唠叨一句:看到一个效果图的时候,千万不要急着手贱去敲代码!先思考清楚页面的构造,理清各元素之间的关系,特别须要注意的是在不一样的设备下须要有怎样的展示,当你思路清晰找到最好的布局方案时,coding其实真的不须要多少时间。浏览器
尺寸相关网络
为何要先说尺寸呢?由于尺寸在布局中的做用很是核心,布局方式定位这些只是改变了元素之间的关系,没有尺寸就什么也不是。好比咱们一般会用margin来控制跟其余元素的距离,这就是布局。ide
不少人都会以为,什么width、margin太简单了,早就掌握了。这种心态我一开始学习CSS的时候也有,以为很好理解很简单,可是后面才发现本身原来不少东西都没真正掌握。看看张鑫旭大神给咱们上的政治课:http://www.zhangxinxu.com/wordpress/2012/07/bottleneck-css-study/ wordpress
先说说百分比,百分比是相对父对象的,这里特性很是好用,不少时候会用在自适应布局上面。浏览器尺寸的改变,就是根节点html的长宽改变,咱们能够用%来将浏览器尺寸和元素尺寸联系起来,作到自适应。函数
另一个比较有意思的是auto,auto是不少尺寸值的默认值,也就是由浏览器自动计算。首先是块级元素水平方向的auto,块级元素的margin、border、padding以及content宽度之和等于父元素width。使用auto属性在父元素宽度变化的时候,该元素的宽度也会随之变化。布局
可是当该元素被设为浮动时,该元素的width就变成了内容的宽度了,由内容撑开,也就是所谓的有了包裹性。overflow | position:absolute | float:left/right均可以产生包裹性,替换元素也一样具备包裹性。在具备包裹性的元素上想利用width : auto;来让元素宽度自适应浏览器宽是不行的。学习
高度方向:外边距重叠,外边距auto为0,这两点须要注意。书写方向什么的,接触比较少就不扯了。
那为何margin:auto对不能计算垂直方向的值呢?很简单,垂直方向是被设计成能够无限扩展的,内容越多浏览器便产生滚动条来扩展,因此垂直方向都找不到一个计算基准,以此返回一个false,便成了0。
用处:经过width、height控制大小,各个方向的margin值控制与边界或者其余元素的距离来定位。
浮动
目前PC网站大多使用float布局,从成本上考虑大改的几率很小,因此不要说浮动无用,老是会有机会让你维护的!表明网站:淘宝、腾讯、百度,好吧BAT都到齐了。
浮动听得多了,博客园上关于用浮动布局的介绍也很是的多。浮动本来用于文本环绕,但却在布局被发扬光大,这就是命!个人理解:浮动布局的核心就是让元素脱离普通流,而后使用width/height,margin/padding将元素定位。脱离普通流的元素,就像脱离地心引力同样,与普通流不在一个高度上。这个跟图层的概念相似。高度不一样因此能够叠在其余元素上面产生重叠或者使用负边距跑到父元素外,理解了这一点浮动布局就很好理解了。
下面用个圣杯布局的例子说明一下,理解了这个以后其余布局更加简单:
HTML & CSS:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>宽度自适应布局</title> <style> .wrap { background-color: #D66464; } .clearfix:after { content: ""; clear: both; display: block; } .left { float: left; width: 100px; background: #00f; height: 180px; } .right { float: right; width: 150px; background: #0f0; height: 200px; } .center { background: #FFFFFF; margin-left: 110px; margin-right: 160px; height: 150px; } </style> </head> <body> <div class="wrap clearfix"> <div class="left">left,宽度固定,高度可固定也能够由内容撑开。</div> <div class="right">right,宽度固定,高度可固定也能够由内容撑开。</div> <div class="center">center,能够自适应浏览器宽度,高度可固定也能够由内容撑开。</div> </div> </body> </html>
原理很是简单,左右侧边栏定宽并浮动,中部内容区放最后不浮动、默认width:auto并设置相应外边距,让左右侧边栏浮动到上面。注意:子元素设置为浮动以后,父对象的高度就坍塌了,须要设置父对象后的元素清除浮动,这样父对象的高度才能被浮动子元素撑起来了。
固然,咱们也要问一下,为啥父对象高度会坍塌呢?上面也说过了,浮动元素已经脱离了普通流,父对象所在的普通流比喻成地表,那浮动元素就已经上天了。可是父对象还在地表啊,从外太空看浮动元素在父对象里面,可是其实并不在,又怎么能撑开父对象呢?宽度若是咱们不设置的话,其实也是为0的,由于父对象里面空空如也,因此宽高为0。
要撑开的办法就两个,1是让父对象也上天(。。。你咋不上天呢),2是把浮动元素的边框边界拉下来。
父对象也上天(即浮动)的话,那就不能实现宽度自适应了。由于float元素的width:auto是包裹内容的,参考前面说的!
办法2就是在后面的元素里加一个clear语句。说到这个问题就要扯到clear与BFC了,我就不献丑了。传送门:https://developer.mozilla.org/zh-CN/docs/Web/CSS/clear
这个三列布局还有个双飞(是双飞翼!想啥呢)的变种,就是在HTML中center部分也就是内容区提到最前面,也就是内容先行渲染。在网络很差的时候,左右双翼能不能出来没关系,先让主体内容出来!这种想法,明显的优秀工程师思惟,但,尼玛的双翼都是广告啊。广告不出来,哪能赚钱养大家这群工程师?因此提出双飞的玉伯才离开了淘宝???(纯属意淫,如真属实,当我扯淡,哈哈哈!)
先上码:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>宽度自适应布局</title> <style> .wrap { background-color: #FBD570; margin-left: 100px; margin-right: 150px; } .clearfix:after { content: ""; clear: both; display: block; } .left { float: left; width: 100px; background: #00f; height: 180px; margin-left: calc(-100% - 100px); } .right { float: right; width: 150px; background: #0f0; height: 200px; margin-right: -150px; } .center { background: #B373DA; height: 150px; float: left; width: 100%; } </style> </head> <body> <div class="wrap clearfix"> <div class="center">center,能够自适应浏览器宽度,高度可固定也能够由内容撑开。</div> <div class="left">left,宽度固定,高度可固定也能够由内容撑开</div> <div class="right">right,宽度固定,高度可固定也能够由内容撑开</div> </div> </body> </html>
思路:
1)既然HTML里面要让center放前面,为了让left跑到center前面,那center也必须浮动了,不然由于都是块元素他们会分两行。
2)浮动以后还要让center宽度自适应,那明显width只能100%,而后在父元素中设width:auto,还有两侧margin,其实也就是父对象宽度自适应,center只是继承content的宽度。
3)对left使用负的margin让他们浮动到上方去。
代码里面我用到了一个calc(),这个CSS3带来的计算函数简直酷毙了!本例里若是不使用calc函数,那么就须要wrap左边距为0,left左边距-100%,而后center多加一层子块DIV设置margin-left:100px,能够达到一样的效果!calc函数与百分比配合就足以实现自适应的要求!目前全部的自适应布局都在利用浏览器来为咱们计算尺寸,可是有了calc以后咱们就能够本身制定规则!单是想一想都高潮了吧?
总结:使用浮动来进行布局,一个比较大的问题是清除浮动。这个可使用一个after伪类来清除。更大的问题是浮动性像水同样向上流动,难以把握。在元素较多并且元素高度尺寸不一的状况下,单纯使用浮动只能实现上端对齐,这对于适应多种设备的布局就显得力不从心了。目前的作法是牺牲一部份内容,将元素作成等高排列,从美观上看也固然也是极好的,比良莠不齐的排列要美观。
普通流布局
普通流布局:display : inline-block!这是一个传说中取代float布局的存在。看了一些网站,PC端浮动为主,移动端的也用的很少啊,已经有些使用flex的了,说好的inline-block一统江湖呢?
使用inline-block以前先处理点小障碍:inline-block元素会有4px左右的空隙,这个是由于咱们写代码时候的换行符所致。
解决办法很简单:在inline-block的父元素中设置样式font-size:0;letter-spacing: -4px; 而后设置inline-block的全部兄弟元素 font-size:值;letter-spacing: 值px; 恢复正常的显示。
另外还有一点须要注意的是inline-block默认是基线对齐的,而inline-block的基线又跟文本基线一致,因此在内容不一样的时候并不能水平对齐。只须要用vertical-align显式声明一下top/bottom/middle对齐便可。这里补充一下基线的内容,没你想的那么简单哦。分有文字和无文字两种状况:
1)无文字:容器的margin-bottom下边缘。与容器内部的元素没一毛钱关系。
2)有文字:最后一行文字的下边缘,跟文字块(p,h等)的margin、padding不要紧!注意是最后一行,不管文字在什么子对象容器内在什么位置都不要紧,浏览器会找到最后一行文字对齐底部。
大家感觉一下:
警示:inline-block的基线是最后一行文字的底部,flex里面的基线是第一行文字的底部(请看下文阮老师的文章)
满满的都是泪啊。。。既然都叫baseline,何须呢?
使用inline-block进行圣杯布局:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>宽度自适应布局</title> <style> .wrap { background-color: #FBD570; font-size: 0; letter-spacing: -4px; /*用于兼容safari,根据不一样字体字号或许须要作必定的调整*/ margin-left: 100px; margin-right: 150px; } .wrap * { font-size: 1rem; letter-spacing: normal; } .left { display: inline-block; vertical-align: top; width: 100px; background: #00f; height: 180px; margin-left: -100px; } .right { display: inline-block; vertical-align: top; width: 150px; background: #0f0; height: 200px; margin-right: -150px; } .center { display: inline-block; vertical-align: top; background: #B373DA; height: 150px; min-width: 150px; width: 100%; } </style> </head> <body> <div class="wrap"> <div class="left">left,宽度高度固定</div> <div class="center">center,能够自适应浏览器宽度,高度固定。</div> <div class="right">right,宽度高度固定</div> </div> </body> </html>
这里也没什么好说的,用到的也是width:auto和width:100%这两点,简单知识点的简单用法。
双飞的话,代码跟圣杯的基本相同,注意在html的顺序变为center>right>left,只改左栏移动的margin-left: calc(-100% - 100px)到预约位置便可。不能用calc的话能够在center里面再加一层,跟浮动同样的处理方式。更简单的方法是使用CSS3带给咱们的box-sizing属性。请看代码:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>宽度自适应布局</title> <style> .wrap { background-color: #FBD570; font-size: 0; letter-spacing: -4px; /*用于兼容safari,根据不一样字体字号或许须要作必定的调整*/ margin-right: 150px; } .wrap * { font-size: 1rem; letter-spacing: normal; } .left { display: inline-block; vertical-align: top; width: 100px; background: #00f; height: 180px; margin-left: -100%; } .right { display: inline-block; vertical-align: top; width: 150px; background: #0f0; height: 200px; margin-right: -150px; } .center { display: inline-block; vertical-align: top; background: #B373DA; height: 150px; min-width: 150px; width: 100%; box-sizing: border-box; padding-left: 100px; background-origin: content-box; background-clip: content-box; } </style> </head> <body> <div class="wrap"> <div class="center"> center,能够自适应浏览器宽度,高度固定。 </div> <div class="right">right,宽度高度固定</div> <div class="left">left,宽度高度固定</div> </div> </body> </html>
总结:相比浮动inline-block更加容易理解,也更符合咱们的认知,结合盒子模型的几个控制属性就能够进行布局了。对于元素高度不一样的状况,目前浮动布局的作法都是将元素作成等高元素进行展示,这从美学上看也符合整齐的要求,不过牺牲了一部份内容。但inline-block有vertical-align属性,能够很好地解决元素高度不一样而带来的布局问题。用过以后,你也会喜欢上inline-block的。。。至少我会!
绝对定位
前面的浮动和普通流中其实定位都是靠盒子模型控制的,与咱们常说的定位仍是有差异的。而绝对定位就是咱们日常所说的定位,给定参考坐标系+坐标肯定位置。关于绝对定位的资料太多,我就不说了。提一点就是absolute定位的基准是最近的非static定位父对象,而fixed是相对html根节点的定位。两种定位都会脱离普通流,跟以前说的浮动同样,上天了。
固然,他们跟浮动在空间中的位置仍是有差异的,项目中有遇到这个问题的请参考张大婶的文章: http://www.zhangxinxu.com/wordpress/2016/01/understand-css-stacking-context-order-z-index/ 仍是要结合项目来看,不然看过也只是看过而已,并不会存到你的脑子里,毕竟仍是至关抽象至关理论性的东西。借用张大神的一个总结图:
使用绝对定位(特指absolute)作自适应布局跟前面两种方式没太大差异,宽度自适应仍是在auto和100%上作文章,而位置则由top/bottom/left/right等控制。仍是以圣杯布局来举例:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>宽度自适应布局</title> <style> .wrap { position: relative; background-color: #FBD570; margin-left: 100px; margin-right: 150px; height: 250px; } .left { position: absolute; top: 0; left: -100px; width: 100px; background: #00f; height: 180px; } .right { position: absolute; top: 0; right: 0; width: 150px; background: #0f0; height: 200px; margin-right: -150px; } .center { position: absolute; top: 0; left: 0; background: #B373DA; height: 150px; min-width: 150px; width: 100%; } </style> </head> <body> <div class="wrap"> <div class="center"> center,能够自适应浏览器宽度,高度固定。 </div> <div class="left">left,宽度高度固定</div> <div class="right">right,宽度高度固定</div> </div> </body> </html>
父元素为relative,子元素为absolute,这样的话,又会出现跟浮动同样的问题:父对象高度坍塌,子元素不能撑起父对象。缘由也跟浮动同样,解决办法的话目前我知道的只有给父对象指定一个肯定height值,你们若是有更好的办法,请联系我!
总结:单纯使用绝对定位进行自适应布局的状况不多,通常绝对定位都用在尺寸固定的元素定位上。并且fixed定位的渲染效率很低,由于它会频繁触发浏览器的重排。另外提一点:CSS3的transform会对绝对定位产生影响哦~好比说让fixed定位再也不固定在浏览器视窗的黑魔法:http://www.zhangxinxu.com/wordpress/2015/05/css3-transform-affect/
弹性盒子
CSS3中对布局影响最大的莫过于弹性盒子模块了,这是一套区别于以往盒子模型布局的全新方案。上面几种方法你能够看到,为了实现自适应咱们用的都是width:auto和100%的嵌套以及各类边距的移动定位,这套规则并不符合咱们的认知。为何不能开拓出一块区域,横竖排列均可以,内部全部元素的尺寸能够按照一个规则和这个区域的大小联系起来?终于CSS3作出了改变,引入了flex弹性布局方案,弹性盒布局有以下优点:
1.独立的高度控制与对齐。
2.独立的元素顺序。
3.指定元素之间的关系。
4.灵活的尺寸与对齐方式。
在MDN上有很是简单易懂的基础教程:https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_Flexible_Box_Layout/Using_CSS_flexible_boxes
上面也已经给出了圣杯布局的自适应布局方案,因此代码就不贴了不过这个例子实现的是3栏成比例缩放,左右栏若是须要固定值的话能够写成 flex: 0 0 150px; 的样式。
可是上面的教程没有给出各个属性的详细解释,建议看看阮一峰的博文,详细易懂并且配图超漂亮的有木有:http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html
总结:弹性盒子在移动端的应用会愈来愈广泛,这套模型值得去好好研究。语法规则都是很是贴近人性,很是灵活,浏览器兼容性也很是好,固然国内百花齐放的移动浏览器会有哪些大坑呢?咱们拭目以待~
其余
其余包括position:relative和CSS3中的transform均可以实现定位,可是因为他们在原来的普通流中还占着一个坑,因此不多用来布局啥的。transform是个很酷炫的东西,能够用平面的素材作出不少3D的效果,并且不须要js就能够作,很是好玩。此文已经很长,就很少说了,之后会写一篇文章来专门说说她的故事。
总结以上!文字太多,放个图片来调和下~~~以为不错的同窗,请点赞!以为错了的同窗,请联系我!
(图片出处:著名摄影师 小杨同窗,转载请注明)
原创文章,转载请注明出处!本文连接:http://www.cnblogs.com/qieguo/p/5421252.html