# 盒子模型

盒模型包含: 内容(content)、填充(padding)、边界(margin)、 边框(border)。有两种盒模型, IE 盒子模型、标准 W3C 盒子模型;区 别: IE 盒子模型的 content 部分把 border 和 padding 计算了进去;

box-sizing 的默认属性是 content-box。

# 如何设置这两种模型

/* 设置当前盒子为 标准盒模型(默认) */
box-sizing: content-box;

/* 设置当前盒子为 IE盒模型 */
box-sizing: border-box;

# box-sizing 的值

  • content-box: padding 和 border 不被包含在定义的 width 和 height 之内。对象的实际宽度等于设置的 width 值和 border、padding 之和。(W3C 盒子模型)
  • border-box: padding 和 border 被包含在定义的 width 和 height 之内。对象的实际宽度就等于设置的 width 值。(IE6 盒子模型)
  • inherit: 继承父元素 box-sizing 属性的值

# 如何告知浏览器使用不同的盒模型渲染布局。

CSS 盒模型负责计算:

  • 块级元素占用多少空间。
  • 边框是否重叠,边距是否合并。
  • 盒子的尺寸。

盒模型有以下规则:

  • 块级元素的大小由widthheightpaddingbordermargin决定。
  • 如果没有指定height,则块级元素的高度等于其包含子元素的内容高度加上padding(除非有浮动元素,请参阅下文)。
  • 如果没有指定width,则非浮动块级元素的宽度等于其父元素的宽度减去父元素的padding
  • 元素的height是由内容的height来计算的。
  • 元素的width是由内容的width来计算的。
  • 默认情况下,paddingborder不是元素widthheight的组成部分。

# 请解释 box-sizing: border-box 的作用, 并且说明使用它有什么好处?

设置以后,相当于以怪异模式解析,border 和 padding 全会在你设置的宽度内部,比如手机端设置两行并且的布局,宽度各为 50%,如果不用这个属性,设置 border 后右边的 div 会下来错位,设置这个属性,宽度还是 50%而不是 50%+ n px,两行可以并列显示

说到 IE 的 bug,在 IE6 以前的版本中,IE 对盒模型的解析出现一些问题,跟其它浏览器不同,将 border 与 padding 都包含在 width 之内。而另外一些浏览器则与它相反,是不包括 border 和 padding 的。对于 IE 浏览器,当我们设置 box-sizing: content-box; 时,浏览器对盒模型的解释遵从我们之前认识到的 W3C 标准,当它定义 width 和 height 时,它的宽度不包括 border 和 padding;对于非 IE 浏览器,当我们设置 box-sizing: border-box; 时,浏览器对盒模型的解释与 IE6 之前的版本相同,当它定义 width 和 height 时,border 和 padding 则是被包含在宽高之内的。内容的宽和高可以通过定义的“width”和 “height”减去相应方向的“padding”和“border”的宽度得到。内容的宽和高必须保证不能为负,必要时将自动增大该元素 border box 的尺寸以使其内容的宽或高最小为 0。

好处:

  • 使用 box-sizing: border-box; 能够统一 IE 和非 IE 浏览器之间的差异。
  • 解决排版的问题,每个盒子之间排版时不用考虑 padding 和 border 的宽度计算

# 说说 content-box 和 border-box,为什么看起来 content-box 更合理,但是还是经常使用 border-box?

# JS 如何设置、获取盒模型对应的宽和高

方式一:通过DOM节点的 style 样式获取

element.style.width / height;

缺点:通过这种方式,只能获取行内样式,不能获取内嵌的样式和外链的样式。

这种方式有局限性,但应该了解。

方式二(通用型)

window.getComputedStyle(element).width / height;

方式二能兼容 Chrome、火狐。是通用型方式。

方式三(IE 独有的)

element.currentStyle.width / height;

和方式二相同,但这种方式只有 IE 独有。获取到的即时运行完之后的宽高(三种 css 样式都可以获取)。

方式四

// vue-lazyload 模块使用这个 api
element.getBoundingClientRect().width / height;

api 的作用是:获取一个元素的绝对位置。绝对位置是视窗 viewport 左上角的绝对位置。此 api 可以拿到四个属性:lefttopwidthheight

