Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

css 世界之盒模型 #86

Open
yangtao2o opened this issue Apr 8, 2020 · 0 comments
Open

css 世界之盒模型 #86

yangtao2o opened this issue Apr 8, 2020 · 0 comments

Comments

@yangtao2o
Copy link
Owner

yangtao2o commented Apr 8, 2020

盒模型(盒尺寸)

元素的内在盒子是由margin boxborder boxpadding boxcontent box组成的,这四个盒子由外到内构成了盒模型。

  • IE 模型: box-sizing: border-box。此模式下,元素的宽度计算为 border+padding+content 的宽度总和。
  • w3c 标准模型: box-sizing: content-box。 此模式下,元素的宽度计算为 content 的宽度。

由于 content-box 在计算宽度的时候不包含 border pading,而且又是默认值,业内一般采用以下代码重置样式:

:root {
  box-sizing: border-box;
}
* {
  box-sizing: inherit;
}

盒模型四大金刚

content

  • 对于非替换元素如 div,其 content 就是 div 内部的元素。
  • 而对于替换元素,其 content 就是可替换部分的内容。

CSS 中的 content 属性主要用于伪元素:before/:after

padding

padding 是四大金刚中最稳定的了,少见有什么异常。

尽管如此还是有些需要注意的地方:

大部分情况下我们会将元素重置为 box-sizing: border-box,宽高的计算是包含了 padding 的,给人一种 padding 也是 content box 一部分的感觉,好像 line-height 属性也作用于 padding 上。

但实际上,元素真正的内容的宽高只是 content box 的宽高,而 line-height 属性是不作用于 padding 的。

padding 不可为负值,但是可以为百分比值。

为百分比时水平和垂直方向的 padding 都是相对于父级元素宽度计算的。

将一个 div 设为 padding: 100%就能得到一个正方形,padding: 10% 50%可以得到一个宽高比 5:1 的矩形。

body {
  width: 400px;
}
.box {
  padding: 10% 50%;
}

padding 配合 background-clip 属性,可以制作一些特殊形状:

/* 三道杠 */
.icon1 {
  box-sizing: border-box;
  display: inline-block;
  width: 12px;
  height: 10px;
  padding: 2px 0;
  border-top: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  background: currentColor; /*注意如果此处背景颜色属性用缩写的话,需要放到其他背景属性的前面,否则会覆盖前面的属性值(此处为 background-clip)为默认值*/
  background-clip: content-box;
}

/* 双层圆点*/
.icon2 {
  display: inline-block;
  width: 12px;
  height: 12px;
  padding: 2px;
  border: 2px solid currentColor;
  border-radius: 50%;
  background-color: currentColor;
  background-clip: content-box;
}

currentColor 是 css 中为数不多的变量,指当前文字的颜色值,非常好用。

margin

作为外边距,margin 属性并不会参与盒子宽度的计算。

但通过设置 margin 为负值,却能改变元素水平方向的尺寸。不过这种情况只会发生在元素是流布局的时候。

即元素 width 是默认的 auto 并且可以撑满一行的时候。如果元素设定了宽度,或者元素设置了float: left / position: absolute这样的属性改变了流体布局,那么 margin 为负也无法改变元素的宽度了。

块级元素的垂直方向会发生 margin 合并,存在以下三种场景:

  • 相邻兄弟元素之间 margin 合并
  • 父元素 margin-top/margin-bottom 和子元素 margin-top/margin-bottom
  • 空块级元素自身的 margin-top 和 margin-botom 合并

要阻止 margin 合并,可以:

  1. 把元素放到 bfc 中;
  2. 设置 borderpadding 阻隔 margin;
  3. 内联元素(如文字)阻隔;
  4. 给父元素设定高度

margin 的百分比值跟 padding 一样,垂直方向的 margin 和水平方向上的一样都是相对于父元素宽度计算的。

<div class="box">
  <div></div>
</div>
<style>
  .box {
    overflow: hidden;
    background-color: lightblue;
  }
  .box > div {
    margin: 50%;
  }
</style>

此时 .box 是一个宽高比 2:1 的矩形,因为空块级元素自身的垂直方向的 margin 发生了合并。

这里父元素设置 overflow: hidden 是利用 bfc 的特性阻止子元素的 margin 和父元素合并,换成其他 bfc 特性或者设置 1px 的 border / padding 都是可以达到效果的。

margin: auto 能在块级元素设定宽高之后自动填充剩余宽高。

margin: auto 自动填充触发的前提条件是元素在对应的水平或垂直方向具有自动填充特性,显然默认情况下块级元素的高度是不具备这个条件的。

典型应用是块级元素水平局中的实现:

div {
  display: block;
  width: 200px;
  margin: 0 auto;
}

auto 的特性是,如果两侧都是 auto,则两侧均分剩余宽度;如果一侧 margin 是固定的,另一侧是 auto,则这一侧 auto 为剩余宽度。

这个特性鲜为人知,且很实用。

除了水平方向,垂直方向的 margin 也能实现垂直居中,但是需要元素在垂直方向具有自动填充特性,而这个特性可以利用 position 实现

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

border

border 主要作用是做边框。

  • border-style 属性的值有 none/solid/dashed/dotted/double
  • border-width 属性的默认值是 3px,是为了照顾小弟 border-style: double
  • border-color 默认是跟随字体的颜色,相当于默认设置了 border-color: currentColor 一样。

border 另一广受欢迎的功能就是图形构建,特别是做应用广泛的三角形:

div {
  border: 20px solid;
  border-color: blue transparent transparent transparent;
}

其实就是将其他三个边框的颜色设置透明,并把宽高设为 0 。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant