本文是CSS核心内容整理的第二篇,承接上一篇的内容继续对CSS的一些重要内容进行整理,推荐先看完这个系列的上一篇.html
布局能够说是我认为CSS中最重要的东西,CSS自己是个奇怪的东西一直以来有点游离于Coder和非Coder之间的感受.自己没有严谨的逻辑,并且有不少奇怪的"习惯",这些在布局中都有所体现.git
1. 基本布局概念浏览器
在布局上高度的用处在于细节和内容,总体是由宽度决定的.并发
首先从多栏布局开始划分,基本上有3种实现方案:固定宽度、流动、弹性.
框架
固定宽度:
ide
固定宽度的含义我就不解释了,我记得我几年前上大学的时候就有很流行的960Grid布局框架,一般固定布局的大小事900到1100,经常使用的是960由于基本上全部显示器都知足,同时960能够被16,12,10,8,6,5,4整除,易于分栏.
布局
流动布局:
测试
大小会随用户调整浏览器窗口大小而变化.当页面宽度变化的时候,文本和元素间的位置均可能变化.强调一下,有些童鞋觉得流动布局就是响应式设计,这是不同的.经过CSS媒体查询,适应各类宽度的可变固定布局才叫响应式设计,这和流动布局是不同的.
网站
弹性布局:
this
估计见过的人很少,效果比较相似于浏览器的放大和缩放功能,好比当浏览器窗口变宽了,那么里面的全部元素都按照必定比例大小变化.这个因为过于复杂,因此实际应用的例子很少.
2. 宽高是彻底不同的
在本文的上一篇中我简述了盒模型中宽高的影响,在布局中它们各自的状况很是不同.
布局高度:
正常状况下,咱们不该该给任何元素设定高度,除非你要建立的是一个绝对定位的元素.只有不设定的固定高度,元素才能随本身包含内容的增长减小而在垂直方向上扩展或搜索.设定了一个固定高度,那么超出的内容要么跑到容器以外,要么被减掉,由overflow属性决定.
布局宽度:
对于宽度咱们是近乎和高度相反的态度,应该精细的控制宽度,从而让内容自动扩展到填满栏的宽度.
3. 固定宽度的三栏布局
首先要认可即便不考虑兼容的状况下,CSS依然是一个复杂的东西.其中的一些基础很重要,它的一些表现和属性支撑了所有的应用.拿出一个固定宽度分三栏的小Demo,请不要轻视它,它没你想的那么Easy.
先上demo代码,稍微有点长但简单,浏览一遍便可:
代码过长-挂在OSC@Git上-点击查看-固定宽度的三栏布局.html
最好将代码copy下到浏览器中看一下效果,这里不是为了说明150+600+210=960的问题.而是为了说布局中各因素的影响.一点点来:
上面的代码中,article里面的内容太多紧凑,因此打算加入padding这样的内边距,好比padding:10px 20px;可是加入后能够发现,三栏的位置窜了,aside被挤下来了.在本系列的上篇中提到过,固定宽度的盒子为它加padding或者margin会致使盒子元素变宽.这里由于article变宽从而没有aside的位置,它就只会放到下一行.
怎么解决?
(1) 从新设置宽度,在原有基础上减去padding和margin.这样作很差的地方就是若是之后要调整padding或者margin的值会很是"危险".
(2) 给容器内部应用的元素添加padding.
按照盒模型,没有设置宽度的元素在水平方向上回适应其父元素,内容会随着margin,border,padding增长而减小.这么一来风险就是之后可能要调整内部元素的padding或者margin时,有牵一发而动全身的可能.一个解决方式是在容器和应用元素之间再加一层没有宽度的div,这个div上加入padding或者margin.这样就不会产生很差的影响.
固然这么作确实是将标记用于表现用途了,没有使用纯粹的CSS.关于这一点,请往下看:
关于表现性标记的思考
HTML 的目的是语义,也就是给内容赋予含义。而 CSS 呢,是为了把表现性的样式分离出来才发明的。不过,有些表现性标记是有害的,而有些则没有反作用。使用表格来建立多栏布局,或者使用<br />标签在段间换行,却不使用<p>标签,这种作法的确不值得提倡,由于这会形成内容难以移植。好比说吧,用三个表格单元做为三栏,这种布局到哪都会显示成表格,就算是在彻底不合适的智能手机里也同样。若是表现性标记没法用 CSS 修改,或者在 CSS 不可用时也要迫使用户接受,那就是滥用 HTML。但是,div 或 span 这种中性的元素,对默认样式没有影响,除非你给它们应用样式,不然它们就跟不存在同样。因此,我认为添加这种元素达到表现性的目的是彻底能够接受的。
这里我插一句,若是对backbone有了解或者使用的童鞋会发现View的时间其实就绑定在一个新建立的空白Div上,也就是this.$el.不少优秀的库其实也是把div做为一个DOM空白载体去用,由于默认状况下它不会对页面产生影响.
(3) 使用CSS3的box-sizing:border-box
不少同窗对这个属性不熟悉,可能由于平时要考虑各类浏览器的兼容因此对于CSS3干脆就不予选择.这里对此不做评论,不过CSS3确实有不少方便的好东西.这里只要给3个浮动的栏分别加上box-sizing:border-box这个属性,再给栏添加padding或者border就不会致使盒子宽度变化了,内容会向内收缩.
预防过大的元素
设计一个未来可能由他人维护的动态网站时,须要考虑得更长远一些。好比,应该预见到可能出现一些过大的元素。若是未来有一张比浮动栏更宽的图片被放到栏中,就会致使布局变宽,而右边的栏又会滑到下方。为此,一个简单的预防措施就是添加一条.inner img {max-width:100%;}声明,以便限制图片的宽度不超过其父元素(在此就是内部div)。 另外一个办法是给每一个栏(或者内部div,若是你用了的话)添加overflow:hidden声明。这条声明不会缩小图片以适应父元素,而会将它(以及任何过大元素)超出容器边界的部分剪切掉。
动态网站中另外一个潜在的问题是换行。HTML 只会在单词间空格的地方换行。一些长 URL,甚至一些长单词,在栏比较窄的状况下,都会致使栏宽过大。所以,还应该给全部栏的外包装元素应用 word-wrap:break-word 声明,以便全部栏及其内容继承这个设定。有了这条声明,浏览器会把过长的词断开显示在不一样行上。只是word-wrap没有定义在哪里断开,所以结果彻底是随机的,并且没有连字符。不过,这条规则只在须要时才会起做用,并且能保护布局不会被长 URL 顶得支离破碎。建议你在每一栏中都用长 URL、大图片,以及包含内容过多的元素测试一下布局,看看这些声明到底会不会起做用,并发现更多须要事先考虑保护措施的其余 漏洞。
4. 中栏流动的三栏布局
在流动布局中,若是想要实现中栏流动,一般有两种方式.第一是在中栏大小变化时,使用负的margin定位右边栏.另外一种是用CSS3让栏容器具备相似表格单元的行为(这种方式在现代浏览器中应用很是之多!).
(1) margin-right:-210px
好吧,可能到这里你还不知道我在说什么,因此直接看代码吧~贴到页面上运行一下看看效果:
代码过长-挂在OSC@Git上-点击查看-中栏流动的三栏布局.html
代码有点长,占用了太多的篇幅~原本想外链的Github上又以为没什么必要~题外话了.
若是运行了代码,大概能够看明白这是要实现什么效果了.三栏中,左栏和右栏的宽度固定,中栏大小适应于浏览器窗口.上面代码是经过负的margin-right实现的,根据代码阐述一下道理.
三栏布局而且实现中栏宽度不固定,最核心的问题就是右边栏的定位,以及控制中栏大小变化时右边栏与布局的关系.
上面代码实现的核心,就是控制两个三栏以外的Div容器,一个包住所有的三栏,另外一个只包住左栏和中栏.让这两个div都强制它们float:left;同时宽度width:100%;包住左栏和中栏的Div咱们额外给它一个margin-right:-210px;210px就是右边栏的宽度.同时给被它包住的中栏加一个margin-right:210px;
为了给右栏腾出210px的宽度,中栏article有一个margin-right:210px;可是只有这个只会把右边栏再向右推210px.此时包裹住中栏和左栏的DIv上有210px的负右外边距,这就会把右栏拉回article元素右外边距所创造的空间内.中栏的宽度不固定为auto,因此它仍会努力的占据左栏剩余的空间.可是本身的margin它会留下来,这样就巧妙的留出来右侧的210px宽度.
上面两段话有点绕嘴,但确是这种布局的精华,也算上本文的一大重点,能够多读几回,这是一种CSS设计中颇有用的技巧.
(2) display:table-cell
table是一种很古老的布局方式,能够说若是如今你还在使用table的特性进行布局和表现样式,那你必定out过久了.使用table布局是难以接受的,不过若是经过CSS使布局有table的特性却很是好了.
经过将display的属性设为table,table-row,table-cell这种方式能够模拟table的行为.
若是将上面的三栏设置为display:table-cell有不少好处:首先不用设置浮动就能够并列显示了,同时内边距也不会破坏布局了,一行中的全部单元格高度所有统一了,任何没有明确设定宽度的栏都浮动了.能够说若是不考虑低版本浏览器支持的问题,我认为这是一个完美的解决方案,强烈推荐.
这里将上面的代码中包裹两栏或者三栏的div所有清除,同时去掉全部float:left;为每一个栏加上display:table-cell.而后将左栏和右栏设置固定宽度,中栏width:auto;看看效果吗,太简单,太干净了不是吗?这个方案第一次看到的时候让我激动了,真的!我对于布局一直很纠结,新的旧的,float仍是position.然而这种布局干净而简单,很是推崇!