# 实例题(根据盒模型解释边距重叠)

元素的高度 110 px 或者 100px 都对,这里需要看父元素的盒模型如何设置的。

父元素如果设置了 overflow: hidden 的话,父元素的高度就是 100px 如果没有设置的话,就是 100px. 实际上设置了 overflow 相当于就是创建了一个 BFC

边距重叠的情况分: 1. 父子元素 2. 兄弟元素上下、左右重叠 3. 空元素的 top 与 buttom

# IE 8 以下版本的浏览器中的盒模型有什么不同

IE8 以下浏览器的盒模型中定义的元素的宽高不包括内边距和边框

# 实现三个 DIV 等分排布在一行(考察 border-box)

# 画一个盒模型,chrome 与 ie 表现一致?

# 行高的构成

  • 行高是由 line-box 组成的
  • line-box 是由一行里的 inline-box 组成的
  • inline-box 中最高的那个,或字体最大的拿个决定行高

# 边框

  • 边框的属性: 线型、大小、颜色
  • 边框背景图
  • 边框衔接

# css 中的 border:none 和 border:0px 有什么区别?

# box-sizing

我们知道,在标准盒子模型中,元素的总宽= content + padding + border + margin。 css 中的盒子模型大家可能都知道,但是这个盒子模型的属性可能没有那么多人知道,box-sizing属性就是用来重定义这个计算方式的,它有三个取值,分别是:content-box(默认)border-boxpadding-box

一般来说,假如我们需要有一个占宽200px、padding10px、border5px的div,经过计算,要这么定义样式。

div {
    width: 170px;   //这里的宽度要使用200-10*2-5*2 = 170得到。
    height: 50px;
    padding: 10px;
    border: 5px solid red;
}

然后我们来使用一下 box-sizing 属性。

div {
    box-sizing: border-box;
    width: 200px;  //这里的宽度就是元素所占总宽度,不需要计算
    height: 50px;
    padding: 10px;
    border: 5px solid red;
}

# border-radius

  • 相信这个属性,写过 css 的同学都知道,用来产生圆角,比如画一个圆形:

      div {
          width:100px;
          height:100px;
          background:red;
          border-radius:50px;    //圆角效果最大为长宽的一半,所以设置为50px及以上均可。
          /*border-radius:50%; */   //或者使用百分比,设置为50%及以上都是圆形效果。
      }
    

img

  • 然后我们来看看它的语法:border-radius: [左上] [右上] [右下] [左下],于是我们来画一个半圆

      div {
          width: 100px;
          height: 50px;
          background: red;
          border-radius: 50px 50px 0 0;
      }
    
  • 那如果要画一个椭圆该怎么办呢?你会发现上面的语法貌似做不到了,其实 border-radius 的值还有一种语法: x半径/y半径

    div {
      width: 100px;
      height: 50px;
      background: red;
      border-radius: 50px/25px;
    }
    
  • 如果我要画半个椭圆,又要咋办呢?

    div {
      width: 100px;
      height: 50px;
      background: red;
      border-radius: 100% 0 0 100% /50%;
    }
    

# box-shadow

上面的例子大都是对 css3 新属性的了解和认识,这个实例则是有关于解决方案的例子。

  • 需求:我们要实现下面这个效果图(三个边框:黑色,绿色,红色):

img

  • 解法一:假如没有 css3 知识,我们可以做这样做:用三个 div,分别设置边框,然后分别控制宽高和位置来达到这个效果。显然,很复杂,这里就不贴代码了。

  • 解法二:现在我们有 css3 的知识了,借助box-shadow就可以轻松解决这个问题。先来看看它的语法:box-shadow: [x偏移] [y偏移] [阴影模糊宽度] [阴影宽度] [颜色],并且还能添加多个阴影,使用逗号隔开。

img

当然你还可以继续增加,四重边框,五重边框......都不再是问题啦。另外,还能加圆角,阴影会贴紧内层 div。

使用这种方法,有一个缺点就是,不支持虚线边框。

  • 解法三: 使用 outline(只能支持两重边框)

img

使用这种方法的缺点就是,只能支持两层的边框,而且还不能根据容器的border-radius自动贴合。