CSS-盒模型

131 阅读10分钟

其实,CSS就三个大模块:盒模型、浮动、定位,其余的都是细节,这三部分,无论如何也要学的非常精通。

所谓盒子模型就是把HTML页面中的元素看作是一个矩形的盒子,也就是一个盛装内容的容器。每个矩形都由元素的内容、内边距(padding)、边框(border)和外边距(margin) 组成。

标准盒子模型:

1. 盒子边框(border)

边框综合属性

border : border-width || border-style || border-color 
属性作用
border-width定义边框粗细,单位是px
border-style边框的样式
border-color边框颜色

边框的样式:border-style

  • none:没有边框即忽略所有边框的宽度(默认值)
  • solid:边框为单实线(最为常用的)
  • dashed:边框为虚线
  • dotted:边框为点线

例如:

 border: 1px solid red;  /* 没有顺序 */

单独设置盒子边框

很多情况下,我们不需要指定4个边框,我们是可以单独给4个边框分别指定的。

上边框下边框左边框右边框
border-top-style:样式;border-bottom-style:样式;border-left-style:样式;border-right-style:样式;
border-top-width:宽度;border- bottom-width:宽度;border-left-width:宽度;border-right-width:宽度;
border-top-color:颜色;border- bottom-color:颜色;border-left-color:颜色;border-right-color:颜色;
border-top:宽度 样式 颜色;border-bottom:宽度 样式 颜色;border-left:宽度 样式 颜色;border-right:宽度 样式 颜色;

边框圆角

语法格式:

border-radius: 左上角  右上角  右下角  左下角;  /* 和OC的枚举一样,也是 上 右 下 左 */
  1. 每个值可以为,数值或百分比的形式。
  2. 数值单位是 px,如果数值为宽、高的一半则变成圆形。

border-radius 属性实际上是以下属性的简写属性:

border-top-left-radius
border-top-right-radius
border-bottom-right-radius
border-bottom-left-radius

border-radius 属性可以接受一到四个值。规则如下:

一个值 - border-radius: 15px;(该值用于所有四个角,圆角都是一样的,相当于15px重复四次)
两个值 - border-radius: 15px 50px;(第一个值用于左上角和右下角,第二个值用于右上角和左下角,相当于15px 50px重复两次)
四个值 - border-radius: 15px 50px 30px 5px;(左上角、右上角、右下角、左下角):

表格合并边框

通过表格的cellspacing="0"将单元格与单元格之间的距离设置为0,但是两个单元格之间的边框会出现重叠,从而使边框变粗。

通过如下css属性可以将相邻边框合并在一起。

table { border-collapse:collapse; }  

collapse 单词是合并的意思,border-collapse:collapse; 表示相邻边框合并在一起。

2. 内边距(padding)

padding属性用于设置内边距。 是指边框与内容之间的距离。

内边距设置

属性作用
padding-left左内边距
padding-right右内边距
padding-top上内边距
padding-bottom下内边距

当我们给盒子指定padding值之后, 发生了2件事情:

  1. 内容和边框有了距离
  2. 盒子会变大了

我们分开写有点麻烦,我们可以不可以简写呢?

值的个数表达意思
1个值padding: 15px; 上下左右内边距都是15px,相当于15px重复四次。
2个值padding: 15px 50px; 上下内边距15px,左右内边距50px;相当于15px 50px重复两次。
4个值padding: 15px 50px 30px 5px; 上 右 下 左。

案例:新浪导航

新浪导航栏的核心就是因为里面的字数不一样多,所以我们不方便给宽度,所以给左右padding ,撑开盒子。

代码如下:

<!DOCTYPE html>
<html lang="en">
    <head>
      <meta charset="utf-8">
      <style>
          nav {
            height: 41px;
            background-color: #FCFCFC;
            border-top: 3px solid #FF8500;  /* 上边框 */
            border-bottom: 1px solid #EDEEF0;  /* 下边框 */
          }
          nav a {
            font-size: 14px;
            color: #4C4C4C;
            text-decoration: none; /*  取消下划线 */
            padding: 0 15px;  /* 内边距,上下0  左右15 */
            /* 因为链接是行内元素没有大小,所以需要转换行内块,才可以设置高度 */
            display: inline-block;
            height: 41px;
            line-height: 41px; /* 行高等于高度可以文字垂直居中 */
          }
          nav a:hover {  /* 链接伪类选择器  鼠标经过a链接的时候 */
            background-color: #eee;
          }
      </style>
    </head>
    <body>
    <nav>
    	<a href="#">首页</a>
    	<a href="#">手机新浪网</a>
    	<a href="#">网站导航</a>
    	<a href="#">三个字</a>
    </nav>
    </body>
</html>

盒子实际大小

盒子的实际大小 = 内容的宽度/高度 + 内边距 + 边框。 margin是盒子和盒子之间的距离。

内边距会撑大原来的盒子

