bblog icon indicating copy to clipboard operation
bblog copied to clipboard

我以前不知道的 margin

Open lishengzxc opened this issue 9 years ago • 0 comments
trafficstars

margin 与容器之间的关系

margin 可以改变容器尺寸

标准盒模型与元素尺寸

https://gw.alicdn.com/tps/TB1vbsxOXXXXXcUXFXXXXXXXXXX-499-463.png

元素尺寸

  1. 可视尺寸 - clientWidth (实线)
  2. 占据尺寸 - outerWidth (虚线)

margin 与可视尺寸

  1. 适用于没有设定 width / height 的普通 block 元素 float absolute fixed inline table-cell
  2. 只适用于水平方向尺寸
  3. 正负值亦可

栗子

<div class="out">
	<div class="in">
	i am a block element
	</div>
</div>
.out {
	padding: 50px;
	background: red;
}

// 调整 .in 的 margin
.in {
	margin: 50px 20px;
	background: green
}

如何利用这一特性?

一侧定宽的自适应布局

栗子

<div class="out">
	<img width="100" style="float: left" src="https://gw.alicdn.com/tps/TB1vbsxOXXXXXcUXFXXXXXXXXXX-499-463.png" />
	<p>我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字</p>
</div>
p {
	margin-left: 120px;
}

margin 与占据尺寸

  1. block / inline-block 水平元素都适用
  2. 与有没有设定 width / height 无关
  3. 适用于水平和垂直方向

栗子

<div class="out">
	<img width="150" src="https://gw.alicdn.com/tps/TB1vbsxOXXXXXcUXFXXXXXXXXXX-499-463.png" />
</div>
// 修改 img 的 margin-bottom
img {
	margin-bottom: 50px;
}

.out {
	background: green;
  	text-align: center;
}

如何利用这一特性?

滚动容器内上下留白

栗子

<div class="out">
	<img width="500" src="https://gw.alicdn.com/tps/TB1vbsxOXXXXXcUXFXXXXXXXXXX-499-463.png" />
</div>
.out {
	padding: 50px 0;
	height: 200px;
	overflow: auto;
}

img {
	margin: 50px 0;
}

margin 的百分比单位

  • 水平 / 垂直方向百分比
  • 普通 / 绝对定位元素百分比
  • 普通元素的百分比 margin 都是相对于容器的宽度
  • 绝对定位元素的百分比 margin 是相对于第一个定位祖先元素的宽度

如何利用这一特性?

宽高比例保持的自适应容器

栗子

<div class="out">
	<div class="box">
	</div>
</div>
.out {
	background: green;
	overflow: hidden;
}
// margin 重叠
.box {
	margin: 50%;
}

margin 重叠

产生 margin 重叠的条件

  1. 必须 block 元素
  2. 不考虑 writing-mode 的话,只发生在垂直方向

margin 重叠的情形

  1. 相邻兄弟元素
  2. 父级和第一个 / 最后一个子元素
  3. 空的 block 元素

相邻兄弟元素

栗子

<p>第一行</p>
<p>第二行</p>
p {
	line-height: 2em;
	margin: 1em 0;
	background: green;
}

父级和第一个 / 最后一个子元素

栗子

<div class="p" style="margin-top: 80px">
	<div class="c" style="margin-top: 80px">我是子</div>
</div>
.p {
	background: yellow;
}

父子 margin 重叠的其他条件

margin-top 重叠

  1. 父元素不是 BFC
  2. 父元素没有 border-top
  3. 父元素没有 padding-top
  4. 父元素和第一个子元素之间没有 inline 元素分割

margin-bottom 重叠

  1. 父元素不是 BFC
  2. 父元素没有 border-top
  3. 父元素没有 padding-top
  4. 父元素和第一个子元素之间没有 inline 元素分割
  5. 父元素没有设置 height min-height max-height

空的 block 元素

栗子

<div class="p">
	<div class="c"></div>
</div>
.p {
	background: green;
	overflow: hidden;
}

