盒子宽高 box-sizing

我们知道盒子有 content、padding、border、margin。那我们设置的 width、height 生效到了哪里?盒子到底多大?

首先要明白什么是盒子的大小?

  • 盒子大小包括 border、padding 和 content。

如果说盒子所占据的空间大小,则就是盒子大小加上与外界的距离,也就是加上 margin。

  • 盒子所占屏幕空间大小 = margin + 盒子大小

额外:浏览器默认会给整个 body 添加 margin,padding 。所以我们通常会重置一下为0。

设置的 width 和 height 指的是盒子的大小,所以和 margin 无关。至于生效到了哪里,由属性 box-sizing 决定。
box-sizing 有两个主要的值:

  • box-sizing:content-box; 默认值
  • box-sizing: border-box;

content-box

content-box 是默认值。如果你设置一个元素的宽为 100px,那么这个元素的内容区 content 就是定死了 100px 宽

因为通常会重置所有盒子的 padding 和 border 为 0,所以 content 的宽高就是盒子的大小宽高。那么我们真正关心的盒子所占空间的大小就是:

  • 盒子占据屏幕空间大小 = margin + content

在这里盒子大小的宽就为 100 px。

但是假如你设置了任何边框和内边距的宽度,它们都会被增加到最后绘制出来的元素宽度中。也就是盒子的大小不再和 content 的大小保持一致。

  • 盒子占据屏幕空间大小 = margin + border + padding + content

这就导致我们对于盒子的大小判断,不再是直观的 width 属性的值,而是需要自己计算加上边框和内边距才是盒子大小。这个反直觉要特别注意。

这个特点在响应式布局时很烦。

border-box

border-box 告诉浏览器:你想要设置的边框和内边距的值是包含在 width 内的。
也就是说,如果你将一个元素的 width 设为 100px,那么这 100px 会包含它的 border 和 padding,内容区的实际宽度是 width 减去 (border + padding) 的值。

  • 盒子占据屏幕的大小 = margin + width、height

换句话说,边框、内边距,内容区的大小是弹性的。比如当边框或内边距扩大,内容区会被压缩,以此来保持整体对外的盒子大小依然是 width 设置的值。

大多数情况下,这种特性就使得我们更容易地固定一个元素占据空间的大小。

IE8 以下的盒子模型相当于默认 box-sizing: border-box

另外设置盒子大小还能,我们还可以设置如下属性:

  • min-width:最小宽度,无论内容多少,宽度都大于或等于min-width
  • max-width:最大宽度,无论内容多少,宽度都小于或等于max-width

移动端适配时, 可以设置最大宽度和最小宽度。
手机页面到电脑上,不至于撑的很大,也不会随着小屏手机而小到字都看不清楚。

下面两个属性不常用,因为高度由内容决定,没必要写死,一般也是设置宽度多一点。

  • min-height:最小高度,无论内容多少,高度都大于或等于min-height
  • max-height:最大高度,无论内容多少,高度都小于或等于max-height

注意:width、height 的默认值是 auto,不是 100%

边框 border

边框相对于content/padding/margin来说特殊一些:
 边框具备宽度width:border-width;

  • 简写属性包含了四个方向,指定特定方向:border-top-width。样式和颜色类似。

 边框具备样式style:border-style;
 边框具备颜色color:border-color;

image.png

border 属性

border 可以同时设置边框的样式,宽度,颜色,没有书写顺序。并且是同时设置4个边框,如果需要特定指出某一个边框:border-top

圆角: border-radius

border-radius常见的值:

  • 数值: 通常用来设置小的圆角, 比如6px;
  • 百分比: 通常用来设置一定的弧度或者圆形;

如果一个元素是正方形, 设置border-radius大于或等于50%时,就会变成一个圆。

margin

上下 margin 的传递

margin-top 传递

  • 如果块级元素的顶部线和父元素的顶部线重叠,那么这个块级元素的margin-top值会传递给父元素

比如两个 div 嵌套,子 div 紧贴着父 div 顶部。现在想要子 div 和 父 div 上下隔开一点,通常就会想到给子 div 填加 margin-top: 5px; 然而实际情况是,这个 margin 在父 div 上生效了。父子 div 依然紧挨着,一下往下降了 5px。