设置内边距会撑大原来的盒子,通过给设置了宽高的盒子减去相应的内边距的值,维持盒子原有的大小。

课堂一练:

  1. 一个盒子宽度为100, padding为 10, 边框为5像素,问这个盒子实际的宽度的是(100 + 20 + 10 )
  2. 关于根据下列代码计算 盒子宽高下列说法正确的是(宽度为352px 高度为306px)
div {
		width: 200px;
		height: 200px;
		border: 1px solid #000000;
		border-top: 5px solid blue;
		padding: 50px;
		padding-left: 100px;
	}

w = 200 + 100 + 50 + 1 + 1 = 352 h = 200 + 50 + 50 + 5 + 1 = 306

3. 外边距(margin)

margin属性用于设置外边距,margin就是控制盒子和盒子之间的距离

外边距设置

属性作用
margin-top上外边距
margin-right右外边距
margin-bottom下外边距
margin-left左外边距

margin值的简写(复合写法)代表意思跟 padding 完全相同。

块级盒子水平居中

可以让一个块级盒子实现水平居中必须:

  1. 盒子必须指定了宽度(width),因为如果块级盒子不设置宽度就是100%宽度,谈何居中?
  2. 然后就给左右的外边距都设置为auto,上下margin多少都可以。

实际工作中常用这种方式进行网页布局,示例代码如下:

.header{ width:960px; margin:0 auto;}

文字居中和盒子居中区别

  1. 盒子内的文字水平居中是 text-align: center,而且还可以让行内、行内块元素居中对齐
  2. 块级盒子水平居中,margin:0 auto;
text-align: center; /*  文字、行内元素、行内块元素水平居中 */
margin: 10px auto;  /* 块级盒子水平居中  左右margin 改为 auto 就阔以了 上下margin多少都可以 */

清除元素的默认内外边距

为了更灵活方便地控制网页中的元素,制作网页时,我们需要将元素的默认内外边距清除:

* {
   padding:0;         /* 清除内边距 */
   margin:0;          /* 清除外边距 */
}

外边距合并

① 相邻块元素垂直外边距的合并

当上下相邻的两个块元素相遇时,如果上面的元素有下外边距margin-bottom,下面的元素有上外边距margin-top,则他们之间的垂直间距不是margin-bottom与margin-top之和,而是取两个值中的较大者这种现象被称为相邻块元素垂直外边距的合并。

解决方案:给上面的盒子再包装一层,然后给外层盒子创建BFC,也就是添加属性overflow: hidden

② 嵌套块元素垂直外边距的合并

对于两个嵌套关系的块元素,如果没有内边距或边框将外边距分隔开,父元素的上外边距会与子元素的上外边距发生合并,合并后的外边距为两者中的较大者。

如果有内边距或边框将外边距分隔开,就不会有合并的问题了。

解决方案:

  1. 可以为父元素定义上内边距或上边框,从而将父元素的上外边距和子元素的上外边距分开。
  2. 可以为父元素添加overflow:hidden

注意:只有普通文档流的垂直外边距才会发生外边距合并,浮动、定位的盒子不会有问题。

4. width > padding > margin

学习完盒子模型,内边距和外边距,什么情况下用内边距,什么情况下用外边距?大部分情况下是可以混用的。就是说,你用内边距也可以,用外边距也可以。 你觉得哪个方便,就用哪个。

我们根据稳定性来分,建议使用的优先级如下:

width >  padding  >  margin   

原因:

  • margin 会有外边距合并,还有 ie6下面 margin 加倍的bug(讨厌)所以最后使用。
  • padding 会影响盒子大小,需要进行加减计算(麻烦)其次使用。
  • width 没有问题(嗨皮)我们经常使用宽度剩余法 高度剩余法来做。

注意:右键 - 检查之后会有下图的样式图,在样式图中我们可以看出盒子width、height、padding、border、margin的颜色不一样,以后在看盒子的样式的时候一定要记得不同的颜色代表不同的属性。

5. 搜索趣图布局案例

无序和有序列表前面默认的列表样式,在不同浏览器显示效果不一样,而且也比较难看,所以,我们一般上来就直接去掉这些列表样式就行了。代码如下

ul { list-style: none; }

效果图如下:

