2020-09-17 margin

1、margin改变元素尺寸

1)、可视尺寸-clientWidth

border+padding+width

2)、占据尺寸-outerWidth

margin+border+padding+width

3)、margin与可视尺寸
  • 适用于没有设定width/height的普通block水平元素(宽高会跟随文档流自动填满),例如:float元素 absolute/fixed元素 inline水平,table-cell元素等就不起作用
  • 只适用于水平方向尺寸

1、普通block水平元素

<style>
    /* 作为参照用 */
    .wra {
        width: 800px;
        height: 300px;
        background-color: #f3f3f3;
    }

    .box {
        height: 200px;
        background-color: #d5d5d5;
        margin: 30px 100px;
    }
</style>

<body>
    <div class="wra">
        <div class="box"></div>
    </div>
</body>

浏览器运行结果:

image.png

4)、margin与占据尺寸
  • block/inline-block水平元素均适用
  • 与有没有设定width/height值无关
  • 适用于水平方向和垂直方向
    实例:滚动容器内上下留白(课程中实例)
    滚动容器内上下留白.png

    自己实际操作(chrome)浏览器下:
<style>
    /* 作为参照用 */
    .wra {
        width: 800px;
        height: 300px;
        background-color: #f3f3f3;
    }
    .img {
        height: 150px;
        margin: 100px 0;
    }
    .a {
        height:100px;
        background-color: bisque;
    }
</style>

<body>
    <div class="wra">
        <img class="img" src="./img/bs-02.png" alt="" />
        <div class="a">22</div>
    </div>
</body>

当占据尺寸大于外部容器高度时,外部容器没有出现上述实例中的竖向滚动条

image.png

2、margin与百分比单位

1)、普通元素的百分比margin都是相对于容器的宽度计算的
<style>
    /* 作为参照用 */
    .wra {
        width: 800px;
        height: 300px;
        background-color: #f3f3f3;
    }
    
    .img {
        margin: 10%;
    }
</style>

<body>
    <div class="wra">
        <img class="img" src="./img/bs-02.png" alt="" />
    </div>
</body>

浏览器预览结果:

image.png

2)、绝对定位元素的百分比margin是相对于第一个定位祖先元素(relative/absolute/fixed)的宽度计算的
  • 如果绝对定位元素的祖先元素没有设置定位属性,则它的百分比margin是相对于文档html元素的宽度计算的
<style>
.box1 {
    width: 1200px;
    height: 400px;
    background-color: #f3f3f3;
}
.box2 {
    width: 800px;
    height: 300px;
    margin: 0 auto;
    background-color: bisque;
}
.img {
    position: absolute;
    /*此时相对于文档html元素的宽度计算*/
    margin: 10%;
}
</style>
<body>
    <div class="box1">
        <div class="box2">
            <img src="./img/bs-02.png" alt="" class="img">
        </div>
    </div>
</body>

3、margin重叠

1、) BFC(块级格式化上下文)

BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。包括浮动,和外边距合并等等,因此,有了这个特性,我们布局的时候就不会出现意外情况了。
display 属性为 block, list-item, table 的元素,会产生BFC.

给这些元素添加如下属性就可以触发BFC。

  • float属性不为none

  • position为absolute或fixed

  • display为inline-block, table-cell, table-caption, flex, inline-flex

  • overflow不为visible。

2)、margin重叠通常特性
  • block水平元素(不包括float和absolute元素)
  • 不考虑writing-mode,只发生在垂直方向(margin-top/margin-bottom)
3)、margin重叠3种情况
3.1 相邻的兄弟元素
<style>
    div {
        line-height: 2em;
        margin: 1em 0;
        background-color: #f3f3f3;
    }
</style>

<body>
    <div>第一行</div>
    <div>第二行</div>
</body>
image.png
3.2 父级和第一个/最后一个子元素
<style>
    .father {
        background-color: #f3f3f3;
    }
    .son {
        margin-top: 80px;
    }
</style>

<body>
    <div class="father">
        <div class="son">son</div>
    </div>
</body>
image.png

以下三种设置效果一样:

image.png

3.2.1 父子margin重叠其他条件:
a)、margin-top重叠
  1. 父元素非块状格式化上下文元素
  2. 父元素没有border-top设置
  3. 父元素没有padding-top值
  4. 父元素和第一个子元素之间没有inline元素分隔
b)、margin-bottom重叠
  1. 父元素非块状格式化上下文元素
  2. 父元素没有border-bottom设置
  3. 父元素没有padding-bottom值
  4. 父元素和最后一个子元素之间没有inline元素分隔
  5. 父元素没有height,min-height,max-height限制