image.png

margin-bottom 传递

  • 如果块级元素的底部线和父元素的底部线重叠,并且父元素的高度是auto,那么这个块级元素的margin-bottom值会传递给父元素
  • 这个比较少见

如何防止出现传递问题?

  • 给父元素设置padding-top\padding-bottom
  • 给父元素设置border
  • 触发BFC: 设置overflow为auto

margin 外边距,这个东西设计出来,本意是用来表示兄弟元素之间的距离,虽然也能在嵌套的父子元素中生效,但是不符合设计初衷。这种父子嵌套使用 padding 内边距更符合语义化一点。

最佳实践:

  • margin 一般是用来设置兄弟元素之间的间距
  • padding 一般是用来设置父子元素之间的间距

上下 margin 的折叠

垂直方向上相邻的2个margin(margin-top、margin-bottom)有可能会合并为1个margin,这种现象叫做collapse(折叠)
比如,上下两个 div 想要隔开距离,上 div 设置了 margin-bottom 为 5px,下 div 设置了 margin-top 为 10 px,按理两个 div 间的距离为 15 px。然而实际上两个 margin 会折叠,两个 div 实际垂直实际相隔 10 px。

image.png

水平方向上的margin(margin-left、margin-right)永远不会collapse。

折叠后最终值的计算规则

  • 两个值进行比较,取较大的值

如何防止margin collapse?

  • 只设置其中一个元素的 margin

元素居中的理解

目前我们了解到元素布局的居中:

  • 行内元素:text-align: center;
  • 块级元素:margin: 0 auto;

这两种方式虽然实现了水平居中,但其实都是歪门邪道,奇淫巧技。

尤其是 margin: 0 auto; 这玩意是利用了浏览器的特性。块级元素所占一整行剩下的 margin 当左右 margin 都为 auto 的时候,浏览器会将剩下的margin 平均分。
为什么无法在垂直方向上通过 auto 居中?就是因为浏览器在垂直方向上没有这个特性。

还有浮动,浮动被设计出来是用来做图文混排的,但是被拿来做布局了。虽然有效果,但是体验非常差,问题也非常多。

所以说这些用法都是牛头不对马嘴,专业的事情就应该让专业的来做,比如元素居中布局,就应该让元素定位来做,或者更为专业的,为布局而生的 flex 来做!

外轮廓 - outline

相当于不占据空间的 border。
image.png

阴影

盒子阴影 – box-shadow

css 文档的表示法:

box-shadow 属性的格式:
image.png

解读一下 css 文档的表示法:

  • 尖括号包起来的类似一个变量。
  • “#” 号表示一个或者多个

文档表示 box-shadow 的属性值为 none 或者 1 个或多个

具体是什么?
image.png

  • && 表示没有书写顺序,不分先后
  • ? 表示可选
  • {2,4} 表示 2~4 个

又是什么就依次往下找解释说明就行。

box-shadow 格式

网页的坐标系原点为左上角。x 轴水平向右,y 轴垂直向下。

image.png

阴影在线生成:

文字阴影 - text-shadow

image.png

行内非替换元素的注意事项

行内非替换元素也就是“纯”行内元素。

以下属性对行内级非替换元素不起作用

  • width、height、margin 的上下方向

以下属性对行内级非替换元素的效果比较特殊

  • padding 和 border,它们能在视觉上撑大了盒子,但是在上下方向上,盒子实际不占据空间。

比如设置 span padding 为 100 px,背景色为红色。可以看出整个 span 盒子在视觉上撑大了。但是在 span 后面紧接着一个 div,会发现 div 跑到了 span 的里面去了。因为 span 在上下方向上盒子实际不占据空间。
image.png
为什么会有这么奇怪的特点?
因为给报纸排版,行内元素这一行中还有其他的内容,比如一个段落,span 包裹放大其中几个字,如果设置 padding 和 border 占据实际空间,那就会把上下其他行的字挤走,段落排版就乱了。W3C 就是出于不影响段落排版的考虑,而这样设计的。

背景色和前景色

  • 背景色会填充到 border。
  • color 为设置前景色,前景色包括文字颜色,也包括边框颜色。