zoukankan      html  css  js  c++  java
  • 《CSS Mastery》读书笔记(3)

    第三章 可视化格式模型

    三个最重要的CSS概念需要掌握,浮动floating,定位positioning, 框模型(有些书翻译成盒子模型)box model。 这些概念控制了元素在页面中的安放和显示。 形成了CSS布局的基本。 需要经过一段时间才能掌握盒子模型的复杂性, 绝对定位和相对定位的区别, 还有浮动和清除怎样工作,一旦掌握以上内容,用CSS开发网站就会变得简单。

    本章会学习:

    • The intricacies and peculiarities of the box model
    • How and why margins collapse
    • The difference between absolute and relative positioning
    • How floating and clearing work

    ==盒子模型回顾==

    image_thumb11[1]

    padding出现在content Area周围, 如果你对一个元素添加背景, 它会填充到content Area和padding所形成的区域, Padding本身用于在内容周围内容周围建立一个槽,以致内容不会紧靠背景的边界。 而border是content area和padding区域外的一条线, 这个线有不同样式, 比如实线,点状线,短划线, border之外是margin, margin是透明不可见的,它被用来控制元素之间的空间。

    CSS2.1也包含outline属性, 不想border属性, outline属性在元素盒子模型的顶部,它不影响元素的大小和位置。 IE8以上的现代浏览器才支持。

    padding, border,margin 都是可选的,默认宽度值为零, 但是很多用户代理样式表会给出特定值, 你可以覆盖这些浏览器属性,把这些元素的margin和padding设置回零, 可以分别设置也可以用通用选择器进行设置:

    * {
    margin: 0;
    padding: 0;
    }

    在CSS中, width和height指的是内容区域的宽度和高度, 增加padding, border, margin不会影响内容区域的尺寸。但是会增加一个元素盒子模型的总体尺寸。

    #myBox {
    margin: 10px;
    padding: 5px;
    70px;
    }

    image_thumb4

    padding, margin, border 可以被应用到一个元素的所有边, 也可以被应用到单独的边, margin可以使负值,并在多种技术中使用。

    IE和盒子模型

    不幸的是,老版本的浏览器,包括IE6的quirks mode (兼容模式)下,使用它们自己的不标准的盒子模型, 除了测量content内容的宽度,这些浏览器把width的值计算成 content ,两边padding和 两边border尺寸 相加后的和,这样做也说得通, 在现实世界中, 盒子具有固定尺寸, padding在盒子里面, 增加更多的padding, 就会给content更少的空间, 然而, 虽然逻辑上可以说的过去,但是这些版本的IE不按照标准会导致严重问题。 例如, 前面例子中盒子的总宽度将是90pixel 在IE5.X中, 因为IE5.X认为两边5 pixel 的padding是70 pixel 宽度width的一部分,而不是要加上去

    image_thumb7

    第9章将会看到解决这个问题的方法, 更彻底的解决办法是部位元素本身添加padding, 而是为元素的父元素或子元素添加padding和margin。

    空白(margin )叠加(collapsing)

    margin collapsing 概念比较简单, 但是它能导致很多混淆, 当你布局一个网页, 简单来说, 当有两个或多个垂直的margin相遇, 他们将形成一个空白边, 这个空白边的高度等于两个发生叠加的空白边高度中的较大者。

    当两个元素叠加, 第一个元素的底部空白与第二个元素的顶部空白边发生叠加。

    image_thumb10

    当一个元素被另一个元素所包含, 假如没有padding和border分隔两个空白,那么顶部和底部的margin也会发生叠加。

    image_thumb13

    尽管初看上去有点奇怪, 但是一个元素本身的上下空白margin也会发生叠加, 假如一个空元素, 他有margin,但是没有padding和border, 这种情况下,顶部空白和底部空白就碰到一起, 他们会发生叠加。

    image_thumb15

    如果这个margin碰到另一个元素的margin,他也会发生叠加。image_thumb20

    margin collapsing只是在普通文档流中盒子框的垂直空白边上才会发生, 行内框,浮动框, 或绝对定位框之间的空白边不会叠加。

    ==定位回顾==

    现在你已经对盒子模型很熟悉,那么再看一下视觉格式模型和定位模型, 理解这两个模型的差异很重要,它们一起决定了元素再页面上的安置。

    视觉格式模型

    人们称p, h1, div  等元素为块级元素。 着意味着它们是视觉表现为一块的内容, 相反, strong 和span等元素,成为行内inline元素, 因为它们的内容被表现为行内框。

    通过display属性, 可以改变盒子的类型。 这意味着,通过设置display属性为block,你能够把一个行内元素,比如anchor 表现得像块级元素, 也可以通过设置display属性为none, 使得一个元素表现不出“盒子”的特征。而且这个“盒子”和它里面的内容,也不会显示, 不占用文档里的空间。

    CSS定位机制有三种, 普通流, 浮动, 绝对定位。 除非专门指定, 否则所有框在普通流里都有定位, 就如名称所示, 元素盒子在普通流里的位置, 由它在文档中的位置决定。

    块级盒子垂直一个接一个排列, 块级盒子之间的距离由盒子的垂直空白(margin)计算所得(上文介绍过)。

    行内盒子在一行中水平排列, 他们水平间距, 可以通过水平padding, boder, 和margin来调节, 但是,垂直padding,border,margin并不影响行内盒子的高度, 相似的,显式设定一个行内盒子的高height和宽width是无效的,由一行形成的水平盒子成为line box, 一个line box总是足够高,以容纳所有里面的line box, 这里有另一个警示, 设定line height可以增加这个盒子的height。 因为这些原因, 改变i一个inline box的尺寸唯一的方法,是改变line height, 水平 border, padding, margin。 (这段有点拗口,希望能解释清楚,中译本有删节,意思偏离原著)。

    image

    Helpfully, CSS2.1 allows you to set the display property of an element to be inline-block. As
    the name suggests, this declaration makes the element line up horizontally as if it were an inline
    element.
    However, the contents of the box behave as though the box were a block-level,
    including being able to explicitly set widths, heights, vertical margins, and padding. Historically,
    this property has been poorly supported
    ; hence, it’s relative obscurity. Thankfully, inline-block is
    now supported by Firefox 3.0 and above, IE 8, and the latest versions of Safari and Opera, so I
    think we are going to see inline-block being used to create more interesting layouts over the
    next few years.

    盒子可以嵌套其他盒子, 大部分盒子由显式定义的元素形成, 然而, 有种情况是块级元素再没有显式定义的情况下被创建---当你在块级元素,像div的开头添加一些文字的时候, 虽然你没有定义文字为块级元素,它也被当成是。 (这里中译版,翻译错误,译者凭想象,真是“厉害”)

    <div>
    some text
    <p>Some more text</p>
    </div>

    在这种情况下, 盒子被描述成匿名块, 因为它并不和一个特定的元素相关联。

    一个相似的事情, 就是在块级元素内部有几行文字, 假如有个段落包含三行文字,每行文字形成一个匿名块, 你不能直接样式化匿名块或line box ,除了使用:first-line伪类, 显然作用有限, 然而理解所有你在屏幕中看到的东西都形成了某种盒子是很有帮助的。

    相对定位

    相对定位很容易掌握, 如果你要相对定位一个元素, 它就会呆在它所在的地方。然后设定它的垂直,水平位置, 来相对于起始点来移动这个元素。如果设定top 为20 pixels, 那么盒子就会在原点下方20pixels, 设定left 为20 pixels, 就会在左边出现20 pixels的空间,把元素移向右边。

    #myBox {
    position: relative;
    left: 20px;
    top: 20px;
    }

    image

    相对定位时,盒子元素继续占有原来的空间,导致位移之后的元素和其他盒子产生重叠。

    绝对定位

    相对定位实际上被认为是普通文档流模型的组成部分, 因为元素的定位相对于它在普通文档流中的定位。相反,绝对定位把元素从文档流中取出, 这样就不占据空间, 文档流中其他元素的布局就像绝对定位元素不存在一般。

    image

    绝对定位元素的位置相对于其关系最近的已定位父元素。 如果这个元素没有已定位的父元素,它将相对于初始包含块来定位。根据用户代理不同, 这将会是画布Canvas或HTML元素。

    正如相对定位盒子一般, 绝对定位的盒子可以从top, bottom, left, right相对于包含块位移, 这个给你充分灵活性, 你可以几乎在页面任何地方定位。

    因为绝对定位盒子从文档流中取出, 它们可以和页面其他元素产生重叠, 因此你可以通过设定z-index控制重叠顺序, z-index的值越高,盒子在重叠中的层次也越高。

    因为绝对定位元素已经从文档流排除。 它们对普通文档流中的元素不会有影响, 如果你想要扩大绝对定位盒子--例如通过增加font size, 周围的盒子不会重新定位, 这样任何尺寸的变化将破坏已经调整好的布局, 使得绝对定位的盒子重叠。

    固定定位 fixed positioning

    固定定位是绝对定位的一个子类别, 不同的是固定定位的包含块是视口。 这就可以使你创建总是出现在窗口中相同位置的浮动元素,这种情况的一个示例是下图, 博客评论表单采用固定定位, 这使得它在页面滚动时一直出现在屏幕上的相同位置, 这有助于改进易用性, 用户不必为了发表评论而滚动到页面底部 。

    image

    遗憾的是IE6 以及更低版本不支持固定定位, IE7部分支持,实现起来比较古怪, 要回避这个问题, 使用javascript来替换这个效果。

    ==浮动==

    最后视觉格式模型是浮动模型, 一个浮动的盒子可以移动到左边或右边直到它接触包含盒子的边界。或另一个浮动的盒子。 因为浮动盒子不在普通文档流中, 在普通文档流中的盒子块表现得就像浮动盒子不存在。

    如下图,当把盒子1向右浮动时,它脱离文档流并且向右移动, 直到它的右边缘碰到了包含框的右边缘。

    image

    再如下图, 当你把盒子1向左浮动,它脱离文档流向左移动, 知道左边缘碰到包含框的左边缘。 因为它已经不在文档流,不占空间,实际上它位于box2 的上面,把它给遮蔽了(obscuring it from the view), 如果你把三个盒子都向左浮动,box1会左移然后碰到包含框停下,其他的盒子都一块左移,直到碰到之前的浮动盒子。

    image

    如果包含框太窄不能水平容纳全部浮动元素, 剩下浮动元素会排到下面找位置直到有足够的空间。 如果浮动元素有不同的高度,浮动元素可能会在走下去找位置的时候被卡住。

    image

    Line box (行框) 和 clearing

    之前说过浮动一个元素后,它就被取出普通文档流,从而对不浮动的元素不再起作用。可是不是完全对,不浮动的盒子里如果有文字内容,那么文字内容还保留着浮动元素的记忆,会给浮动盒子留出空间。 用技术语言来讲, 浮动盒子 旁边的 line box 行框被缩短,给浮动元素留出空间,这样就包围住浮动盒子。事实上,浮动就是为文字绕着图像排列而生的。

     image

    要阻止line box 绕着浮动盒子的周围, 你要给line box元素应用clear属性, clear属性的值可以是left, right, both或 none, 它表示box的哪些边不应挨着浮动盒子。 为了实现这样的效果, 浏览器在被清理元素的顶部添加足够的margin, 而将元素往下压,直到顶边过了浮动元素。

    image

    就像你看到的, 浮动元素从文档流取出后,对周围元素不影响, 但是对元素进行清理实际上为前面的浮动元素留出了垂直空间。

    这是个有用的布局工具, 它让周围的元素为浮动元素留出空间。 解决了前面绝对定位的问题, 也就是垂直高度的改变不影响周围元素, 从而破坏了设计。

    现在在来看看浮动和清理的细节, 你想把一幅图片浮动到一堆文字左边, 你想它们都包含在另一个有背景和边的元素里。 你可能要尝试下这样。

    .news {
    background-color: gray;
    border: solid 1px black;
    }
    .news img {
    float: left;
    }

    .news p {
    float: right;
    }

    image

    然而,因为浮动元素从文档流取出,容器div没有空间被占用,如何让容器元素视觉上包围浮动元素呢?这就需要在这个元素中的某个地方应用clear。 不幸的是没有现存的元素去应用clear, 你可以加个空元素在最后的段落, 去clear。

    .news {
    background-color: gray;
    border: solid 1px black;
    }


    .news img {
    float: left;
    }

    .news p {
    float: right;
    }


    .clear {
    clear: both;
    }

    <div class="news">
    <img src="/img/news-pic.jpg" alt="my pic" />
    <p>Some text</p>
    <br class="clear" />
    </div>

    这个就得到了我们想要的效果, 但是代价是添加了多余的代码, 通常会有现存的元素可以应用clear, 但是有时你可以为了布局而不得不添加无意义的标记。

    还可以不对浮动的文本和图像进行清理, 而是选择对容器div进行浮动。

    .news img {
    float: left;
    }
    .news p {
    float: right;
    }

    <div class="news">
    <img src="/img/news-pic.jpg" alt="my pic" />
    <p>Some text</p>
    </div>

    这就得到了想要的结果, 不幸的是,下一个元素现在将要被浮动所影响, 要解决这个问题, 有人选择再布局里浮动几乎所有元素,然后用合适的有意义的元素clear这些浮动, 通常是在站点的footer, 这可以帮助减少多余标记。 但是浮动可以很复杂, 古老的浏览器可能会噎住, 这样,很多人还是倾向于增加多余的标记。

    overflow属性定义一个元素支持什么样的行为,如果内容太大,超出范围, 默认内容会溢出盒子,跑到隔壁的空间, overflow的值设置为hidden或auto的一个有用的副作用是它将自动clear任何包含的浮动元素。 这个是一个有用的方式清除一个元素而不增加多余的标记。 这个方法在很多情况下不合适, 因为设这盒子的overflow属性会影响它的行为。 更特别的是, 这个方法在某些情况下可以强制scroll bars 或clip内容。

    有些人使用css生成内容或javascript对浮动元素进行清理, 这两种方法的基本概念相同。并不直接向标记中添加进行清理的元素, 而是将它动态添加到页面在中, 对于这两种方法,需要制定进行清理的元素应该出现在哪里, 而且常常要添加一个类名。

    <div class="news clear">
    <img src="/img/news-pic.jpg" alt="my pic" />
    <p Some text</p>
    </div>

    使用css方法时,结合使用 :after伪类和内容声明,在指定的现有内容末尾添加新的内容, 在这个示例中,我添加了一个句点,因为它是非常小和不显眼的字符, 不希望新内容占用任何垂直空间何在页面上显示, 你需要将height设置成0, 将visibility设置成hidden。 因为被清理的元素在他们的顶空白边添加了空间,所以生成的内容需要将它的display property设置成block。

    这样设置后就会对生成的内容进行清理。

    .clear:after {
    content: ".";
    height: 0;
    visibility: hidden;
    display: block;
    clear: both;
    }

    这个方法在大多数现代浏览器中是有效的, 但是在IE6和更低版本中不起作用, 有各种解决方法,有很多收录在 www.positioniseverything.net/easyclearing.html. 最常用的设计使用 Holly Hack (见第8章) 从而迫使IE5-6应用布局 (见第9章) 和不正确的清理浮动.

    .clear {
    display: inline-block;
    }
    /* Holly Hack Targets IE Win only */
    * html .clear {height: 1%;}
    .clear {display: block;}
    /* End Holly Hack */

    但是由于其复杂性,这个方法不适合大部分人使用

    An explanation of the JavaScript method is beyond the scope of this book but is worth a brief
    mention. Unlike the previous method, the JavaScript method works on all major browsers when
    scripting is turned on. However, if you use this method, you need to make sure that the content is
    still readable when scripting is turned off.

  • 相关阅读:
    每日一题_191208
    每日一题_191207
    每日一题_191206
    每日一题_191205
    每日一题_191204
    每日一题_191203
    每日一题_191202
    每日一题_191201
    每日一题_191130
    2020届成都一诊理科16题
  • 原文地址:https://www.cnblogs.com/grkin/p/3537869.html
Copyright © 2011-2022 走看看