.c {
	margin: 10px;
}

一些条件限制

  1. 没 border
  2. 没 padding
  3. 内没 inline 元素
  4. 没 height / min-height

margin 重叠的计算规则

  1. 正正取大值
  2. 正负值相加
  3. 负负最小值

margin 重叠的意义

最初

<h2>h2</h2>
<p>p1</p>
<p>p2</p>
<ul>
  <li>l1</li>
  <li>l2</li>
  <li>l3</li>
</ul>

margin 的 auto

maring: auto 的作用机制

你已经知道的事实

  • 元素有时候,就算没有设置 width / height,也会自动填充;
div {
	background: red;
}
div {
	position: absolute;
	left: 0;
	right: 0;
}
  • 如果设置 width / height,自动填充特性就会被覆盖
div {
	width: 200px;
}
// 此时 margin 是 0;
  • 原来应该填充的尺寸被 width / height 强制变更,而 margin: auto 就是为了填充这个变更尺寸设计的;
div {
	width: 200px;
	margin-right: 100px;
	margin-left: auto;
}
  • 为什么图片 margin: 0 auto; 布局?解决~
  • 为什么明明容器定高,元素定高,margin: auto 0; 无法垂直居中?解决~
  • 那我们垂直方向的话,margin 就无解了吗?
  • writing-mode: vertical-lr
  • 绝对定位元素的 marin: auto; 的居中

例子

.p {
	position: relative;
	height: 500px;
}
.c {
	positon: absolute;
	top: 0;
	bottom: 0;
	right: 0;
	left: 0;
}
.p {
  display: flex;
  height: 500px;
  background: green;
}

.c {
  margin: auto;
  height: 100px;
  width: 100px;
  background: yellow;
}

margin 负值定位

1. 两端对齐

<div class="box">
  <div class="p">
    <div class="c"></div>
    <div class="c"></div>
    <div class="c"></div>
  </div>
</div>
.box {
  width: 1200px;
  background: red;
}

.p {
  margin-right: -20px;
  overflow: hidden;
}

.c {
  width: 386.66px;
  height: 300px;
  background: yellow;
  float: left;
  margin-right: 20px;
}

2. margin 负值下的等高布局

.box {
	overflow: hidden;
}
.cl, .cr {
	float: left;
}
.cl {
	background: red;
}
.cr {
	background: yellow;
}

3. margin 负值下的两栏自适应布局

元素占据空间跟随 margin 移动

<div class="out">
	<img width="100" style="float: right;" src="https://gw.alicdn.com/tps/TB1vbsxOXXXXXcUXFXXXXXXXXXX-499-463.png" />
	<p>我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字我是文字</p>
</div>
p {
	margin-right: 120px;
}

DOM 顺序和视觉不符,那么这样~

<div style="float: left; width: 100%;">
	<p style="margin-right: 120px"></p>
</div>
<img width="100" style="float: left; margin-left: -150px" />

margin 无效情形解析

  1. inline 元素垂直 margin 天然无效
  2. 可能 margin 重叠了
  3. display: table-cell 与 margin https://developer.mozilla.org/en-US/docs/web/css/margin
  4. position: absolute 与 margin (绝对定位元素非定位放线的 margin 值“无效” relative)
  5. 内联特性导致的 margin 无效
<!--测试例子5-->
<div style="height: 200px; background: yellow">
	<img width="200" src="https://gw.alicdn.com/tps/TB1vbsxOXXXXXcUXFXXXXXXXXXX-499-463.png" />
</div>

margin-start / margin-end 的了解

  • 正常的流向,margin-start 等同于 margin-left,两者重叠不累加;
  • 如果水平流是从右往左,margin-start 等同于 margin-right;
  • 垂直流(writing-mode: vertical-*;),margin-start 等同于 margin-top;

margin-before / after

margin-collapse

当元素发生 margin 重叠的时候,具体该如何表现

  • collapse
  • discard
  • separate

lishengzxc avatar Nov 16 '16 15:11 lishengzxc