zoukankan      html  css  js  c++  java
  • CSS基础:块级元素与盒模型

    简介

      在 HTML4.01 中,元素通常可以分为块级元素( "Block-level element" ) 和内联元素 ( "Inline-level element" ) 两大类。块级元素单独占一行显示,内部可以包含内联元素或其他块级元素;内联元素不换行,内部只能包含其他内联元素,在这篇文章中将只讨论块级元素。

    (:在 HTML5 中并没有块级元素和内联元素的概念,而是通过内容模型( "Content model" )规定了每个元素的分类( "Content categories" )和允许包含的内容( "Permitted content" ),例如:<a> 标签在 HTML4.01 中是内联元素,理论上不能嵌套诸如 <div> 之类的块级元素,但是在 HTML5 中判断是否合法要稍微复杂一点: <a> 标签的分类可能属于流元素( "Flow content" )或短语元素( "Phrasing content" ),交互元素( "Interactive content" ),可触元素( "palpable content" )中的一种或多种,具体情况要根据上下文而定,允许包含的内容是 "transparent",意为透明的,也就是说既可以包含 "Flow content" 又可以包含 "Phrasing content" ,根据父元素决定,如果单独像 "a > div" 这样嵌套,由于 <div> 标签的分类属于 "Flow content",因此这里是合法的,如果像 "p > ins > a > div" 这样嵌套,"a > div" 是否合法要看 "ins > div" 是否合法,由于 <ins> 允许包含的内容也是 "transparent",所以再看 "p > div" 是否合法,由于 <p> 允许包含的内容只能是 "Phrasing content",所以总的来说这里是不合法的)

      还需要注意的是:块级元素和 CSS 中 { display: block; } 的元素不是一个概念,例如,<li> 元素默认的 display 值为 list-item,<table> 元素默认的 display 值为 table ,但是它们都是块级元素,具有块级元素的基本特征,在同一个水平流上只能显示一个元素。

      块级元素总是被表示为一个矩形的盒子,称为 "盒模型",由 "外边距+边框+内边距+盒子本身宽高" 组成,如图所示:

    "盒子本身宽高" 规定的部分称为内容区域 "Content box",在 CSS 中设置的 "width" 和 "height" 就是作用于这个区域;

    "盒子本身宽高+内边距" 规定的部分称为内边距区域 "Padding box",在 CSS 中设置的 "background" 就是作用于这个区域;

    "盒子本身宽高+内边距+边框" 规定的部分称为边框区域 "Border box";

    "盒子本身宽高+内边距+边框+外边距" 规定的部分称为外边距区域 "Margin box";

    利用 CSS3 的 "border-sizing" 属性可以更改 "width" 和 "height" 的作用区域,理论上讲有如下四种情况:

    { box-sizing: content-box; }    /* 默认 */

    { box-sizing: padding-box; }    /* 火狐曾经支持 */

    { box-sizing: border-box; }    /* 全部支持 */

    { box-sizing: margin-box; }    /* 不支持 */

    "border-sizing" 属性被所有现代浏览器支持,IE 家族只有 IE8 以上才支持,并且需要添加各个浏览器的私有前缀。

    块级元素的水平格式化

      具体表现为:正常流中的块级元素其水平部分的总和等于父容器的宽度,也就是说:左外边距+左边框+左内边距+宽度+右内边距+右边框+右外边距 = 父容器的宽度。这条规则主要涉及到 "margin","padding","border","width" 四个属性,其中 "margin" 和 "padding" 的默认值均为0,"border" 的默认值为 "none","width" 的默认值为 "auto",意为补齐,并且只有 "width","margin" 的值可以设置为 "auto",它们又有以下几种特殊情况:(仅讨论水平方向上,"margin" 仅代表 "margin-left" 和 "margin-right")

    "width" 和 "margin" 均固定:这种情况又称为格式化属性过分受限( "overconstrained" ),此时浏览器总会将 "margin-right" 强制为 "auto" 以撑满父容器;
    "width" 值固定,"margin-left" 或 "margin-righ" 只有一侧值固定:浏览器表现为将另一侧 "margin" 的值强制为 "auto" 以撑满父容器;
    "width" 值为 "auto",两侧 "margin" 值固定:浏览器表现为 "width" 撑满父容器除 "margin" 外的剩余宽度;
    "width" 值固定,两侧 "margin" 值为 "auto":浏览器表现为 "margin-right" 和 "margin-left" 平分剩余宽度以撑满父容器,借用这种方法可以使块级元素水平居中;
    "width" 和 "margin" 均为 "auto":浏览器表现为 "width" 撑满父容器,"margin" 为0,并且只要 "width" 设置为 "auto",无论是 "margin-left" 还是 "margin-right" 被设置为 "auto",它们最后都会变成0;

    根据这一准则,以及创造者背后的意图,我们应该少设置盒子的宽度,避免其丢失流动性。

    块级元素的垂直格式化

      具体表现为:块级元素的高度会尽可能小,直到可以包裹其中的内容,或者也可以理解为块级元素的高度由它的内容撑开。在垂直方向上,不但 "height" 的表现与 "width" 有区别,垂直方向的 "margin" 设置为 "auto" 时与水平方向的 "margin" 也不同,它将自动计算为0,另外垂直方向的 "margin" 会发生合并现象:
    相邻兄弟元素之间上者的 "margin-bottom" 和下者的 "margin-top" 合并,可以通过触发 BFC 或在中间插入一个内联元素阻断,防止合并发生;
    父容器和它的第一个子元素的 "margin-top" 合并,可以通过触发 BFC 或在中间插入一个内联元素阻断,防止合并发生,另外也可以设置父容器的 "border" 或 "padding" 进行阻断,因为它们可以将两者的 "margin" 分开,而子元素的就不行;
    父容器和它的最后一个子元素的 "margin-bottom" 合并,避免方法同上;
    合并的规则是:"正正取最大","负负取最小","正负则相加"。

    同样,根据这一准则,我们应该少设置盒子的高度,也是避免其丢失流动性。总的来说就是:页面元素的宽度由外到内自适应,高度由内到外撑开。

    关于 width 和 height

      上面已经说了,尽量避免将 "width" 和 "height" 的值设置为固定,除此之外,还有一种流动性更好的替代方案,即 "min-width","max-width" 和 "min-height","max-height",并且这四个属性的兼容性非常好,兼容 IE8 以上以及所有现代浏览器,需要注意的是,它们和 "width","height" 之间有一套独立的覆盖规则,与常规的 CSS 优先级无关:
    即使 "width" 设置了 "!important" ,如果它超过了最大宽度,依然会被后者覆盖,或者说截断;
    当 "max-width" 和 "min-width" 冲突时,"min-width" 的权重更大,与优先级无关;

    示例:

    .test {
         100px !important;
        max- 50px; /* 最终结果为50px */
    }
    
    .test {
         100px !important;
    min- 70px; /* 最终结果为70px */ max- 50px; }

    关于 padding

      关于 "padding" 要说的只有两点:一是 "padding" 不能设置为负值,二是无论是水平还是垂直方向,"padding" 的百分比值都是基于父容器的宽度计算的。

    示例:

    <!-- html -->
    <div class="father">
        <div class="son"></div>
    </div>
    
    /* css */
    .father {
         200px;height: 100px;
        background: red;
    }
    .son {
         50px;height: 50px;
        padding: 25%;  /* 最终结果为50px */
        background: green;
    }
    

    关于 border

      "border-color" 有一个很重要的特性,其默认值是 "transparent",但是当设置了 "color" 后,其计算结果为 "color" 设置的颜色,拥有类似特性的属性还有 "outline","box-shadow","text-shadow" 等。

    示例:

    .test {
        border: solid 1px;  /* 边框颜色为红色 */
        color: red;
    }
    

    关于 margin

      和 "padding" 属性一样,"margin" 的百分比值也是基于父容器的宽度计算的,但是 "margin" 的值却可以设置为负值,并且 "-margin" 有着相当大的作用:
    一是处于文档流中的元素,当 "margin-top" 和 "margin-left" 设置为负值时,元素向着对应方向移动;当 "margin-bottom" 和 "margin-right" 设置为负值时,元素本身不动,而是将后面的元素拉过来,这时文档流中堆叠顺序总是遵循默认的后来者居上的原则,也就是说后面的元素会覆盖前面的元素。
    二是处于文档流中的元素,如果先设置了 "position:relative" 和 "z-index" 改变堆叠顺序,那么覆盖规则由 "z-index" 的大小决定。
    三是使用 "position:absolute" 脱离文档流的元素,当 "margin-top" 和 "margin-left" 设置为负值时,元素向着对应方向移动;当 "margin-bottom" 和 "margin-right" 设置为负值时,元素本身不动,对后面的元素也没有影响。
    四是使用 "float" 脱离文档流的元素,如果负 "margin" 的方向与浮动方向相同,那么元素向着对应方向移动;相反,那么元素本身不动,而是将前面或者后面的元素拉过来。
    五是当元素的 "width" 为 "auto" 时,负 "margin" 可以增大元素的宽度,使其超出父容器的宽度。

  • 相关阅读:
    POJ 3977 折半枚举
    [CQOI2007]余数求和 (分块+数学
    NOI P1896 互不侵犯 状压DP
    HDU 5446 Unknown Treasure (卢卡斯+CRT
    宁夏邀请赛F FLOYD
    P1414 又是毕业季II (数学?
    P2051 [AHOI2009]中国象棋 DP
    POJ 2449:Remmarguts' Date(A* + SPFA)
    HDU 6215:Brute Force Sorting(链表+队列)
    HDU 6207:Apple(Java高精度)
  • 原文地址:https://www.cnblogs.com/blog-cxj2017522/p/8745509.html
Copyright © 2011-2022 走看看