最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 从包含块的角度理解元素宽高百分比及边距百分比的计算方式

    正文概述 掘金(CatWatermelon)   2021-01-22   539

    1. 对于包含块的理解?

    一个元素的尺寸和位置经常受其包含块containint block的影响。大多数情况下,包含块就是这个元素最近的祖先块元素的内容区,但也不是总是这样。

    2. 包含块的影响

    在学习如何确定元素包含块之前,先了解一下它的重要性。

    元素的尺寸及位置,常常会受它的包含块所影响。对于一些属性,例如 width, height, padding, margin,绝对定位元素的偏移值 (比如 position 被设置为 absolutefixed),当我们对其赋予百分比值时,这些值的计算值,就是通过元素的包含块计算得来。

    3. 确定包含块

    确定一个元素的包含块的过程完全依赖于这个元素的 position 属性:

    1. 如果 position 属性为 staticrelativesticky,包含块可能由它的最近的祖先块元素(比如说inline-block, block 或 list-item元素)的内容区的边缘组成,也可能会建立格式化上下文(比如说 a table container, flex container, grid container, 或者是 the block container 自身)。

    2. 如果 position 属性为 absolute ,包含块就是由它的最近的 position 的值不是 static (也就是值为fixed, absolute, relativesticky)的祖先元素的内边距区的边缘组成。

    3. 如果 position 属性是 fixed,在连续媒体的情况下(continuous media)包含块是 viewport ,在分页媒体(paged media)下的情况下包含块是分页区域(page area)。

    4. 如果 position 属性是absolute或fixed,包含块也可能是由满足以下条件的最近父级元素的内边距区的边缘组成的:

      1. transformperspective 的值不是 none

      2. will-change 的值是 transformperspective

      3. filter 的值不是 nonewill-change 的值是 filter(只在 Firefox 下生效).

      4. contain 的值是 paint (例如: contain: paint;)

    原文:

    The process for identifying the containing block depends entirely on the value of the element's position property:

    1. If the position property is **static**, **relative**, or sticky, the containing block is formed by the edge of the

      content box

      of the nearest ancestor element that is either a block container (such as an inline-block, block, or list-item element) or establishes a formatting context (such as a table container, flex container, grid container, or the block container itself).

    2. If the position property is **absolute**, the containing block is formed by the edge of the

      padding box

      of the nearest ancestor element that has a position value other than static (fixed, absolute, relative, or sticky).

    3. If the position property is **fixed**, the containing block is established by the viewport (in the case of continuous media) or the page area (in the case of paged media).

    4. If the position property is **absolute** or **fixed**, the containing block may also be formed by the edge of the

      padding box

      of the nearest ancestor element that has the following:

      1. A transform or perspective value other than none

      2. A will-change value of transform or perspective

      3. A filter value other than none or a will-change value of filter (only works on Firefox).

      4. A contain value of paint (e.g. contain: paint;)

    Note: The containing block in which the root element (<html>) resides is a rectangle called the initial containing block. It has the dimensions of the viewport (for continuous media) or the page area (for paged media).

    浏览器视口(viewport)

    从包含块的角度理解元素宽高百分比及边距百分比的计算方式

    通过js代码获取视口大小:

    function getClientSize() {
        var w=window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
        var h=window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
        return {w, h}
    }
    

    4. position值为static、relative、sticky时宽高百分比的计算

    If the position property is static, relative, or sticky, the containing block is formed by the edge of the content box of the nearest ancestor element that is either a block container (such as an inline-block, block, or list-item element) or establishes a formatting context (such as a table container, flex container, grid container, or the block container itself).

    <style>
        * {
            margin: 0;
        }
        .inner {
            /* position默认值为static,这个例子中static、relative、sticky取得的结果是一致的 */
            position: static;
            height: 10%;
            width: 20%;
            background-color: blue;
        }
    </style>​
    
    <body>
        <div class="inner"></div>
    </body>
    

    从包含块的角度理解元素宽高百分比及边距百分比的计算方式

    可以发现inner的宽为215.391,高为0,页面显示空白。

    距离inner最近的块级元素body元素,因此body的内容区content box就是inner的包含块。**在无边距的情况下,无内容的块级元素高度为0且默认占满一行,一般来说一行的宽度相当于视口的宽度,因此body宽度=视口viewport的宽度。**通过getClientSize获取视口宽高 {w: 1077, h: 969},也就是说,包含块body的content box宽高{w: 1077, h: 0},因此inner宽高{w: 1077/5=215.4, h: 0}。

    可以试着给body一个100px的高,发现inner的高度变为10px。

    需要注意的是,一定是要以最近的块级元素的内容区content box作为包含块。

    <body>
        <div class="outer">
            <div class="inner"></div>
        </div>
    </body>​
    
    <style>
        * {
            margin: 0;
        }
        body {
            height: 200px;
            padding: 100px;
        }
        .outer {
            height: 400px;
            width: 400px;
            background-color: red;
            display: inline;
        }
        .inner {
            height: 10%;
            width: 20%;
            background-color: blue;
        }
    </style>
    

    从包含块的角度理解元素宽高百分比及边距百分比的计算方式

    此时的父元素outer是行内元素,所以依然是以最近的块级元素的内容区content box为准。

    视口宽高依然是 {w: 1077, h: 969}

    从包含块的角度理解元素宽高百分比及边距百分比的计算方式

    此时body元素的内容区content box:高度为固定的200px,而宽度需要视口宽度(块级元素默认是占满一行的)减去左右内边距总和200px,因此body{w: 1077-200=877, h: 200},即inner{w: 877/5=175.4, h: 20}。

    5. position值为absolute时宽高百分比的计算

    If the position property is absolute, the containing block is formed by the edge of the padding box of the nearest ancestor element that has a position value other than static (fixed, absolute, relative, or sticky).

    <body>
        <div class="outer">
            <div class="inner"></div>
        </div>
    </body>​
    
    <style>
        * {
            margin: 0;
        } 
       .outer {
            position: relative;  /* 这个例子中relative、sticky、fixed、absolute取得的结果是一致的 */
            height: 400px;
            width: 400px;
            background-color: red;
        }
        .inner {
            position: absolute;
            height: 10%;
            width: 20%;
            background-color: blue;
        }
    </style>
    

    从包含块的角度理解元素宽高百分比及边距百分比的计算方式

    距离inner最近的position不为static的祖先元素是outer{w: 400, h: 400},无padding,即inner的包含块为outer的content+padding,即{w: 400, h: 400},因此inner{w: 80, h: 40}

    尝试给outer加上padding: 100px试试。

    从包含块的角度理解元素宽高百分比及边距百分比的计算方式

    此时的outer宽高为{w: 400+200, h: 400+200},因此inner的包含块宽高也发生了改变,为outer的content+padding,即{w: 600, h: 600}。

    在上面的基础上,将outer的position改成static。

    .outer {
        position: static;  /* 改成默认值 */
        height: 400px;
        width: 400px;
        background-color: red;
        padding: 100px;
    }
    .inner {
        position: absolute;
        height: 10%;
        width: 20%;
        background-color: blue;
    }
    

    此时的inner:

    从包含块的角度理解元素宽高百分比及边距百分比的计算方式

    此时,inner的最近的postion不为static的祖先元素既不是outer也不是body,那么只剩下html了,即,inner此时的包含块为初始包含块,通过getClientSize得知initial containing block的大小为{w: 1077, h: 969},因此inner{w: 1077/5=215.4, h: 969/10=96.9}。

    6. position值为fixed时宽高百分比的计算

    If the position property is fixed, the containing block is established by the viewport (in the case of continuous media) or the page area (in the case of paged media).

    <body>
        <div class="outer">
            <div class="inner"></div>
        </div>
    </body>
    
    ​<style>
        * {
            margin: 0;
        } 
       .outer {
            position: relative;
            height: 400px;
            width: 400px;
            background-color: red;
            padding: 100px;
        }
       .inner {
            position: fixed;
            height: 10%;
            width: 20%;
            background-color: blue;
        }
    </style>
    

    此时inner的大小和上一张图的大小一样,都是根据初始包含块为基准进行计算的:

    从包含块的角度理解元素宽高百分比及边距百分比的计算方式

    7. position值为static、relative、sticky时边距百分比的计算

    边距的计算都是以包含块的宽度为参考来计算的。

    当position的值为static、relative、sticky时,是以最近块级祖先的content box为包含块计算的

    <body>
        <div class="outer">
            <div class="inner"></div>
        </div>
    </body>
    
    ​<style>
         * {
             margin: 0;
         }
         .outer {
             height: 400px;
             width: 800px;
             background-color: red;
             padding: 100px;  /* 此时的padding不参与计算,加不加的结果是一样的 */
         } 
        .inner { 
            position: static;  /* 这个例子中static、relative、sticky取得的结果是一致的 */
            margin-top: 10%;
            height: 100px;
            width: 100px;
            background-color: blue;
         }
    </style>
    

    此时inner的margin-top的值计算出来是80px:

    从包含块的角度理解元素宽高百分比及边距百分比的计算方式

    当position的值为absolute时,是以最近position值不为static的祖先元素的padding box计算的

    例①:将inner的position改成absolute:

    <style>
         * {
             margin: 0;
         }
         .outer {
             height: 400px;
             width: 800px;
             background-color: red;
             padding: 100px;
         }
         .inner { 
             position: absolute;
             margin-top: 10%;
             height: 100px;
             width: 100px;
             background-color: blue;
         }
    </style>
    

    此时inner的包含块是初始包含块,因此inner的margin-top的值1077/10=107.7。

    例②:在例①的基础上将outer的position值由默认的static改为relative(非static得所有值,结果都是一样的):

    从包含块的角度理解元素宽高百分比及边距百分比的计算方式

    此时,outer元素的padding box就是inner元素的包含块,因此inner的margin-top最终值为:(800(width)+100(padding-left)+100(padding-right)) * 10% = 100。

    当position的值为fixed时,是以初始包含块为参考来计算的

    将inner的position改成fixed,此时inner的包含块是初始包含块,因此inner的margin-top的值1077/10=107.7。

    8. 定位元素的offset值为百分比的计算方式

    定位元素的top、bottom、left、right是以最近的postion值不为static的祖先元素的padding box作为包含块计算的。

    <style>
        * {
            margin: 0;
        }
        .outer {
            height: 400px;
            width: 800px;
            background-color: red;
            padding: 100px;
        }
        .inner {
            position: absolute;
            top: 10%;
            left: 10%;
            margin-top: 10%;
            height: 100px;
            width: 100px;
            background-color: rgb(106, 106, 129);
        }
    </style>
    

    此时inner的包含块是初始包含块。

    从包含块的角度理解元素宽高百分比及边距百分比的计算方式

    在此基础上试试给outer加上postion:relative:

    从包含块的角度理解元素宽高百分比及边距百分比的计算方式

    9. 总结

    日常开发中,除去特殊情况,我们可以按下列规则来记:

    1. position为relative、static、sticky的元素,其包含块是最近块级祖先元素的content box,计算百分比宽高时是以包含块的content box为参考,计算百分比边距是以包含块的宽度为参考计算的。

    2. position为absolute的元素,其包含块是最近的position值不为static的祖先元素的padding box(如果没有,则包含块为初始包含块),计算百分比宽高时是以包含块的padding box为参考,计算百分比边距是以包含块的宽度为参考计算的,计算offset值,是以padding box为参考计算的。

    3. position为fixed的元素,其包含块是初始包含块

    参考

    1. developer.mozilla.org/en-US/docs/… MDN

    起源地下载网 » 从包含块的角度理解元素宽高百分比及边距百分比的计算方式

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元