3.3 空的block元素margin重叠
image.png
3.3.1 空block元素margin重叠其他条件:
  1. 元素没有border设置
  2. 元素没有padding值
  3. 里面没有inline元素
  4. 没有height,或者min-height
4)、margin重叠的计算规则
4.1 正正取大值
image.png
4.2 正负值相加
image.png
4.3 负负最负值
image.png
5)、善用margin重叠
image.png

4、margin:auto;

1)、元素有时候,就算没有设置width或height,也会自动填充对应的方位;
<style>
    .a {
        width: 200px;
        height:100px;
        background-color: #f3f3f3;
        position: relative;
    }
    .b {
        position: absolute;
        /* 宽度自动填满 */
        left: 0;
        right: 0;
        /* 结束 */
        /* 高度自动填满 */
        top: 0;
        bottom: 0;
        /* 结束 */
    }
</style>

<body>
    <div class="a">
        <div class="b"></div>
    </div>
</body>
image.png
2)、 margin:auto用处 —— 原本应该填充的尺寸被width/height强制变更,而margin:auto就是为了填充这个变更的尺寸设计的;
2.1 如果一侧定值,一侧auto,auto为剩余空间大小;如果两侧均是auto,则平分剩余空间;
2.2 为什么图片margin:0 auto;不水平居中?

因为此时图片是inine水平,就算没有width,其也不会占据整个容器

2.3 为什么明明容器定高,元素定高,margin:auto 0;无法垂直居中?
<style>
    .a {
        height: 200px;
        background-color: #f3f3f3;
    }
    .b {
        width: 500px;
        height: 100px;
        background-color: bisque;
        margin: auto;
    }
</style>

<body>
    <div class="a">
        <div class="b"></div>
    </div>
</body>
image.png

如果.b没有设置height:100px;高度会自动200px高吗?—— 不会

2.4 我们垂直方向margin无法实现居中了吗?
  1. writing-mode与垂直居中——更改流为垂直方向,实现垂直方向的margin:auto居中(但此时水平方向没法居中)
<style>
    .a {
        width: 800px;
        height: 200px;
        background-color: #f3f3f3;
        writing-mode: vertical-lr;
    }
    .b {
        width: 500px;
        height: 100px;
        background-color: bisque;
        margin: auto;
    }
</style>

<body>
    <div class="a">
        <div class="b"></div>
    </div>
</body>
image.png
  1. 绝对定位元素的margin:auto;居中
<style>
    .a {
        width: 800px;
        height: 200px;
        background-color: #f3f3f3;
        position: relative;
    }
    .b {
        position: absolute;
        /* 没有width/height,absolute元素自动填满了容器 */
        left: 0;
        right: 0;
        top: 0;
        bottom: 0;
        /* 结束 */
        /* width/height限制了absolute元素自动填满容器 */
        width: 500px;
        height: 100px;
        /* 结束 */
        background-color: bisque;
        /* margin:auto自动平分被变更的尺寸空间 */
        margin: auto;
    }
</style>

<body>
    <div class="a">
        <div class="b"></div>
    </div>
</body>
image.png

5、margin负值定位

1)、margin负值下的两端对齐:margin改变元素尺寸
<style>
.box {
    width: 880px;
    margin: auto;
    background-color: #d5d5d5;
}
.ul {
    overflow: hidden;
    margin-right: -20px;
}
.li {
    width: 280px;
    height: 100px;
    margin-right: 20px;
    background-color: bisque;
    float: left;
}
</style>
<body>
    <div class="box">
        <div class="ul">
            <div class="li">列表1</div>
            <div class="li">列表2</div>
            <div class="li">列表3</div>
        </div>
    </div>
</body>
image.png
2)、margin负值下的等高布局:margin改变元素占据的空间(这个例子没看懂)
image.png
3)、margin负值下的两栏自适应布局:元素占据空间跟随margin移动
<body>
    <div style="float:left;width:100%;">
        <p style="margin-right: 170px;">图片有浮动图片有浮动图片有浮动图片有浮动图片有浮动图片有浮动图片有浮动</p>
    </div>
    <img src="./img/bs-02.png" style="width:150px;float:left;margin-left:-150px;" alt="">
</body>
image.png

这里构建一个宽度100%的浮动容器(如果无需兼容IE8-,可以使用CSS3 calc),左浮动,后面跟随的图片也是同方向浮动,但是,margin-keft负值自身的宽度大小,配合<p>元素margin-right留下的补间空白,实现自适应效果。

6、margin无效情形解析

1)、inline水平元素的垂直margin无效

