整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

零基础教你学前端-77、CSS盒模型

网站布局中,我们会使用各种各样的元素,这些元素本质上就是一个个小的容器,也称之为盒子,盒子里面可以放置文本,图片,或者其他元素。

什么是 CSS 盒模型呢?

CSS 盒模型本质上是一个包裹每个 HTML 元素的盒子,包含 margin、border、padding 和 content 四个部分。

浏览器就是通过盒模型,来计算元素在网页中占据的空间大小的。

前面我们介绍过这些盒模型的要素:Content,表示盒子的内容,包含文本、图像等等。Padding,表示填充内容周围的一个区域,它是透明的。Border,表示围绕填充和内容的边框。Margin,表示边框以外的区域,它也是透明的。

我们来举个例子。

创建一个 019-css-box-model 文件夹,在文件夹里创建一个 box-model-1.html 文件和一个box-model-1.css 文件。

构建 html 基础代码,引入样式文件。为了便于比较效果,我们定义两个 div 元素,添加不同的类名,补全文本。

HTML
<div class="box1">
    盒子模型组成部分:内容,内边距,边框,外边距
</div>
<div class="box2">
    盒子模型组成部分:内容,内边距,边框,外边距
</div>
CSS
* {
  margin:0;
  padding:0
}
div {
  width: 200px;
  height: 200px;
}
.box1 {
  background-color: orange;
  border:20px solid gray;
  padding:20px;
  margin:20px;
}
.box2 {
  background-color: yellow;
}

打开 CSS 文件,定义通配符选择器,声明样式 margin: 0,padding: 0。取消所有元素默认的边距和填充样式。

定义 div 选择器,声明样式:width: 200px,height: 200px。为两个 div 元素添加宽度和高度。

定义 .box1 选择器,声明样式:background-color: orange。

定义 .box2 选择器,声明样式:background-color: yellow。

在浏览器里预览效果,两个有背景颜色的盒子就做好了。

给 box1 添加样式:border: 20px solid gray,为橙色的盒子增加一个边框。

对比黄色的盒子,橙色盒子总宽度增加了 40px,总高度也增加了 40px。

继续给 box1 添加样式:padding: 20px。

此时橙色的盒子继续变大。对比黄色的盒子,宽度和高度又增加了40px。

继续给 box1 添加样式:margin: 20px。

这时我们发现,因为添加了外边距,橙色盒子的位置发生了偏移。

通过这个例子我们发现,给元素添加内填充、边框以及外边距之后,盒子会变大并发生位置变化。

那么,如何在所有浏览器中正确设置一个元素的宽度和高度呢?这对于精确的页面布局,意义重大!

计算盒子的宽度和高度,请牢记这两个公式:

盒子的宽度 = 内容宽度 + 左填充 + 右填充 + 左边框 + 右边框 + 左边距 + 右边距

盒子的高度 = 内容高度 + 上填充 + 下填充 + 上边框 + 下边框 + 上边距 + 下边距

再次强调:当应用 CSS 设置一个元素的 width 和 height 属性时,只是设置了元素内容区域的宽度和高度。要计算一个元素的完整尺寸,必须要加上填充、边框和边距。

我们将上面这种计算元素大小的盒模型,称作标准盒模型。

那能不能给元素设置了 margin 和 padding 属性后,元素本身的宽高就固定为设置的这个值呢?这就要应用另外一种盒模型,叫做怪异盒模型。

给元素声明 box-sizing 属性,取值为 border-box,这个元素就按照怪异盒模型来呈现大小了。

我们先来做个例子。

在 019-css-box-model 文件夹下,创建一个 box-model-2.html 文件和一个box-model-2.css 文件。

构建 html 基础代码,引入样式文件。为了便于比较效果,我们还是定义两个 div 元素,添加不同的类名,补全文本。

HTML
<div class="box1">
    我是一个div,用来演示怪异盒子
</div>
<div class="box2">
    我是一个div,用来进行做比较
</div>
CSS
*{
    margin:0;padding:0
}
div{
    width: 200px;
    height:200px;
}
.box1{
    background-color: orange;
    box-sizing: border-box;
    border:20px solid gray;
    padding:20px;
    margin:20px
}
.box2{
    background-color: yellow;
}

打开 CSS 文件,定义通配符选择器,声明样式 margin: 0,padding:0。取消所有元素默认的边距和填充样式。

定义 div 选择器:声明样式:width: 200px,height: 200px。

定义 .box1 选择器,声明样式:background-color: orange。

定义 .box2 选择器,声明样式:background-color: yellow。

在浏览器里预览效果,两个有背景颜色的盒子就做好了。

给 box1 添加样式:box-sizing: border-box,触发怪异盒模型。继续添加样式 border: 20px solid gray,padding:20px。

可以看到,box1 添加了边框和内边距,但是大小并没有改变,宽高仍然是200px。显而易见,内容的大小被压缩了。

继续为 box1 添加样式:margin: 20px。

大家可以猜一下,外边距会不会继续压缩内容呢?

仔细观察一下,box1 位置发生了偏移,观察一下容器的大小,并没有变化。

所以,怪异盒模型宽度和高度的计算公式为:

盒子的宽度 = CSS样式设置的 width 值 + 左边距 + 右边距

盒子的高度 = CSS样式设置的 height 值 + 左边距 + 右边距

实际上,box-sizing 属性还有一个值: content-box,就是用来触发元素的标准盒模型。这也是元素盒模型的默认值,如果没有给元素设置 box-sizing 属性,容器的大小就按照标准盒模型来计算。

回到样式代码,将 box1 的 box-sizing 属性值修改为 content-box。

我们发现,容器总宽高变为了 320px。

注释掉box-sizing: content-box,容器的总宽高仍然是 320px。

HTML
<!--回答问题: -->
<div class='box'></div>
<style>
    div {
        width:100px;
        height:100px;
        background-color:orange;
        box-sizing:content-box;
        border:10px solid gray;
    }
    .box {
        width:200px;
        padding:200px;
        border-top:10px solid yellow;
        margin:20px 30px;
    }
</style>

文章配套视频链接: https://www.bilibili.com/video/BV1oU4y1278g/?p=81

简介

在HTML中,有一个很重要的理论:块元素和行内元素。在CSS中极其重要的一个理论——CSS盒子模型。 在“CSS盒子模型”理论中,页面中的所有元素都可以看成一个盒子,并且占据着一定的页面空间。

一个页面由很多盒子组成,这些盒子之间会互相影响,因此掌握盒子模型需要从两个方面来理解:一是理解单独一个盒子的内部结构(往往是padding),二是理解多个盒子之间的相互关系(往往是margin)。

2 盒子模型概念

盒模型指的是网页元素的结构。当指定一个元素的宽度或高度时,便设置了元素内容的尺寸,可以把每个元素都看成一个盒子,盒子模型是由4个属性组成,号称“盒尺寸四大家族”:

  • content(内容区),可以是文本或图片 —— 变化多端
  • padding(内边距),用于定义内容与边框之间的距离 —— 温和向内
  • margin(外边距),用于定义当前元素与其它元素之间的距离 —— 激进对外
  • border(边框),用于定义元素的边框 —— 功勋卓越

此外,在盒子模型中,还有宽度(width)和高度(height)两大辅助性属性。记住,所有的元素都可以看成一个盒子 。如下图所示:

2.1 内容区

内容区是CSS盒子模型的中心,它呈现了盒子的主要信息内容,这些内容可以是文本、图片等多种类型。内容区是盒子模型必备的组成部分,其他3个部分都是可选的。 内容区有3个属性:width、height和overflow。使用width和height属性可以指定盒子内容区的高度和宽度。在这里注意一点,width和height这两个属性是针对内容区content而言的,并不包括padding部分。 当内容过多,超出width和height时,可以使用overflow属性来指定溢出处理方式。

2.2 内边距

内边距,指的是内容区和边框之间的空间,可以看成是内容区的背景区域。padding属性接受长度值或百分比值,但不允许使用负值。 关于内边距的属性有5种:padding-top、padding-bottom、padding-left、padding-right,以及综合了以上4个方向的简写内边距属性padding。使用这5种属性可以指定内容区与各方向边框之间的距离。

2.2.1 元素的尺寸

因为CSS中默认的box-sizing是content-box,所以使用padding会增加元素的尺寸。

.box {
   width: 80px;   
    padding: 20px;
}

如果不考虑其他CSS干扰,此时.box元素所占据的宽度就应该是120像素(80px+20px×2),这其实是不符合现实世界的认知的,人们总是习惯把代码世界和现实世界做映射,因此,新人难免会在padding的尺寸问题上踩到点坑。这也导致很多人乐此不疲地设置box-sizing 为border-box,甚至全局设置。

2.2.2 标签元素内置的padding

  • ol/ul列表内置padding-left,但是单位是px不是em。
  • 很多表单元素都内置padding。例如:所有浏览器<input>/<textarea>输入框内置padding;所有浏览器<button>按钮内置padding;所有浏览器<radio>/<chexkbox>单复选框无内置padding。

2.3 外边距

外边距,指的是两个盒子之间的距离,它可能是子元素与父元素之间的距离,也可能是兄弟元素之间的距离。外边距使得元素之间不必紧凑地连接在一起,是CSS布局的一个重要手段。 外边距的属性也有5种:margin-top、margin-bottom、margin-left、margin-right,以及综合了以上4个方向的简写外边距属性margin。 同时,CSS允许给外边距属性指定负数值,当外边距为负值时,整个盒子将向指定负值的相反方向移动,以此产生盒子的重叠效果,这就是传说中的“负margin技术”。

2.3.1 margin与元素尺寸

  • 元素的内部尺寸

只有元素是“充分利用可用空间”状态的时候,margin才可以改变元素的可视尺寸。比方说,如下CSS:

.header {
 width: 160px; 
  margin: 0 -5px;
}

此时元素宽度还是160像素,尺寸无变化。因为只要宽度设定,margin就无法改变元素尺寸,这和padding是不一样的。

但是,如果是下面这样的HTML和CSS:

<div class="header">
   <div class="son">
</div></div>
.header { width: 160px; }
.menu { margin: 0 -5px; }

则.menu元素的宽度就是165像素了,尺寸通过负值设置变大了,因为此时的宽度表现是“充分利用可用空间”。

  • 元素的外部尺寸

只要元素具有块状特性,无论有没有设置width/height,无论是水平方向还是垂直方向,即使发生了margin合并,margin对外部尺寸都着着实实发生了影响。

2.3.2 margin合并

块级元素的上外边距(margin-top)与下外边距(margin-bottom)有时会合并为单个外边距,这样的现象称为“margin合并”。

  • margin合并一般出现在以下3种场景:(1)相邻兄弟元素margin合并。这是margin合并中最常见、最基本的。(2)父级和第一个/最后一个子元素。(3)空块级元素的margin合并。
  • margin合并的计算规则把margin合并的计算规则总结为:“正正取大值”, “正负值相加” ,“负负最负值”。
  • margin合并的意义对于兄弟元素的margin合并其作用和em类似,都是让图文信息的排版更加舒服自然。父子margin合并的意义在于:在页面中任何地方嵌套或直接放入任何裸<div>,都不会影响原来的块状布局。<div>是网页布局中非常常用的一个元素,其语义是没有语义,也就是不代表任何特定类型的内容,是一个通用型的具有流体特性的容器,可以用来分组或分隔。由于其作用就是分组的,因此,从行为表现上来看,一个纯粹的<div>元素是不能够也不可以影响原先的布局的。自身margin合并的意义在于可以避免不小心遗落或者生成的空标签影响排版和布局。

2.3.3 margin:auto

margin:auto的填充规则如下。 (1)如果一侧定值,一侧auto,则auto为剩余空间大小。 (2)如果两侧均是auto,则平分剩余空间。

2.4 边框

在CSS盒子模型中,边框与我们之前学过的边框是一样的。 边框属性有border-width、border-style、border-color,以及综合了3类属性的简写边框属性border。

border属性总是能解决很多棘手的问题,在在图形构建、体验优化以及网页布局这块几大放异彩,,同时保证其良好的兼容性和稳定性。下面我们一起看看border都有哪些精彩的特性表现。

2.4.1 为什么border-width不支持百分比值

我们通过比对笔记本、手机发现,虽然两台设备的尺寸差异很大,但是边框的大小相比而言就可以忽略不计了。边框是不会因为设备大就按比例变大的。因此,如果支持百分比值,是不是就意味着设备大了边框也跟着变大?有一张图片,大片区域都是白色的,在白底背景上和文字混在一起,就会有一片奇怪的空白区域,会让人产生没对齐的假象,此时,我们给这张图片套个1px灰色边框,区域就明显了,对吧!设计的初衷就是为了这么点儿事,没有需要使用百分比值的场景。于是,综合这两点,造成了border-width不支持百分比值。

2.4.2 border与图形构建

border属性可以轻松实现兼容性非常好的三角图形效果,为什么可以呢?其底层原因受inset/outset 等看上去没有实用价值的border-style属性影响,边框3D效果在互联网早期其实还是挺潮的,那个时候人们喜欢有质感的东西,为了呈现逼真的3D效果,自然在边框转角的地方一定要等分平滑处理,然后不同的方向赋予不同的颜色。然后,这一转角规则也被solid类型的边框给沿用了。因此,我们就不难理解下面的4色边框的表现了:

div {
   width: 10px; height: 10px;    
    border: 10px solid;    
    border-color: #f30 #00f #396 #0f0;
}

运行一下上面的代码看一下效果吧!

2.4.3 border与透明边框技巧

这是提高用户体验的一个小技巧,尤其在移动端,我们的操作工具一般就是我们的手指,但是,我们的手指粗细可以媲美胡萝卜,而屏幕尺寸就那么点儿,如果我们正在走路,则一些精致的图标和按钮很容易就点不中甚至误点。

稳妥的方法是外部再嵌套一层标签,专门控制点击区域大小。如果对代码要求较高,则可以使用padding或者透明border增加元素的点击区域大小。

3 总结

现实生活中看到的盒子,有正方形、长方形、圆柱形等,依据形状特点,可包裹不同物件。CSS中的盒子虽然没有那么多的形状,但在视觉呈现上不同类型的盒子还是会有很大的不同,有的盒子要占据一行,有的盒子不能定义外边距、宽度和高度,有的盒子宽度和高度能自适应。CSS中用display指定盒类型(即框类型),常用的有 block(块)、inline(行内)、inline-block(行内块)、table(表格),以及CSS3新增的flexbox(伸缩盒)。 HTML 元素只有两种默认的盒类型,即块级元素(block-level element)和行内元素(inline-level element)。其中行内元素不可定义CSS属性width、height、上下margin和上下padding。常用的span和div分别是行内元素和块级元素。

由此可见,需要掌握的内容太多,要想学会所有布局相关的技术不太现实。高级的布局话题基于文档流和盒模型等概念,这些是决定网页元素的大小和位置的基本规则。因此理解和掌握如何设置元素的大小和位置至关重要。

4 最后的最后

为初学者提供学习指南,为从业者提供参考价值。我坚信码农也具有产生洞见的能力。关注【码农洞见】,一起学习和交流吧!

SS盒模型本质上是一个盒子,每一个元素都被抽象成一个盒子,每一个盒子又包括四部分

内容(content),内填充(padding),边框(border),外边距(margin)

盒子模型简图

标准盒子模型&&IE盒子模型

  • IE盒子模型

width = content-width + padding-width + border-widthheight = content-height + padding-height + border-height

  • 标准盒子模型

width = content-widthheight = content-height

BFC块级元素

一个块格式化上下文(block formatting context) 是Web页面的可视化CSS渲染的一部分。它是块盒子的布局发生,浮动互相交互的区域。

  • CSS2.1中规定满足下列CSS声明之一的元素便会生成BFC
- 根元素,即HTML元素
- float的值不为none
- overflow的值不为visible
- display的值为inline-block、table-cell、table-caption
- position的值为absolute或fixed
  • 作用
- 自适应两栏布局
- 可以阻止元素被浮动元素覆盖
- 可以包含浮动元素——清除内部浮动
- 分属于不同的BFC时可以阻止margin重叠

可替换元素

在 CSS 中,可替换元素replaced element)的展现效果不是由 CSS 来控制的。这些元素是一种外部对象,它们外观的渲染,是独立于 CSS 的简单来说就是通过修改某个属性就使得显示变换的元素

  • 常见替换元素

img/object/video/iframe/textarea/input

  • 特征
- 内容和外观不受页面上CSS的影响
- 有默认的尺寸,并且在很多CSS上有自己的表达样式

伪元素

  • ::before
在元素内容之前插入额外生成的内容
  • ::after
在元素内容之后插入额外生成的内容
  • ::first–letter
选取元素的首个字符
  • ::first–line
选取元素的第一行
  • ::selection
对用鼠标键盘等已选取的文字部分应用样式
  • ::spelling-error
表示浏览器标记为不正确拼写的文本段
只有一小部分CSS属性可用于 ::spelling-error 伪元素选择器:
color/background-color/cursor/caret-color/outline
text-decoration/text-emphasis-color/text-shadow
  • ::grammar-error
伪元素应用于浏览器标识为语法错误的文本段
只有一小部分的css能够应用在::grammar-error的选择器中
color/background-color/cursor/text-emphasis-color/text-shadow/outline/text-decoration
  • ::focus-within
当元素本身或其后代获得焦点时,:focus-within伪类的元素就会有效

focus-within兼容情况