前言
由于有很多知识非常符合直觉或者和其他语言有通用性,因此个人觉得不需要全部记下来,本篇只记录一些个人觉得需要注意或单独记忆的知识点。
本篇主要涉及盒模型。
盒模型
1. 块级盒子(Block box)和 内联盒子(Inline box)
在 CSS 中我们广泛地使用两种“盒子” —— 块级盒子 (block box
) 和 内联盒子 (inline box
)。这两种盒子会在页面流(page flow
)和元素之间的关系方面表现出不同的行为:
一个被定义成块级的(block
)盒子会表现出以下行为:
- 盒子会在内联的方向上扩展并占据父容器在该方向上的所有可用空间,在绝大数情况下意味着盒子会和父容器一样宽
- 每个盒子都会换行
width
和height
属性可以发挥作用- 内边距(
padding
), 外边距(margin
)和 边框(border
)会将其他元素从当前盒子周围“推开”
除非特殊指定,诸如标题 (<h1>
等) 和段落 (<p>
) 默认情况下都是块级的盒子。
如果一个盒子对外显示为 inline
,那么他的行为如下:
- 盒子不会产生换行
- width 和 height 属性将不起作用
- 垂直方向的内边距、外边距以及边框会被应用但是不会把其他处于 inline 状态的盒子推开
- 水平方向的内边距、外边距以及边框会被应用且会把其他处于 inline 状态的盒子推开
用做链接的 <a>
元素、 <span>
、 以及 都是默认处于 inline 状态的。
我们通过对盒子display
属性的设置,比如 inline
或者 block
,来控制盒子的外部显示类型。
后续还会涉及到 弹性盒子(Flexbox),置
display: flex
,在一个元素上,外部显示类型是block
,但是内部显示类型修改为flex
。后面再仔细记录
2. 不同显示类型的例子
直接根据下面的代码和实际表现来理解
(1)例1
p,
ul {
border: 2px solid rebeccapurple;
padding: .5em;
}
.block,
li {
border: 2px solid blue;
padding: .5em;
}
ul {
display: flex;
list-style: none;
}
.block {
display: block;
}
<p>I am a paragraph. A short one.</p>
<ul>
<li>Item One</li>
<li>Item Two</li>
<li>Item Three</li>
</ul>
<p>I am another paragraph. Some of the <span class="block">words</span> have been wrapped in a <span>span element</span>.</p>
效果如下
(2)例2
p,
ul {
border: 2px solid rebeccapurple;
}
span,
li {
border: 2px solid blue;
}
ul {
display: inline-flex;
list-style: none;
padding: 0;
}
.inline {
display: inline;
}
<p>
I am a paragraph. Some of the
<span>words</span> have been wrapped in a
<span>span element</span>.
</p>
<ul>
<li>Item One</li>
<li>Item Two</li>
<li>Item Three</li>
</ul>
<p class="inline">I am a paragraph. A short one.</p>
<p class="inline">I am another paragraph. Also a short one.</p>
效果如下
3. 什么是 CSS 盒模型
完整的 CSS 盒模型应用于块级盒子,内联盒子只使用盒模型中定义的部分内容。模型定义了盒的每个部分 —— margin, border, padding, and content —— 合在一起就可以创建我们在页面上看到的内容。为了增加一些额外的复杂性,有一个标准的和替代(IE)的盒模型
(1)盒模型的各个部分
CSS 中组成一个块级盒子需要:
- Content box:显示内容。大小通过
width
和height
设置 - Padding box:内边距,包围在内容区域外部的空白区域。大小通过
padding
相关属性设置 - Border box:边框,包裹住内容和内边距。大小通过
border
相关属性设置 - Margin box:最外层的外边距,是盒子和其他元素之间的空白区域。大小通过
margin
相关属性设置
如图所示:
(2)标准盒模型
在标准模型中,如果你给盒设置 width
和 height
,实际设置的是 content box
。padding
和 border
再加上设置的宽高一起决定整个盒子的大小。见下图。
假设定义了 width
, height
, margin
, border,
padding
:
.box {
width: 350px;
height: 150px;
margin: 25px;
padding: 25px;
border: 5px solid black;
}
如果使用标准模型,实际占用空间的宽高分别为:
宽 = 410px (350 + 25 + 25 + 5 + 5)
高度 = 210px (150 + 25 + 25 + 5 + 5)
备注:
margin
不计入实际大小 —— 当然,它会影响盒子在页面所占空间,但是影响的是盒子外部空间
盒子的范围到边框为止 —— 不会延伸到margin
(3)替代 (IE) 盒模型
使用这个模型,所有宽度都是可见宽度,所以内容宽度是该宽度减去边框和填充部分。
使用上面相同的样式得到 (width = 350px, height = 150px)
默认浏览器会使用标准模型。如果需要使用替代模型,可以通过为其设置 box-sizing: border-box
来实现
.box {
box-sizing: border-box;
}
如果希望所有元素都使用替代模式,而且确实很常用,设置 box-sizing
在 <html>
元素上,然后设置所有元素继承该属性,正如下面的例子:
html {
box-sizing: border-box;
}
*, *::before, *::after {
box-sizing: inherit;
}
(4)尝试修改代码使两种模型显示一样大的盒子
.box {
border: 5px solid rebeccapurple;
background-color: lightgray;
padding: 40px;
margin: 40px;
width: 300px;
height: 150px;
}
.alternate {
box-sizing: border-box;
width: 390px;
height: 240px;
}
<div class="box">I use the standard box model.</div>
<div class="box alternate">I use the alternate box model.</div>
4. 外边距,内边距,边框
(1)外边距
外边距是盒子周围一圈看不到的空间。它会把其他元素从盒子旁边推开。外边距属性值可以为正也可以为负。设置负值会导致和其他内容重叠。无论使用标准模型还是替代模型,外边距总是在计算可见部分后额外添加。
我们可以使用margin
属性一次控制一个元素的所有边距,或者每边单独使用等价的普通属性控制:
- margin-top
- margin-right
- margin-bottom
- margin-left
示例:
.box {
margin-top: -40px;
margin-right: 30px;
margin-bottom: 40px;
margin-left: 4em;
}
<div class="container">
<div class="box">Change my margin.</div>
</div>
效果如下
(2)外边距折叠
如果有两个外边距相接的元素,这些外边距将合并为一个外边距,即最大的单个外边距的大小。
例如有两个段落,顶部段落的页 margin-bottom为 50px,第二段的margin-top 为 30px。因为外边距折叠的概念,所以框之间的实际外边距是 50px,而不是两个外边距的总和
(3)边框
边框是在边距和填充框之间绘制的。
为边框设置样式时,有大量的属性可以使用——有四个边框,每个边框都有样式、宽度和颜色,我们可能需要对它们进行操作。
也可以使用border属性一次设置所有四个边框的宽度、颜色和样式。
分别设置每边的宽度、颜色和样式,可以使用:
- border-top
- border-right
- border-bottom
- border-left
设置所有边的颜色、样式或宽度,可以使用:
- border-width
- border-style
- border-color
设置单边的颜色、样式或宽度,可以使用最细粒度的普通属性之一:
- border-top-width
- border-top-style
- border-top-color
- border-right-width
- border-right-style
- border-right-color
- border-bottom-width
- border-bottom-style
- border-bottom-color
- border-left-width
- border-left-style
- border-left-color
(4)内边距
内边距位于边框和内容区域之间。与外边距不同,不能有负数的内边距,所以值必须是 0 或正的值。
应用于元素的任何背景都将显示在内边距后面,内边距通常用于将内容推离边框。
我们可以使用padding
简写属性控制元素所有边,或者每边单独使用等价的普通属性:
- padding-top
- padding-right
- padding-bottom
- padding-left
5. 盒子模型和內联盒子
以上所有的方法都完全适用于块级盒子。有些属性也可以应用于内联盒子,例如由<span>
元素创建的那些内联盒子。
在下面的示例中,我们在一个段落中使用了<span>
,并对其应用了宽度、高度、边距、边框和内边距。可以看到,宽度和高度被忽略了。外边距、内边距和边框是生效的,但它们不会改变其他内容与内联盒子的关系,因此内边距和边框会与段落中的其他单词重叠(也就是不会推开)。
span {
margin: 20px;
padding: 20px;
width: 80px;
height: 50px;
background-color: lightblue;
border: 2px solid blue;
}
<p>
I am a paragraph and this is a <span>span</span> inside that paragraph. A span is an inline element and so does not respect width and height.
</p>
效果如下
6. 使用display: inline-block
使用display: inline-block
可以实现这种情况,就是不希望一个项切换到新行,但希望它可以设定宽度和高度。
一个元素使用 display: inline-block
,会实现我们需要的块级的部分效果:
- 设置
width
和height
属性会生效 padding
,margin
, 以及border
会推开其他元素
但是,它不会跳转到新行,如果显式添加 width
和 height
属性,它只会变得比其内容更大。
在下一个示例中,我们将 display: inline-block
添加到 <span>
元素中
span {
margin: 20px;
padding: 20px;
width: 80px;
height: 50px;
background-color: lightblue;
border: 2px solid blue;
display: inline-block;
}
<p>
I am a paragraph and this is a <span>span</span> inside that paragraph. A span is an inline element and so does not respect width and height.
</p>
效果如下
总结
只记录了 CSS 的部分内容