2个前提

  1. 非替换元素
    置换元素”又叫做“替换元素”,它们所具有的特征为:在不使用css修饰时,元素的标签和属性也会影响元素的显示。
    常见的置换元素:
img
input
textarea
select
object
iframe
canvas
  1. 正常书写模式
2)、margin重叠
3)、display为table相关类型(不包括table-caption,table以及inline-table)的所有,甚至也可应用于::first-letter。

实际测试中,使用chrome 版本 85.0.4183.121(正式版本) (64 位)测试,只有display为table时margin有效,其他table类型的margin都无效。::first-letter测试margin-left,margin-right也有效(p标签测试)。因为,实际情况还需在相应的浏览器去测试。

4)、绝对定位元素非定位方位的margin值“无效”
<style>
.a {
    width: 100px;
    height: 100px;
    background-color: #f3f3f3;
    position: absolute;
    top: 10%;
    left: 30%;
    /* 此时的margin-bottom和margin-right无效 */
    margin-bottom: 100px;
    margin-right: 100px;
}
</style>
<body>
    <div class="box">
        <div class="a"></div>
    </div>
</body>

其实是有效的,只是绝对定位的元素脱离了文档流,它和它的相邻元素是没有任何关系的,所以它不可能像普通元素那样通过margin影响到相邻元素。

有margin-bottom

image.png

没有margin-bottom
image.png

5)、鞭长莫及导致的margin无效(看起来margin无效,其实是有效果的,只是margin不够大)
<style>
    .box {
        background-color: #f3f3f3;
    }
    .img {
        float: left;
    }
    .a {
        margin-left: 100px;
        /* 当margin-left值没有超过图片宽度时:
        加overflow:hidden属性时.a的clientWidth为父元素宽度-图片宽度-marginLeft值 
        不加overflow:hidden属性时.a的clientWidth为父元素宽度-marginLeft值 
        不过浏览器效果看起来没有差别。
        当margin-left值超过图片宽度时:
        .a的clientWidth为父元素宽度-marginLeft值,跟overflow:hidden属性没有关系
        */
        overflow: hidden;
    }
</style>

<body>
    <div class="box">
        <img class="img" src="./img/bs-02.png" alt="">
        <div class="a">这是一段文字文字文字这是一段文字文字文字这是一段文字文字文字</div>
    </div>
</body>
image.png

其实右边的div的margin-left值是相对于其父元素的计算的

6)、内联特性导致的margin无效(margin小到一定负值,不起作用了)
<style>
    .box {
        background-color: #f3f3f3;
        height: 200px;
    }
    .img {
        margin-top: -200px;
    }
</style>

<body>
    <div class="box">
        <img class="img" src="./img/bs-02.png" alt="">x
    </div>
</body>
image.png

原因:受x影响,内联元素默认是vertical-align对齐于x字母的底部基线的(X在浏览器有一个默认的高度)

7、了解margin-start和margin-end

是css3为了适应于文档流应运而生的

1)、margin-start --- margin-left只能是左边方向,margin-start不一定是左边方向
<style>
    .box {
        /* 默认为ltr */
        direction: rtl;
    }
    .img {
        margin-left: 100px;
        -webkit-margin-start: 100px;
        -moz-margin-start:100px;
        margin-start: 100px;
    }
</style>
<body>
    <div class="box">
        <img src="./img/bs-02.png" alt="" class="img"><span>x</span>
    </div>
</body>
image.png

margin-start特性

  • 正常的流向,margin-start等同于margin-left,两者重叠不累加;
  • 如果水平流是从右往左,margin-start等同于margin-right;
  • 在垂直流下(writing-mode:vertical-*;),margin-start等同于margin-top;
2)、webkit下的其他margin相关属性
2.1 margin-before——默认流向的情况下,等同于margin-top;
2.2 margin-after——默认流向的情况下,等同于margin-bottom;
3)、margin-collapse——控制margin重叠
-webkit-margin-collapse: <collapse> | <discard> | <separate>
  • collapse(默认-重叠)
  • discard(取消兄弟元素之间的margin值)
  • separate(取消重叠)

使用chrome 版本 85.0.4183.121(正式版本) (64 位)测试,该属性说书无效的属性

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 224,383评论 6 522
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 96,028评论 3 402
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 171,486评论 0 366
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 60,786评论 1 300
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 69,793评论 6 399
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 53,297评论 1 314
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 41,685评论 3 428
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 40,655评论 0 279
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 47,192评论 1 324
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 39,223评论 3 345
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 41,343评论 1 354
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,966评论 5 350
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,656评论 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 33,130评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 34,257评论 1 275
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 49,869评论 3 381
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 46,407评论 2 365