zoukankan      html  css  js  c++  java
  • 《CSS世界》读书笔记(十二)

    <!-- 《CSS世界》张鑫旭著 -->

    正确看待 CSS 世界里的 margin 合并

    什么是 margin 合并

    块元素的上外边距(margin-top)与下外边距(margin-bottom)有时会合并成单个外边距,这样的现象称为“margin合并”。

    (1)块级元素,但不包括浮动元素和绝对定位元素,尽管浮动和绝对定位可以让元素块状化

    (2)只发生在垂直方向,准确来说,是只发生在和当前文档流方向的相垂直的方向上

    margin 合并的3种场景

    (1)相邻兄弟元素margin合并。这是 margin 合并中最常见、最基本的。

    (2)父级和第一个/最后一个子元素。

    在实际开发中,给我们带来麻烦的多半是父子 margin 合并。示例可见 http://demo.cssworld.cn/4/3-3.php

    如何阻止这里 margin 合并的发生?

    对于 margin-top 合并,可以进行如下操作(满足一个条件即可):

    • 父元素设置为块状格式化上下文元素;(块状格式上下文的概念见6.3节)
    • 父元素设置 border-top 值;
    • 父元素设置 padding-top 值;
    • 父元素和第一个子元素之间添加内联元素进行分隔。

    对于 margin-bottom 合并,可以进行如下操作(满足一个条件即可):

    • 父元素设置为块状格式化上下文元素;
    • 父元素设置 border-bottom值;
    • 父元素设置 padding-bottom 值;
    • 父元素和最后一个子元素之间添加内联元素进行分隔;
    • 父元素设置 height、min-height或max-height。

    (3)空块级元素的 margin 合并。例如,下面 CSS 和 HTML 代码:

    .father { overflow: hidden; }
    .son { margin: 1em 0; }
    
    <div class="father">
        <div class="son"></div>
    </div>

    结果,此时 .father 所在的这个父级<div>元素高度仅仅是 1em。因为.son这个空<div>元素的 margin-top 和 margin-bottom 合并在一起了。

    如果不希望空<div>元素有margin合并,可以进行如下操作:

    • 设置垂直方向的 border;
    • 设置垂直方向的 padding;
    • 里面添加内联元素(直接 Space键空格是没用的);
    • 设置 height 或者 min-height。

    margin 合并的计算规则

    作者把 margin 合并的计算规则总结为“正正取大值”、“正负值相加”、“负负最负值”三句话

    (1)正正取大值。

    如果是相邻兄弟合并:

    .a { margin-bottom: 50px; }
    .b { margin-top: 20px; }
    
    <div class="a"></div>
    <div class="b"></div>

    此时,.a 和 .b 两个<div>之间的间距是 50 px,取大的那个值。

    如果是父子合并:

    .father { margin-top: 20px; }
    .son { margin-top: 50px; }
    
    <div class="father">
        <div class="son"></div>
    </div>

    此时,父元素 .father 等同于设置了 margin-top: 50px,取大的那个值。

    如果是自身合并:

    .a {
        margin-top: 20px;
        margin-bottom: 50px;
    }
    
    <div class="a"></div>

    此时,.a 元素的外部尺寸是 50px,取大的那个值。

    (2)正负值相加。

    如果是相邻兄弟合并:

    .a { margin-bottom: 50px; }
    .b { margin-top: -20px; }
    
    <div class="a"></div>
    <div class="b"></div>

    此时,.a 和 .b 两个<div>之间的间距是 30 px,是-20px+50px 的计算值。

    父子合并与自身合并的计算规则类似。

    (3)负负最负值。

    如果是相邻兄弟合并:

    .a { margin-bottom: -50px; }
    .b { margin-top: -20px; }
    
    <div class="a"></div>
    <div class="b"></div>

    此时,.a 和 .b 两个<div>之间的间距是 -50 px,取绝对负值最大的值。

    父子合并与自身合并的计算规则类似。

    margin 合并的意义

    CSS 世界的 CSS 属性是为了更好地进行图文信息展示而设计的。margin 合并设计的意义是为了让图文信息的排版更加舒服自然。

    深入理解 CSS 中的 margin: auto

    首先,我们需要知道下面这些事实:

    (1)有时候元素就算没有设置 width 或 height,也会自动填充。

    (2)有时候元素就算没有设置 width 或 height,也会自动填充对应的方位。例如:

    div {
        position: absolute;
        left: 0;
        right: 0;
    }

    此时<div>宽度就会自动填满包含块容器。

        此时,如果设置 width 或 height,自动填充特性就会被覆盖。例如:

        div { 200px; }

    此时, <div>宽度被限制成了200px,无法自动填充外部容器的可用宽度了。

        假设外部的容器宽度是300px,则有100px的宽度因为 width 设置而闲置,而 margin: auto 就是为了填充这个闲置的尺寸而设计的!

        margin: auto 的填充规则如下:

    (1)如果一侧定值,一侧 auto,则 auto 为剩余空间的大小

    (2)如果两侧均是 auto,则平分剩余空间。

    margin 的初始值大小是 0.

    .father { width: 300px; }
    .son {
        width: 200px;
        margin-right: 80px;
        margin-left: auto;
    }

    此时,.son 的左边距是 20px,右边距是 80px。 示例见 http://demo.cssworld.cn/4/3-4.php

    上面的例子中如果 margin-right 缺失,实现的效果正好是块级元素的右对齐效果,因为 margin的初始值是0.

    居中对齐左右同时设置 auto 即可。

    .son {
        width: 200px;
        margin-right: auto;
        margin-left: auto;
    }

    触发 margin: auto 计算有一个前提条件,就是 width 或 height 为auto时,元素是具有对应方向的自动填充特性的。

     那我们怎么才能用margin实现垂直方向居中呢?

    第一种方法是使用 writing-mode 改变文档流的方向;但是这种方法只能实现一个方向的居中

    第二种方法是绝对定位元素的 margin: auto 居中。可以实现水平垂直同时居中。

    .father {
        width: 300px;
        height: 150px;
        position: relative;
    }
    
    .son {
        position: absolute;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
    }

    此时,.son 元素的尺寸表现为“格式化宽度和格式化高度”,和<div>的“正常流宽度”一样,同属于外部尺寸,也就是尺寸自动填充父级元素的可用尺寸,此时,我们给.son设置尺寸。

    .son {
        position: absolute;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
        width: 200px;
        height: 100px;
    }

    此时,宽高被限制,原本应该填充的空间就被空余了出来,这多余的空间就是 margin: auto 计算的空间,因此,如果这时我们再设置一个 margin: auto:

    .son {
        position: absolute;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
        width: 200px;
        height: 100px;
        margin: auto;
    }

    那么我们这个.son元素就水平方向和垂直方向同时居中了。示例见 http://demo.cssworld.cn/4/3-5.php

        由于绝对定位元素的格式化高度即使父元素 height: auto 也是支持的,因此应用场景相当广泛,唯一不足的是此居中计算 IE8 及以上版本浏览器才支持。

    这种方式比top: 50% 然后margin 负一半元素高度的方法要好得多。

        最后,还有一个问题,假如说这里面的元素尺寸比外面的大,那这个auto该怎么计算呢?

    结果很有意思,不同流方向上的计算规则还不一样。在默认的水平流下,如果里面的元素尺寸大,水平方向 auto 计算后的负值会被当作 0 来处理,所以不会水平居中;但垂直方向计算后的负值则会保留,所以会垂直居中。

        另外,对于替换元素,如果我们设置display: block,则 margin: auto 的计算规则同样合适。

  • 相关阅读:
    Python之利用 gensim的word2vec进行酒店评论+wiki百科语料联合词向量训练
    Python之酒店评论主题提取LDA主题模型
    Python之酒店评论分词、词性标注、TF-IDF、词频统计、词云
    Pycharm使用技巧----Pycharm工程使用anaconda环境
    Python之Pandas 简介与Pandas 读取csv文件及相关操作01
    csv文件用excel打开乱码的解决方案
    apply()和call()的方法
    如何将webstrom本地的代码上传到github上
    通过Ajax方式上传文件,使用FormData进行Ajax请求
    Express bodyParser中间件使用方式
  • 原文地址:https://www.cnblogs.com/beginner2014/p/9497847.html
Copyright © 2011-2022 走看看