代码:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <style>
          * {  /* 清空默认的内外边距 几乎是我们写css必须要写的 */
            margin: 0;
            padding: 0;
          }
          ul {
            list-style: none; /* 取消列表自带的小点  默认的列表样式 */
          }
          .searchPic {
            width: 238px;
            height: 294px;
            border: 1px solid #D9E0EE;
            border-top: 3px solid #FF8400;  /* 这句话要放到 border 的下面,因为就近原则 */ 
            margin: 100px;
          }
          .searchPic h3 {
            height: 35px;
            line-height: 35px;  /* 让行高等于高度 ,可以让文字垂直居中 */
            border-bottom: 1px solid #D9E0EE; 
            font-size: 16px;
            font-weight: normal;  /*  让粗体不变粗 */
            padding-left: 12px;
          }
          .searchPic img {
            margin: 7px 0 0 8px; /*  上 右 下 左 */
          }
          .searchPic ul li a {
            font-size: 12px;
            color: #666;
            text-decoration: none; /* 取消下划线 */
          }
          .searchPic ul {
            margin-left: 8px;
          }
          .searchPic ul li{
            padding-left: 10px;
            height: 26px;
            line-height: 26px;
            /* 左中设置小圆点方块 */
            background: url(images/square.png) no-repeat left center;
          }
          .searchPic ul li a:hover {
            text-decoration: underline;  /* 添加下划线 */
            color: #ff8400;
          }
        </style>
    </head>
    <body>
     <div class="searchPic">
     	<h3>搜索趣图</h3>
     	<img src="images/happy.gif" height="160" width="218" alt="">
     	<ul>
            <li><a href="#">GIF:小胖墩游泳被卡 被救后一脸无辜</a></li>
            <li><a href="#">GIF:小胖墩游泳被卡 被救后一脸无辜</a></li>
            <li><a href="#">GIF:小胖墩游泳被卡 被救后一脸无辜</a></li>
     	</ul>
     </div>
    </body>
</html>

6. CSS3盒模型

  1. 宽度属性width和高度属性height仅适用于块级元素,对行内元素无效
  2. 计算盒子模型的总高度时,还应考虑上下两个盒子垂直外边距合并的情况。
  3. 如果是行内元素(比如a标签),可以转成行内块元素,只设置高度和左右padding,不设置宽度,由内容撑开盒子,会达到文字自适应大小的效果。
  4. 如果是块级元素,没有给宽度,则会继承父亲的宽度,这时候给左右padding不会影响本盒子宽度(因为宽度都没给啊)。如果手动给宽度为100%,这时候左右padding会影响本盒子宽度,如下图:

上图宽度设置为100%,就相当于设置为父视图的238px,加上自己的左padding12px,所以最终的宽度是250px。

box-sizing

CSS3中可以通过 box-sizing 来指定盒模型,即可指定为 content-box、border-box,这样我们计算盒子大小的方式就发生了改变。

可以分成两种情况:

  1. box-sizing: content-box 盒子大小为 width + padding + border,content-box:此值为其默认值,其让元素维持W3C的标准Box Mode
  2. box-sizing: border-box 盒子大小为 width,就是说 padding 和 border 是包含到width里面的
div:first-child {
  width: 200px;
  height: 200px;
  background-color: pink; 
  box-sizing: content-box;  /*  就是以前的标准盒模型  w3c */
  padding: 10px;
  border: 15px solid red;
  /* 盒子大小为 width + padding + border   content-box:此值为其默认值,其让元素维持W3C的标准Box Mode */
}
div:last-child {
  width: 200px;
  height: 200px;
  background-color: purple;
  padding: 10px;
  box-sizing: border-box;   /* padding border  不撑开盒子 */
  border: 15px solid red;
  /* margin: 10px; */  
  /* 盒子大小为 width  就是说padding和border是包含到width里面的 */
}

box-shadow

上面我们学习了文字阴影,如下:

text-shadow: 水平位置 垂直位置 模糊距离 阴影颜色;

除了文字阴影还有盒子阴影,语法格式:

box-shadow: 水平位置 垂直位置 模糊距离 阴影尺寸(影子大小) 阴影颜色 内/外阴影;

  1. 前两个属性是必须写的。其余的可以省略。
  2. 默认外阴影 (outset) ,但是允许改,如果想要内阴影就加个inset
div {
    width: 200px;
    height: 200px;
    border: 10px solid red;
    /* box-shadow: 5px 5px 3px 4px rgba(0, 0, 0, .4);  */
    /* box-shadow:水平位置 垂直位置 模糊距离 阴影尺寸(影子大小) 阴影颜色  内/外阴影; */
    box-shadow: 0 15px 30px  rgba(0, 0, 0, .4);/* 水平距离 垂直距离 阴影大小 阴影颜色 */
}

效果如下:

水晶图片案例

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <style>
		div {
			width: 249px;
			height: 249px;
			line-height: 249px;
			background-color: pink;
			margin: 100px;
			background: url(images/shui.jpg) 0 0 no-repeat;
			font-size: 30px;
			text-align: center;
			color: rgba(255, 255, 255, 0.7);/*  颜色半透明 */
			border-radius: 50%; /*  变成一个圆 圆角 */
			box-shadow: 5px 5px 10px 16px rgba(255,255,255, 0.4) inset,  
			5px 4px 10px rgba(0,0,0,0.3);/* 添加内部的亮光效果,外部的影子效果 */			
		}
        </style>
    </head>
    <body>
    <div> 水晶图片 </div>
    </body>
</html>

效果图: