CSS - 盒子模型

388 阅读11分钟

LK03ak.png

HTML中的每一个元素都可以看做是一个盒子,如下图所示,可以具备这4个属性

LK0hry.png

属性值描述
内容(content)元素的内容width/height
内边距(padding)元素和内容之间的间距
边框(border)元素自己的边框
外边距(margin)元素和其他元素之间的间距

因为盒子有四边,所以margin/padding/border都包括top/right/bottom/left四个方向的值:

LK0jKr.png

content

我们可以设置内容的宽度和高度

注意: 对于行内级非替换元素来说, 设置宽高是无效的

属性描述
width元素的宽度
min-width元素的最小宽度,无论内容多少,宽度都大于或等于min-width
max-width元素的最大宽度,无论内容多少,宽度都小于或等于max-width
height元素的高度
min-height元素的最小高度,无论内容多少,宽度都大于或等于min-height
max-height元素的最大高度,无论内容多少,宽度都小于或等于max-height

当元素的宽度和元素的最小宽度或最大宽度冲突的时候,以最小宽度或最大宽度为准

同样,这适用于元素的高度

padding

padding属性用于设置盒子的内边距,通常用于设置边框和内容之间的间距

padding包括四个方向,所以有如下的取值:

  • padding-top: 上内边距
  • padding-right: 右内边距
  • padding-bottom: 下内边距
  • padding-left: 左内边距

padding是padding-top、padding-right、padding-bottom、padding-left的简写属性(shorthand property)

padding缩写属性是从零点钟方向开始, 沿着顺时针转动的, 也就是上右下左

在实际开发中,各个位置上padding的值可以被设置为正整数,零 (不可以被设置为负整数)

如果在padding-top, padding-left, padding-right, padding-bottom中使用百分比作为值,那么这个值相对的是其包含块(一般是父元素)的宽度

LK2qJ6.png

border

边框相对于content/padding/margin来说特殊一些

因为border具备 宽度width颜色color样式style三个特性

border-width

  • border-top-width、border-right-width、border-bottom-width、border-left-width

  • border-width是上面4个属性的简写属性,缩写方式和padding的缩写方式一致

border-color

  • border-top-color、border-right-color、border-bottom-color、border-left-color
  • border-color是上面4个属性的简写属性,缩写方式和padding的缩写方式一致

border-style

  • border-top-style、border-right-style、border-bottom-style、border-left-style
  • border-style是上面4个属性的简写属性,缩写方式和padding的缩写方式一致

border-style的可选值如下:

一般常用的值是 solid, dashed,dotted

LK2WgT.png

border

如果我们相对某一边同时设置 宽度 样式 颜色, 可以进行如下设置:

  • border-top
  • border-right
  • border-bottom
  • border-left
  • border: 统一设置4个方向的边框
.lorem {
  width: 300px;
  border-top: 1px solid red;
  border-right: 2px dashed blue;
  border-bottom: 3px dotted gray;
  border-left: 4px double green;
}
.lorem {
  width: 300px;
  /*
  如果使用border同时设置四边的时候
  只能将四边设置成同样的值, 是不可以单独设置各边的样式的
  */
  border: 1px solid red;
}
# border 在mdn上的设置规则如下
# 也就意味着边框颜色、宽度、样式的编写顺序任意
# 同时 除了line-style之外的其余2个属性是可以省略的

# line-width可以使用3个表示粗细的关键字 分别为 thin(约1px), medium(约3px), thick(约5px)
# line-width的默认值是medium

# color的默认值是 如果设置了前景色,就是要前景色,如果没有设置前景色,默认值是#000
# 一般推荐的编写顺序是 <line-width> <line-style> <color>
<line-width> || <line-style> || <color>
/*
	border的值也可以是none,表示的是清除边距
*/
.box {
  border: none;
}

border-radius

border-radius一般用于设置盒子的圆角

描述
数值通常用来设置小的圆角, 比如6px --- 常见
百分比通常用来设置一定的弧度或者圆形 --- 除50%外,其余设置较少

border-radius本质上是border-top-left-radius、border-top-right-radius、border-bottom-right-radius,和 border-bottom- left-radius 的简写属性

border-radius的本质是在盒子的四个定角按照一定的半径做圆,取圆和盒子相交的部分

/*
	缩写规则和margin和padding一致:
	 + 左上角和右下角 以10px做弧
	 + 右上角和左晓娇 以20px做弧
*/
border-radius: 10px 20px;
/*
	border-box = content + padding + border
	所做的圆
		x轴的直接为border-box的width * 40%
		y轴的直接为border-box的height * 40%
*/
border-radius: 40%;
/*
	如果一个元素是正方形, 设置border-radius大于或等于50%时,就会变成一个圆
	注意: 是大于等于50%,超过50%的时候,效果和50%是一致的
*/
border-radius: 50%;

margin

margin属性用于设置盒子的外边距, 通常用于元素和元素之间的间距

margin包括四个方向, 所以有如下的取值:

  • margin-top:上内边距
  • margin-right:右内边距
  • margin-bottom:下内边距
  • margin-left:左内边距

marginmargin-top、margin-right、margin-bottom、margin-left的简写属性

margin缩写属性是从零点钟方向开始, 沿着顺时针转动的, 也就是上右下左

在实际开发中,各个位置上margin的值可以被设置为正整数,零和负整数

margin也可以有四个,三个,两个和一个值的写法,其规则和padding一致

如果在margin-top, margin-left, margin-right, margin-bottom中使用百分比作为值,那么这个值相对的是其包含块(一般是父元素)的宽度

LhGMdD.png

margin 的传递

  1. 只有上下外边距 会进行传递,左右外边距 并不会产生任何的传递
  2. 父子元素必须贴边,且设置了子元素的上下margin
  3. 如果父子都设置了margin值,以较大的那个为准
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    body {
      margin: 0;
    }

    .container {
      width: 300px;
      height: 300px;
      background-color: red;
    }

    .box {
      width: 100px;
      height: 100px;
      background-color: blue;
      /*
        margin-top的传递:
          如果块级元素的顶部线和父元素的顶部线重叠,
      		那么这个块级元素的margin-top值会传递给父元素

        margin-bottom的传递:
      		如果块级元素的底部线和父元素的底部线重写,并且父元素的高度是auto,
      		那么这个块级元素的margin-bottom值会传递给父元素
      */
      margin-top: 100px;
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="box"></div>
  </div>
</body>
</html>

解决方法(任意一种皆可):

  1. 移除子元素的margin-top,改用父元素的padding-top

  2. 为父元素设置透明的1pxborder-top --- 阻止了两个margin的合并

  3. 使用overflow: auto (任何非visible值)display: flow-root等方法开启父元素的BFC

    --- 也就是让父元素产生独立的渲染空间,与父元素外的渲染空间隔离

margin 折叠问题

  1. 垂直方向上相邻的2个margin(margin-top、margin-bottom)有可能会合并为1个margin,这种现象叫做collapse(折叠)
  2. 水平方向上的margin(margin-left、margin-right)永远不会collapse

合并规则: 两个值进行比较,取较大的值

解决方法: 只设置其中一个元素的margin

  1. 兄弟块级元素之间的margin折叠

LhGOrp.png

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    body {
      margin: 0;
    }

    .box {
      width: 300px;
      height: 300px;
    }

    .box1 {
      background-color: red;
      margin-bottom: 10px;
    }

    .box2 {
      background-color: blue;
      margin-top: 50px;
    }
  </style>
</head>
<body>
  <div class="box box1"></div>
   <div class="box box2"></div>
</body>
</html>
  1. 父子块级元素之间的margin折叠

LhGZK6.png

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    body {
      margin: 0;
    }

    .container {
      width: 300px;
      height: 300px;
      background-color: red;
      margin-top: 10px;
    }

    .box {
      width: 100px;
      height: 100px;
      background-color: blue;
      margin-top: 30px;
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="box"></div>
  </div>
</body>
</html>

水平居中方法

在一些需求中,需要元素在父元素中水平居中显示(父元素一般都是块级元素、inline-block)

元素方式描述
行内级元素和行内块级元素text-aligin: center
块级元素margin: 0 auto虽然默认情况下margin的默认值是0
但是块级元素的一个特性是独占父元素的一行显示
所以此时如果我们设置了块级元素的宽度
但浏览器还是需要让块级元素独占一行
此时就会将margin-right设置为auto,也就是由浏览器来决定
当我们设置了margin: 0 auto
那么就意味着margin-leftmargin-right的值都是auto
也就是左右外边距都由浏览器来自行决定
此时块级元素就水平居中了

注意: margin: auto 0 并不能使块级元素垂直居中对齐

​ margin和padding 的默认值都是0

​ 块级元素水平方向独占一行 auto表现为填满 所以 0 auto 可以水平居中

​ 但是垂直方法是依次排列的,auto表现为0,所以auto 0 不可以让块级盒子垂直局中

行内非替换元素在盒子模型中的注意事项

属性描述
width、height、上下外边距不起作用
上下内边距 和 上下方向的border起作用
但是不占空间
左右外边距 和 左右内边距 和 左右方向的border正常起作用
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    span {
      padding-bottom: 10px;
      border-bottom: 1px solid #000;
    }

    div {
      display: block;
      background: rgba(0, 255, 0, 0.5);
    }
  </style>
</head>
<body>
  <!--
    给元素添加下划线的方法
    1. text-decoration: underline --- 下划线会紧贴着文本, 没有间隙
    2. 通过padding-bottom和boder-bottom进行设置
			 也就是通过行内级元素的上下内边距和上下边框 生效但不占位的特点来实现
  -->
  <span>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ad, nulla!</span>
  <div>Hello World</div>
</body>
</html>

image.png

box-sizing

描述
content-box设置的宽高就是内容的宽高 --- 默认值
border-box设置的宽高是以border为基准的宽高

content-box的示意图如下:

LhR2wz.png

border-box的示意图如下:

LhR3xu.png

一般情况下,在为盒子设置了边框和内边距的时候,如何盒子设置了具体的宽度或高度

为了避免盒子被撑开,影响整体布局

此时一般推荐将当前元素的box-sizing设置为border-box

outline

outline是在元素边框外的一个围绕元素的视觉边界线,是一种视觉高亮样式,通常用以表示元素的焦点状态(例如用户通过键盘导航到一个按钮时)

  1. 不占用空间
  2. 默认显示在border的外面

和outline相关的属性:

  • outline-width: 外轮廓的宽度
  • outline-style: 取值跟border的样式一样,比如solid、dotted等
  • outline-color: 外轮廓的颜色
  • outline: outline-width、outline-style、outline-color的简写属性,跟border用法类似

在开发中outline的主要作用是,清除input, a这类元素在被选中的时候 (也就是处于:focus状态)下默认添加的outline

input {
  /* 给input自身设置样式,相当于在input的所有状态下都设置了相同的样式 */
  outline: none
}

shadow

box-shadow

box-shadow属性可以为块级元素设置一个或者多个阴影

# <shadow># 中的 # 表示可以设置多个<shadow>, 多个<shadow>之间通过逗号进行分割
# 多个阴影值,左边的层级比右边的高,即左边的阴影会盖在右边的阴影上边
box-shadow: none | <shadow>#
  1. 每个阴影用<shadow>表示
  2. 多个阴影之间用逗号,隔开,从前到后叠加
.box {
  box-shadow: 3px 5px 10px 5px #444;
}

box-shadow中各个属性的值

属性描述备注
offset-x水平方向的偏移,正数往右偏移, 负数往左偏移必填
offset-y垂直方向的偏移,正数往下偏移, 负数往上偏移必填
blur-radius高斯模糊半径
当模糊半径越大时,阴影的颜色变化变得越渐进和平缓,
导致图像或阴影的过渡效果变得更加平滑和柔和
可选
默认值: 0
spread-radius延伸半径
用于调整阴影的大小
可选
默认值: 0
<color>阴影的颜色可选
默认值:
1. 如果没有设置前景色color,即为#000
2. 如果设置了前景色color,即使用color属性的值
inset外框阴影变成内框阴影可选

box-shadow的值可以是多个,也就是可以给盒子设置多个阴影

.box {
  width: 300px;
  height: 300px;
  background-color: #f00;
  /*
  	box-shadow: 5px 5px 15px 5px #289fed;
   	  1. 阴影大小和.box一样的大小,且位于.box下边
  		2. 阴影的颜色是#289fed
  		3. 阴影向右位移5px,向下位移5px
  		4. 扩散半径是5px,所以阴影大小比.box的大小在每个方向上都增加了5px
    	5. 模糊半径 15px,阴影从#289fed逐渐渐变到透明,渐变半径是15px
  */
  box-shadow:
    5px 5px #289fed,
    10px 10px #5fb8ff,
    15px 15px #a1d8ff,
    20px 20px #cae6ff,
    25px 25px #e1eeff,
    5px 5px 15px 5px #fff;
}

LhRsGO.png

text-shadow

text-shadow用法类似于box-shadow,用于给文字添加阴影效果

但是text-shadow在设置值的时候没有spread-radiusinset

.box {
  text-shadow: 2px 3px 10px #333;
}