CSS@6盒模型

作者 Jackie Anxis 日期 2016-11-26
CSS@6盒模型

CSS盒模型


经典图解


如上图所述,每个HTML元素,都像一个盒子,而这个盒子,有content(内容),padding(填充缝隙),border(边界/外壳),margin(边缘空白)。

  • content:可以理解为盒子里装的内容物
  • padding:可以理解为盒子的外壳和内容之间的缝隙(或者是填充物),就像快递盒子里面可能会填上那种充气的保护垫
  • border:可以理解为盒子的外壳
  • margin:可以理解为盒子与盒子间的空隙

相关属性

width 元素宽度

width:<length>|<percentage>|auto|inherit

解释:

  • 该属性,很明显,是用来设置元素宽度的,但是具体设置的是content部分的宽度,还是border包含的部分的宽度,要视情况而定,本篇后面会讲
  • 一般对于inline(行级)元素设置宽度是没有意义的,只给inline-blockblock或者其他某些类型的元素设置宽度
  • 默认值是auto,没有继承性,除非设置了inherit
  • 引申出min-widthmax-width属性,是给元素设置最小宽度和最大宽度的

height 元素高度

height:<length>|<percentage>|auto|inherit

解释:

  • width一致

padding 填充宽度

padding:[<length>|<percentage>]{1, 4}|inherit

解释:

  • padding是设置填充宽度的一个属性。可以设置1到4个值,分别设置上、右、下、左(顺时针)四个填充宽度,如上图。
  • 设置为<percentage>时,百分比数值是相对父元素
  • 也可以分开设置padding:padding-top,padding-right,padding-bottom,padding-left
  • 举例说明:
    • 写一个值的情况:padding:20px;,说明四个方向的padding都是同一个值,也就是20px
    • 写两个值的情况:padding:20px 10px;,其实等于padding:20px 10px 20px 10px;,也就是说,如果上和下的padding相等,那么只要设置一个就够了,左右也是一样。
    • 写三个值的情况:padding:20px 10px 5px;,其实等于padding:20px 10px 5px 10px,事实上写三个就只指定了上,右和下的宽度,剩余的左宽度应该等于右边的宽度。
  • 总结一下规则:
    • 对面相等,后者省略
    • 四面相等,只写一个
  • 其实类似padding这样,要对四个方向设值的属性,一般都可以像padding的规则进行设置。
  • padding的颜色和content的颜色一致,都是background-color

margin 外边距宽度

margin:[<length>|<percentage>|auto]{1, 4}|inherit

解释:

  • margin的书写方式基本上和padding是一样的,但是还是有一些区别的。
  • margin默认为0,但是可能浏览器的默认样式表会给某些标签设置初始margin值,比如IE6、IE7的body标签,默认的样式应该是:display:block;margin:15px 10px;zoom:1;(不是很确定),而没有预设padding值,chrome/firefox也只是设置了margin:8px;没有预设padding
  • 上下毗邻的两个元素的margin-topmargin-bottom会合并,取两者之间的较大值,看下面这个例子,两个元素间距仅为30px,而不是30px+10px:

    <div style="height:30px;width:100px;margin:30px 10px;background-color:lightseagreen;"></div>
    <div style="height:30px;width:100px;margin:10px 10px;background-color:lightseagreen;"></div>

  • 父元素的上下margin分别会和第一个子元素的margin-top以及最后一个子元素的margin-bottom进行合并。

    <div style="width: 100px; margin: 40px auto; background-color: lightblue;">
    <div style="height:30px;width:100px;margin:30px 0;background-color:lightseagreen;"></div>
    <div style="height:30px;width:100px;margin:10px 0;background-color:lightseagreen;"></div>
    </div>


    但值得注意的是,上面这种情况的触发条件是比较苛刻的。只有在父元素没有设置border的时候才会合并。因为子元素的所有内容(包括margin)是要完全包含在父元素的border里面的。假设,我在上面这种情况中,给父元素添加border,就会变成下面这种情况:


border 边框

border:[<border-width>||<border-style>||<border-color>]|inherit
border-width:[<length>|thin|medium|thick]{1,4}|inherit
border-style:[solid|dashed|dotted|…]{1,4}|inherit
border-color:[<color>|transparent]{1,4}|inherit
border-radius:[<length>|<percentage>]{1,4} [/[<length>|<percentage>]{1,4}]

解释:

  • 上面的属性,都可以写成border-direction-xxx的形式,如border-bottom-color
  • border-style最常用的三种就是:solid(实线), dashed(虚线), dotted(点线)
  • 重点讲一下border-radius
    • 事实上,每个角都是一个椭圆,而椭圆都会有两个属性,就是x轴长度和y轴长度,如图所示。
    • 所以设置全部四个角,需要8个值来表示,前四个,分别表示1,2,3,4个角的X轴方向半径,而后四个,则需要在前面加上/以示区别。比如上图中的圆角矩形,可以写成border-radius: 10px 15px 5px 5px /10px 5px 5px 15px
    • border-radius也满足对面相同,后者省略;四面相等,只写一个的规则,也就是,如果1号角和3号角如果一样,则只要写1号角的就行了。
    • border-radius还满足x,y一致,后者省略的规则,也就是说如果x方向半径和y方向半径一致的话,y方向就可以不写
    • border-radius设置百分比的值时,是相对本元素的widthheight而言的。也就是说,如果对一个正方形元素,设置border-radius:50%就可以变成圆形,如下:

