CSS核心内容整理 - (中)

    本文是CSS核心内容整理的第二篇,承接上一篇的内容继续对CSS的一些重要内容进行整理,推荐先看完这个系列的上一篇.

四.  页面布局

    布局可以说是我认为CSS中最重要的东西,CSS本身是个奇怪的东西一直以来有点游离于Coder和非Coder之间的感觉.本身没有严谨的逻辑,而且有很多奇怪的"习惯",这些在布局中都有所体现.

  1. 基本布局概念

    在布局上高度的用处在于细节和内容,整体是由宽度决定的.

    首先从多栏布局开始划分,基本上有3种实现方案:固定宽度流动、弹性.

    固定宽度:

        固定宽度的含义我就不解释了,我记得我几年前上大学的时候就有很流行的960Grid布局框架,通常固定布局的大小事900到1100,常用的是960因为基本上所有显示器都满足,同时960可以被16,12,10,8,6,5,4整除,易于分栏.

    流动布局:

        大小会随用户调整浏览器窗口大小而变化.当页面宽度变化的时候,文本和元素间的位置都可能变化.强调一下,有些童鞋以为流动布局就是响应式设计,这是不一样的.通过CSS媒体查询,适应各种宽度的可变固定布局才叫响应式设计,这和流动布局是不一样的.

    弹性布局:

        估计见过的人不多,效果比较类似于浏览器的放大和缩放功能,比如当浏览器窗口变宽了,那么里面的所有元素都按照一定比例大小变化.这个由于过于复杂,所以实际应用的例子不多.

  2. 宽高是完全不一样的

    在本文的上一篇中我简述了盒模型中宽高的影响,在布局中它们各自的情况非常不一样.

    布局高度:

        正常情况下,我们不应该给任何元素设定高度,除非你要创建的是一个绝对定位的元素.只有不设定的固定高度,元素才能随自己包含内容的增加减少而在垂直方向上扩展或搜索.设定了一个固定高度,那么超出的内容要么跑到容器之外,要么被减掉,由overflow属性决定.

    布局宽度:

        对于宽度我们是近乎和高度相反的态度,应该精细的控制宽度,从而让内容自动扩展到填满栏的宽度.

  3. 固定宽度的三栏布局

    首先要承认即使不考虑兼容的情况下,CSS依然是一个复杂的东西.其中的一些基础很重要,它的一些表现和属性支撑了全部的应用.拿出一个固定宽度分三栏的小Demo,请不要轻视它,它没你想的那么Easy.

    先上demo代码,稍微有点长但简单,浏览一遍即可:

    代码过长-挂在OSC@Git上-点击查看-固定宽度的三栏布局.html

231415_FMaX_723632.jpg

    最好将代码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

    231544_swAA_723632.jpg

    代码有点长,占用了太多的篇幅~本来想外链的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.然而这种布局干净而简单,非常推崇!

转载于:https://my.oschina.net/blogshi/blog/224919

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值