CSS——CSS 基本视觉格式化:① “块盒子”格式化

栏目: CSS · 发布时间: 6年前

内容简介:前言:接下来的几篇系列文章我们讲一个东西:盒子(BOX)。 “盒模型”(box model)作为 CSS 看待元素的一种方式,CSS 将每个元素都看作由一个盒子表示。从某方面来说,对于初级、中级学习者的我们,大可将 CSS 的学习看作是对“盒子”的学习。 为什么这么说?请看下图我个人的 CSS 学习流程:图中我们可以看到,几乎所有的内容都是围绕着“盒子”这个东西在展开。本篇我们将阐述最基本的理论知识,将“盒子”的方方面面一步步带到我们跟前。
本文推荐 PC 端阅读~

本文同步更新于:
- 「公众号:前端一万小时」
- 「知乎:Oli's 前端一万小时」
- 「语雀:前端一万小时」

本文版权归 “前端一万小时” 所有,未经授权,请勿转载!
复制代码
CSS——CSS 基本视觉格式化:① “块盒子”格式化
CSS——CSS 基本视觉格式化:① “块盒子”格式化

前言:接下来的几篇系列文章我们讲一个东西:盒子(BOX)。 “盒模型”(box model)作为 CSS 看待元素的一种方式,CSS 将每个元素都看作由一个盒子表示。从某方面来说,对于初级、中级学习者的我们,大可将 CSS 的学习看作是对“盒子”的学习。 为什么这么说?请看下图我个人的 CSS 学习流程:

CSS——CSS 基本视觉格式化:① “块盒子”格式化

图中我们可以看到,几乎所有的内容都是围绕着“盒子”这个东西在展开。

本篇我们将阐述最基本的理论知识,将“盒子”的方方面面一步步带到我们跟前。

1 什么是“盒子”

“盒子 box”由 CSS 引擎根据文档中的内容所创建,主要用于文档元素的格式化、定位和布局等。

盒子与元素并不是一一对应的,有时多个元素会合并生成一个盒子,有时一个元素会生成多个盒子(如匿名盒子)。

一个完整的“盒子”中心有一个内容区(content area)。这个内容区周围有可选的 padding、边框和 margin。这些项之所以被认为是可选的,是因为它们的宽度可以设置为 0,实际上就是从“盒子”上去除这些项。

CSS——CSS 基本视觉格式化:① “块盒子”格式化

一个完整的“盒子”

2 “视觉格式化模型”概述

CSS 视觉格式化模型(visual formatting model)是用来处理和在视觉媒体上显示文档时使用的计算规则。

通俗的讲就是:页面(文档树)可以想象成是由一个个 box 组合而成的,而“视觉格式化模型(Visual formatting model)” 是一套规则,将这些 box “布局”成访问者看到的样子。

每个盒子的“布局”由以下因素决定( 本篇文章和下一篇文章主要讲解第①、②点,其属于“最基本的视觉格式化”,而对于剩下的要点,我们在接下来的系列文章中会挨个讨论 ):

① 盒子的尺寸:精确指定、由约束条件指定或没有指定;

② 盒子的类型:行内盒子(inline box)、行内级盒子(inline-level box)、原子行内级盒子(atomic inline-level box)、块盒子(block box);

③ 定位方案(positioning scheme):普通流定位、浮动定位或绝对定位;

④ 文档树中的其它元素:即当前盒子的子元素或兄弟元素;

⑤ 视口尺寸与位置;

⑥ 所包含的图片的尺寸;

⑦ 其他的某些外部因素。

CSS——CSS 基本视觉格式化:① “块盒子”格式化

每一个元素都是一个“盒子”,“盒子”可以嵌套“盒子”

:bulb:如上图所示, 视觉格式化模型 会根据盒子的“包含块”( containing block )——(包含其他盒子的块称为“包含块”)的边界来渲染盒子。通常,盒子会创建一个包含其后代元素的“包含块”,但是盒子并不由“包含块”所限制,当盒子的布局跑到”包含块“的外面时称为溢出( overflow )。

上图中,section 的包含块是 body ,header、article、footer 的包含块是 section。

:warning:区别:

  • “盒子模型”是处理盒子本身的内部属性——边距、边框等;
  • 而“视觉格式化模型”是用来处理这些盒子的摆放。

3 关于“盒子”我们一定需要知道的——基本视觉格式化

3.1 “盒子”的生成

盒子的生成是 CSS “视觉格式化模型”的一部分,用于从文档元素生成盒子。

盒子有不同的类型,盒子的类型取决于 CSS 的 display 属性——元素“角色”的改变。

3.1.1 “块级元素”和“块级盒子”

设置元素的 display 属性为 block、list-item 

或  table 时,该元素将成为“块级元素”。

这些元素在正常流中时,会在其框之前和之后生成“换行”,所以处于

正常流中的块级元素会“垂直”摆放
选择器 {
    display: block、list-item 或 table;
}
复制代码

:bulb:(“正常流”是指:西方语言文本从左向右、从上向下显示的方向,这也是我们熟悉的传统 HTML 文档的文本布局方向。注意,在非西方语言中,流方向可能不同。)

但,元素是否是“块级元素”仅是元素本身的属性,并不直接用于格式化上下文的创建或布局。

一个“块级元素”会被格式化成一个块(例如文章的一个段落),且默认按照垂直方向依次排列。

:bulb:一个“块级元素”都会至少生成一个“块级盒子”,也有可能生成多个(例如列表项元素)。而“块级盒子”才会参与“块格式化上下文(block formatting context)”的创建。

3.1.2 “行内级元素”和“行内盒子”

当元素的 display 属性为 inline、inline-blockinline-table 时,该元素将成为“行内级元素”。

选择器 {
    display: inline、inline-block 或 inline-table;
}
复制代码

这些元素不会在之前或之后生成“行分隔符”,所以处于正常流中的块级元素会 “水平” 摆放,它们是块级元素的后代。

显示时,它 不会生成内容块 ,但是可以与其他行内级内容一起显示为多行。

:bulb:同理,“行内级元素”会生成“行内级盒子”,该盒子同时会参与“行内格式化上下文(inline formatting context)”的创建。

:trophy:小总结:相对更详细的“盒子”细分:

CSS——CSS 基本视觉格式化:① “块盒子”格式化

:warning: 注意 :一定要记得的是,display 之所以得名,是因为它影响的是元素如何“显示”,而不影响他本质上是何种元素,也就不能乱玩“嵌套关系”!

一个极端的反例就是:你不能让一个“链接”来包围一个“段落”。

<a href="http://…" style="display: block;">
<p style="display: inline;">这是一个错误的示例</p>
</a>
复制代码

(对于生成不同类型“盒子”在实际项目中的运用,我们将在后续文章详细讨论。例如:怎样给“链接”加样式——生成导航栏、怎样给“表单”加样式等。)

3.2不同类型“盒子”在格式化方式上也有所不同

本篇我们主要探讨 “块盒子”格式化,下篇文章讨论“行内盒子”格式化。

CSS——CSS 基本视觉格式化:① “块盒子”格式化

块盒子

3.2.1水平格式化

正常流中,“块盒子”的水平部分 = 其父元素的 width = 7 个属性之和——(margin-left :heavy_plus_sign:margin-right) :heavy_plus_sign: (padding-left :heavy_plus_sign: padding-right):heavy_plus_sign:(border-left :heavy_plus_sign: border-right):heavy_plus_sign: 内容区自身 width 。

在这 7 个属性中只有 3 个属性的值可以设置为 auto:width、margin-left、margin-right。其余的要不必须是确定的值,要不就是默认值 0。

CSS——CSS 基本视觉格式化:① “块盒子”格式化

:rocket:可详细分为以下 5 种组合:

  • 3 个都不是 auto:按 CSS 的术语来讲,这叫“格式化属性过分受限”, 此时总会把 margin-right 强制为 auto 来适应父元素的宽度
  • 2 个不是 auto:是 auto 的将自动调整到适应父级元素的宽度;
  • margin-left、margin-right 是 auto:他们会自动设置为相等的长度, 导致此元素在其父级元素中居中
  • 一个 margin 和 width 是auto:auto 的 margin 会减为0,width 自动填充其包含块;
  • 3 个都是 auto:两个外边距减为 0,width 会尽可能的宽(自动充满)。

:warning:注意:由于 水平 margin 不会合 并,父元素的 padding 、边框、margin 可能会对子元素带来“偏移”的影响。

3.2.2垂直格式化

正常流中,“块盒子”的垂直部分 = 其父元素的 heigh t = 7 个属性之和——(margin-top :heavy_plus_sign: margin-bottom) :heavy_plus_sign: (padding-top :heavy_plus_sign: padding-bottom):heavy_plus_sign:(border-top :heavy_plus_sign: border-bottom):heavy_plus_sign: 内容区自身 height 。

同理,在这 7 个属性中只有 3 个的值可以设置为 auto:height、margin-top、margin-bottom。其余的要不必须是确定的值,要不就是默认值 0。

:warning:不过,margin-top 和 margin-bottom 设置为 auto 也没有什么用,因为会被重置为 0。所以,想利用上下 margin 都是 auto 来垂直居中是不可能的。

CSS——CSS 基本视觉格式化:① “块盒子”格式化

垂直格式化的另一个重要方面是垂直相邻 margin 的合并。

这种合并行为只应用于 margin,如果元素有 padding 和边框,padding 和边框是不会合并的。当两个或更多垂直 margin 相遇时,他们将形成唯一一个 margin,这个 margin 的高度等于两个发生叠加的 margin 的高度中的较大者。

:warning:注意:当一个元素包含在另一个元素中时,彼此相邻的 margin-bottom 和 magin-top 也会发生叠加,取较大者。

3.2.3 负 margin

提问:水平或垂直方向各自 7 大属性相加要等于父元素的 width 或 height,那 margin 为负值会造成什么结果?

1. 水平方向

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
<div>
  <p class="wide">How are you?</p>
  <p>Fine,thank you,and you?</p>
</div>
</body>
</html>
复制代码

(1)类型①

div {
    width: 400px;
    border: 3px solid black;
}

p.wide {
    border: 1px dashed black;
    margin-left: 20px;
    width: auto;
    margin-right: -50px;
    background-color: yellow;
}
复制代码

(2)类型②

div {
    width: 400px;
    border: 3px solid black;
}

p.wide {
    border: 1px dashed black;
    margin-left: 20px;
    width: 500px;
    margin-right: auto;
    background-color: yellow;
}
复制代码

(3)类型③

div {
    width: 400px;
    border: 3px solid black;
}

p.wide {
    border: 1px dashed black;
    margin-left: -50px;
    width: auto;
    margin-right: 10px;
    background-color: yellow;
}
复制代码
CSS——CSS 基本视觉格式化:① “块盒子”格式化

2. 垂直方向

(1)类型 ①:负 margin-top

:link:效果及源码链接

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
<div>
  <p class="wide1">How are you?</p>
  <p class="wide2">Fine,thank you,and you?</p>
</div>
</body>
</html>
复制代码
div {
    width: 400px;
    border: 3px solid black;
}

p.wide1 {
    border: 1px dashed black;
    margin-top: -20px;  /*修改这里的值来观察效果*/

    margin-right: 20px;
    margin-bottom: 30px;
    margin-left: 20px;
    width: auto;
    background-color: yellow;
}   
  
p.wide2 {
    border: 1px dashed black;
    margin-top: ;
    margin-right: 20px;
    margin-bottom: ;
    margin-left: 20px;
    width: auto;
    background-color: grey;
}
复制代码
CSS——CSS 基本视觉格式化:① “块盒子”格式化

:bulb:把段落1的 margin-top 设为“负”,它就被向上“拉”了 20 像素,且紧挨它的段落2也相应向上拉了 20 像素。

(2)类型 ②:负 margin-bottom

:link:效果及源码链接

div {
    width: 400px;
    border: 3px solid black;
}

p.wide1 {
    border: 1px dashed black;
    margin-top: px;
    margin-right: 20px;
    margin-bottom: -50px;  /*修改这里的值来观察效果*/

    margin-left: 20px;
    width: auto;
    background-color: yellow;
}   
    
p.wide2 {border: 1px dashed black;
         margin-top: ;
         margin-right: 20px;
         margin-bottom: ;
         margin-left: 20px;
         width: auto;
         background-color: grey;
}
复制代码
CSS——CSS 基本视觉格式化:① “块盒子”格式化

:bulb:把段落1的 margin-bottom 设为“负”,段落2会根据段落1底端的位置放置。

(3)类型 ③:正负 margin 合并

“块盒子”重叠的时候,如果垂直 margin 都为负值,浏览器会取两个 margin 绝对值的最大值;如果一个正 margin 与一个负 margin 合并,则会从正 margin 减去这个负 margin 的绝对值。

:link:效果及源码链接
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
<div>
 <ul>
  <li>Fine</li>
  <li>thank you</li>
  <li>and you?</li>
 </ul>
<p>回答 How are you? 的方式!</p>
</div>
</body>
</html>
复制代码
div {
    width: 400px;
    border: 3px solid black;
}

ul {
    border: 1px dashed black;
    margin-top: px;
    margin-right: 20px;
    margin-bottom: -15px;  /*①修改这里的值来观察效果*/
    margin-left: 20px;
    width: auto;
    background-color: yellow;
}   
    
li {
    border: 1px dashed black;
    margin-top: ;
    margin-right: 20px;
    margin-bottom: 20px;   /*②修改这里的值来观察效果*/
    margin-left: 20px;
    width: auto;
    background-color: grey;
}

p {
    border: 1px dashed black;
    margin-top: -18px;  /*①修改这里的值来观察效果*/
    margin-right: 20px;
    margin-bottom: px;
    margin-left: 20px;
    width: auto;
    background-color: yellow;
}
复制代码
CSS——CSS 基本视觉格式化:① “块盒子”格式化

:bulb:ul 和 p 重叠的 margin 都为“负”,则取绝对这较大者(-18px)

CSS——CSS 基本视觉格式化:① “块盒子”格式化

:bulb:当上边的较大者(-18px)增加到 li 的最大正 margin 上(20px)时,就得到了 20px - 18px =2px

后记:这篇我们学习了“块盒子”的格式化方式,下一篇我们接着这篇继续探讨“行内盒子”的格式化方式。在“行内盒子”格式化方式中,我们会谈到很多细小的基础知识,和本篇的学习方式一样,让我们尽可能的用代码、用图片来攻克它们。

加油!


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Master Switch

The Master Switch

Tim Wu / Knopf / 2010-11-2 / USD 27.95

In this age of an open Internet, it is easy to forget that every American information industry, beginning with the telephone, has eventually been taken captive by some ruthless monopoly or cartel. Wit......一起来看看 《The Master Switch》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

html转js在线工具
html转js在线工具

html转js在线工具