outline 轮廓

outline:[<outline-width>||<outline-style>||<outline-color>]|inherit

outline-width:[<length>|thin|medium|thick]|inherit
outline-style:[solid|dashed|dotted|…]|inherit
outline-color:<color>|inherit

解释:

  • outline是在border外面的一圈,不占据空间的轮廓。基本上和border的属性一致。
  • 下面这个例子,你会发现两个div块之间,outline会互相覆盖,这说明outline并不占据空间。
    div{
    width: 200px;
    height: 50px;
    outline: 10px solid rgba(230,230,230,0.5)
    }
    .left{
    background-color: lightseagreen;
    }
    .right{
    background-color: darkorange;
    }

overflow 溢出

overflow:visible|hidden|scroll|auto

解释:

  • overflow是用来设置如果子元素超过父元素的溢出规则。
  • visible表示可见;
  • hidden表示隐藏;
  • scroll表示固定显示滚动条;
  • auto表示根据内容多少来选择显示或不显示滚动条;
  • 效果对比:

    overflow: visible; overflow: visible; overflow: visible; overflow: visible; overflow: visible; Jackie Anxis

    overflow: hidden; overflow: hidden; overflow: hidden; overflow: hidden; overflow: hidden; overflow: hidden; overflow: hidden; overflow: hidden; overflow: hidden; overflow: hidden; Jackie Anxis



    overflow: scroll; overflow: scroll; overflow: scroll; overflow: scroll; overflow: scroll; overflow: scroll; overflow: scroll; overflow: scroll; overflow: scroll; overflow: scroll; Jackie Anxis

    overflow: auto; overflow: auto; overflow: auto; overflow: auto; overflow: auto; overflow: auto; overflow: auto; overflow: auto; overflow: auto; overflow: auto; Jackie Anxis

  • 也可以利用overflow-xoverflow-y分别设置X和Y方向的溢出处理

box-sizing 选择宽度设置

box-sizing:content-box|border-box|inherit

解释:

  • box-sizing是用来指定,widthheight指定的究竟是content内容的宽度还是border包含的宽度。
  • 默认是content-box,表示CSS样式中,widthheight指定的是content内容的宽度,也就是说,width: 100px;padding:10px;这段代码,实际上border(不包含border)里面的内容应该宽为120px
  • 设置为border-box,表示CSS样式中,widthheight指定的是border(包括border在内)包含内容的宽度。
  • width: 100px; padding:10px; border:10px; box-sizing: border-box;

这段代码,实际上,content部分的宽度只有60px,而要加上paddingborder的宽度才达到100px。


box-shadow 设置阴影

box-shadow:none|<shadow>[,<shadow>]*
<shadow>:inset?&&<length>{2,4}&&<color>

解释:

  • box-shadow用来设置一个元素的阴影,默认是none,可以是多个值,中间用,隔开,表示多层阴影。
  • inset表示内阴影
  • 对于每一层阴影,length可以有2-4个,分别表示水平偏移(正值表示向右)、垂直偏移(正值表示向下),模糊半径,阴影大小;如下图所示的一段CSS:
    box-shadow: 10px 10px 5px 20px lightblue;


黑色边框部分,是向下偏移10px,向右偏移10px应该产生的阴影(也就是box-shadow: 10px 10px lightblue;的情况下应该有的大小),而红色边框比黑色边框总共宽40px(2个阴影大小的宽度),而5px的模糊半径,是包含在20px的阴影大小里面的。

关于盒模型中百分比的问题做一个统一说明

width&height

对子元素的widthheight设置百分比值,无论父元素的box-sizing如何,都是相对父元素content部分进行计算的。

/*left div content-box*/
.parent{
width: 200px;
height: 100px;
padding: 10px;
box-sizing: content-box;
}
.child{
width: 50%;
height: 50%;
}
/*right div border-box*/
.parent{
width: 200px;
height: 100px;
padding: 10px;
box-sizing: border-box;
}
.child{
width: 50%;
height: 50%;
}

100x50
90x40

  • 第一个父元素的content-box的宽为200px;所以子元素的width/height应该是基于200px进行计算的。
  • 第二个父元素的content-box的宽为200px-10px*2=180px;所以子元素的width/height应该是基于180px进行计算的。

padding&margin&border

对子元素的paddingmargin设置百分比值,无论父元素的box-sizing如何,都是相对父元素content部分的width进行计算的。
哦,忘了说了。border是不允许设置百分比值的。可怜的border

/*padding-test*/
.parent {
width: 400px;
height: 150px;
padding: 50px;
box-sizing: border-box;
}
.child1{
width: 200px;
height: 20px;
padding: 5% 16.67%;
}
.child2{
width: 200px;
height: 20px;
margin: 5% 16.67%;
}

  • 父元素的content-box的宽为400px-50px*2=300px;所以子元素的padding/margin应该是基于300px进行计算的。
  • 注意:无论上下还是左右的padding或者margin,都是相对父元素的width而言的,和height无关。

border-radius

对元素的border-radius设置百分比值,x轴方向的值是相对于元素border-boxwidth计算的,y轴方向的值是相对于元素border-boxheight计算的

div{
width: 1000px;
height: 500px;
padding: 200px;
border: 1px dashed gray;
background-clip: content-box;
/*background-clip: border-box;*/
border-radius: 10%;
}

以下是左上角部分截图: