WEB基础之:CSS基本视觉格式化
基本视觉格式化
1. 基本框Basic Boxes
CSS 假定每个元素都会生成一个或多个矩形框,称为元素框。各元素框的中心有一个内容区(content area)。内容区周围有可选填充(padding)、边框(borders)、轮廓(outlines)和外边距(margins)。
边框(border)与内容(content)和内边距(padding)有相同的背景。另外边框的宽度不能为负。
2. 元素显示选择Altering Element Display
通过设置display属性值来影响用户代理的显示方式。
属性值类别 | 描述 |
---|---|
<display-outside>`` | block / inline(default) / run-in` | |
<display-inside>`` | flow / flow-root / table / flex / grid / ruby` | |
<display-listitem> | list-item&&<display-outside>?&&[ flow / flow-root ]? |
<display-internal> | table-row-group / table-header-group / table-footer-group / table-row / table-cell / table-column-group / table-column / table-caption / ruby-base / ruby-text / ruby-base-container / ruby-text-container |
<display-box> | contents / none |
<display-legacy> | inline-block / inline-list-item / inine-table / inline-flex / inline-grid |
2.1 将行内样式显示为块级样式
例如,配置如下导航链接:
<nav>
<a href="index.html">WidgetCo Home</a>
<a href="products.html">Products</a>
<a href="services.html">Services</a>
<a href="fun.html">Widgety Fun!</a>
<a href="support.html">Support</a>
<a href="about.html" id="current">About Us</a>
<a href="contact.html">Contact</a>
</nav>
默认情况下,导航中每个元素显示为行内样式;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RPbAwSI7-1608194868701)(https://i.loli.net/2020/11/08/lTCEvndq35OJtGe.png)]
将导航中每个元素以列表样式显示:实现方式如下
- 将所有链接放到表格单元格
- 将所有链接显示在各自独立的导航中
- 将所有链接以块级元素显示。如下:
nav a {
display: block;
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kV0rahT9-1608194868707)(https://i.loli.net/2020/11/08/BakD34cvfOI8Fym.png)]
**注:**将链接作为块,您可以像 div 或 p 元素那样对它们进行样式设置,其优点是整个元素框成为链接的一部分。因此,如果用户的鼠标指针停留在元素框中的任何位置,则可以单击链接。
2.2 将列表元素显示为行内样式
- 只能改变他们的显示角色。
例如配置如下列表:
<ul id="rollcall">
<li>Bob C.</li>
<li>Marcio G.</li>
<li>Eric M.</li>
<li>Kat M.</li>
<li>Tristan N.</li>
<li>Arun R.</li>
<li>Doron R.</li>
<li>Susie W.</li>
</ul>
将列表元素变成各个元素之间有竖线的行内样式。
#rollcall li {
border-right: 1px solid;
display: inline;
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ybPfpmjX-1608194868711)(https://i.loli.net/2020/11/08/6LsGjJxVapuP4dh.png)]
3. 块级元素
默认情况下width被定义为内容区的宽度,height则定义内容区的高度。可以使用box-sizing 属性改变这些属性的处理方式。
- box-sizing
box-sizing 属性允许你以某种方式定义某些元素,以适应指定区域。
box-sizing: content-box (default) | padding-box | border-box
3.1 水平格式化
水平格式通常比您想象的更复杂。部分复杂性与 box-sizing
的默认行为有关。使用默认值 content-box
,指定的宽度值将影响内容区域的 width
,而不是整个可见元素框的 width
。
如果当定义一个 <div> 容器的 box-sizing 属性为 border-box 时,并配置:
box-sizing: border-box; width: 100px; padding: 10px; border: 10px solid gold;
那么最终div容器的实际宽度为 100px, 内容部分(content)的有效宽度变成了 100px-2*10px-2*10px=60px;
如果定义一个 <div> 设置 box-sizing 属性为content-box(默认),并设置:
box-sizing: content-box; width: 100px; padding: 10px; border: 10px solid gray;
那么最终 div 容器的实际宽度为:
100px(width)+2*10px*(padding)+2*10px(border)=140px
内容部分(content)的宽度为100px;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IqM73xyV-1608194868716)(https://i.loli.net/2020/11/08/pyYeD8cokCnaOQ1.png)]
注意:margin 的尺寸不会被计算入最终容器宽度,因为对他的定义为对这个容器的留白,但不属于容器本身。
3.1.1 水平属性Horizontal Properties
水平格式化的 “7大属性” 是 margin-left
, border-left
, padding-left
, width
, padding-right
, border-right
, 和 margin-right
。
在这7个属性中,只有3个属性可以设置为auto: margin-left
, width
, margin-right
。其余属性必须设置特定的值(默认值为0).
3.1.2 Using auto
- 某个设置为auto
如果设置 **margin-left
, width
, margin-right
**中的某个值为auto,而余下两个属性指定为特定的值,那么设置为auto的属性会确定所需的长度,从而使元素框的宽度等于父元素的width。
假设 7 个属性的总和必须等于 500 像素,没有设置填充或边框,右边框(margin-right)和宽度(width)设置为“100px”,左边框设置为“auto”。因此,左边框(margin-left)将为 300 像素宽:
#using_auto {
width: 500px;
background: gold;
}
p {
margin-left: auto;
margin-right: 100px;
width: 100px;
background: white;
}
<div id="using_auto">
<p>A paragraph</p>
</div>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZFMNC6tO-1608194868719)(https://i.loli.net/2020/11/08/dBGu38FafDtENSC.png)]
- 过度约束overconstrained
如果将margin-left
, width
, margin-right
都设置为某个值,用 CSS 术语来说,这些格式化属性被“过度约束(overconstrained)”时,此时总会将**margin-right
强制为auto**。
p {
margin-left: 100px;
margin-right: 100px;
width: 100px;
background: white;
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pQ80DLZk-1608194868722)(https://i.loli.net/2020/11/08/KpfyeUjoVkJWwR3.png)]
- 自动宽度
最为常见应用,等价于只设置外边框,而没有设置任何width声明,如:
p {
margin-left: 100px;
margin-right: 100px;
background: white;
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cfQd29aP-1608194868724)(https://i.loli.net/2020/11/08/Z3tOwaujr5GplXD.png)]
- 不只一个auto
如果两个外边距(margin)都设置为auto,它们将会设置为相等的长度,内容将会在父元素居中显示。
p {
margin-left: auto;
margin-right: auto;
width: 100px;
background: white;
}
- 全部设置为auto
如果这三个属性全部设置为auto,两个外边距都会设置为0,而width会尽可能宽。
p {
margin-left: auto;
margin-right: auto;
width: auto;
background: white;
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lNJCtUNO-1608194868726)(https://i.loli.net/2020/11/08/l94ChI35VLfnjKg.png)]
3.1.3 负外边距Negative Margins
- 外边距可以为负值
只要7个水平属性的总和等于父元素的width,只要所有属性都是大于或等于0的,元素就不会大于其父元素的内容区。
#negative_margins {
width: 500px;
border: 3px solid black;
}
p {
margin-left: 10px;
width: auto;
margin-right: -50px;
background: gold;
}
<div id="negative_margins">
<p>A paragraph</p>
</div>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-X1qkanb6-1608194868727)(https://i.loli.net/2020/11/08/YNoqwbShODgz5QK.png)]
子元素的宽度大于父元素,但并没有违反规范,因为7个水平属性值总和等于总宽度,数据计算并没有错误:10px+0+0+540+0+0-50px=500px。
- 还有可能因为设置auto将右外边距设置为负值。如下:
#negative_margins {
width: 500px;
border: 3px solid black;
}
p {
margin-left: 10px;
border: 3px solid gold;
width: 600px;
margin-right: auto;
}
<div id="negative_margins">
<p>A paragraph</p>
</div>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-g6vhtzlH-1608194868729)(https://i.loli.net/2020/11/08/Mse8vOzyTKB2l5P.png)]
- 如查左外边距为负,不仅段落会超出div的边框,还会超出浏览器容器本身的边界。
p {
margin-left: -50px;
border: 3px solid gold;
width: 400px;
margin-right: auto;
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-38B4cPiE-1608194868731)(https://i.loli.net/2020/11/08/YLE1bX6Ze59kfDC.png)]
3.1.4 百分数percentage
如下相要设置一个元素的内容是其包含块的2/3,左右填充各为5%,左外边距为5%,则右外边距为:100%-67%-5%-5%-5%=18%
<p style="width: 67%; padding-right: 5%; padding-left: 5%; margin-right: auto; margin-left: 5%;">
playing percentages
</p>
混合百分比和长度单位使用,不过在此不做谈论。
3.1.5 替换元素Replaced Elements
如果实际图像的宽度是 100 像素,那么它将被设置为 100 像素宽。可以通过为“width”指定一个特定的值来覆盖这个规则,为每个图像设置不同的宽度值:
<img src="smile.svg" style="display: block; width: 25px; margin: 0;" />
<img src="smile.svg" style="display: block; width: 50px; margin: 0;" />
<img src="smile.svg" style="display: block; width: 100px; margin: 0;" />
3.2 垂直格式化Vertical Formatting
一个元素的默认高度由其内容决定。高度还会受到内容宽度的影响。段落越窄,相应地高度就越高,以便容纳其中所有的行内内容。
额外的高度具有类似于额外填充的视觉效果。
<p style="height: 12em; width: 20em; border: solid gold;">...</p>
但是假设高度“小于”显示内容所需的高度:
<p style="height: 2em; width: 20em; border: solid gold;">...</p>
在元素的内容比其框的高度高的情况下,用户代理的实际行为将取决于属性“overflow”的值。
3.2.1 垂直属性Vertical Properties
- 垂直格式化的7大属性:
margin-top
,border-top
,padding-top
,height
,padding-bottom
,border-bottom
, andmargin-bottom
. - 这7个属性的值总和必须等于元素包含块的height。
- 只有
margin-top
,height
,margin-bottom
可以设置为auto。上、下填充和边框必须设置为特定的值(默认为0). - 如果正常流中一个块元素的
margin-top
或margin-bottom
设置为auto,则会自动计算为0。如果值为0,则不能容易地将流元素在其包含块中垂直居中。 - 'height 必须设置为auto,或设置为某种类型的非负值;它永远不会小于零。
3.2.2 百分数高度
不同情况下的百分数高度是不一样的,显式声明包含块的height,子元素得到的高度将是父元素的一半。
如果未显式声明包含块的htight,百分数高度会重置为“auto”。使’ div ‘的’ height ‘为’ auto ‘,那么段落的高度将与’ div '本身一样高:
3.2.3 auto高度
具有“height: auto”的正常流块框的呈现高度刚好能够将其行内内容(包括文本)的行框括起来。如果一个 auto的height, normal-flow 块框只有块级别的子元素,那么它的默认高度将是最顶层块级别子元素的外边框边缘到最底层块级别子元素的外边框边缘底部的距离。
如果块级元素有顶部或底部填充,或顶部或底部边框,那么它的高度将是其最顶层的子元素的外边框边界到其最底端的子元素的外边框边界之间的距离;
3.2.4 重叠垂直外边距Collapsing Vertical Margins
垂直格式化的重叠行为只应用于margin,padding与border不会重叠。
重叠举例:
li {
margin-top: 10px;
margin-bottom: 15px;
}
如声明所示,每个列表项有10像素的margin-top,15像素的margin-bottom,但浏览器显示这个列表时,相邻列表之间的距离为15像素,而不是25像素。原因是相邻margin,会取较大margin进行显示。
3.2.5 负外边距与重叠Negative Margins and Collapsing
- 负外边距会影响外边距如何重叠。如果垂直外边距都设置为负值,浏览器会取两个外边距绝对值的最大值。
- 如果一正、一负外边距重叠,浏览器会取:“正外边距-负外边距的绝对值”。
- 负margin-top会使元素看上去向上拉。
- 负margin-bottom会使段落看上去被向下拉。
- 如果同时为负,则为最大负外边距的绝对值-最小负外边距的绝对值。
3.2.6 列表项
与一个列表项元素关联的标志可能在列表内容之外,也可能处理为内容开始处的一个行内标志,取决于list-style-position
值:
- 如果标志放在外部,列表项会放在与内容边界的有一定距离的位置上。
- 如果标志放在内部,那么列表项相对于相邻列表就像一个块级元素一样。
- 无论列表样式如何改变,标志与内容边界的距离都不变。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TbXGIuuM-1608194868733)(https://i.loli.net/2020/11/09/FnLVDvXAez4BRGt.png)]
4. 行内元素Inline Elements
4.1 基本术语和概念Basic Terms and Concepts
4.1.1 基本术语
- 匿名文本(Anonymous text):指所有未包含在行内元素中的字符串。如标记
<p> I'm <em>so</em> happy!</p>
中, “I’m” 与 “ happy!” 都是匿名文本。注意,空格也是匿名文本的一部分。 - em框(Em box):font-size值决定了每个em框的高度。也称字符框(character box)。
- 内容区(Content area):
- 一种是元素中各字符的em框串在一起构成的框,即行内非替换元素。
- 另一种是由元素中字符字形描述的框。即,行内替换元素:元素固有宽高,边距、边框。
- 行间距(Leading):
- 行内非替换元素:等于
font-size
与line-height
的差,这个差实际上要分成两半,分别应用到内容区的顶部和底部。 - 行内替换元素:没有行间距的概念
- 行内非替换元素:等于
- 行内框(Inline box):
- 行内非替换元素:行内框的高度等于
line-height
的值。 - 行内替换元素:行内框的高度等于内容区的高度,因为行间距没有行间距概念。
- 行内非替换元素:行内框的高度等于
- 行框(Line box):当前行中出现的行内框的最高点和最低点的最小框。
4.1.2 概念
- 内容区类似于块级元素的内容框
- 行内元素的背景作用于内容区以及内边距
- 行内元素的边框包围内容区、内边距和边框
- 非替换元素的margin、padding、border不会影响行内框高度
- 替换元素的margin、border会影响行内框高度
- 可以为除了行内非替换元素外的任意元素设置垂直外边距
4.2 行内非替换元素
4.2.1 建立框
对于行内替换元素或匿名文本某一部分,font-size值确定了内容区的高度。如标记:font-size: 15px;
则内容区的高度为15px,因为元素中所有em框的高度都15px。
若再增加标记line-height:21px
,font-size
与line-height
相差6px,用户代理将这6px一分为二,将其一半分别应用到内容区的顶部和底部,得到行内框。即:内容区+行间距=行内框。
5. 百分数参数总结
- 对margin/padding使用百分数将会相对于包含块的内容区宽度计算
- 对于height属性使用百分数将会相对于包含块内容区的高度计算
- 对于定位元素(position属性非static)的top、bottom属性使用百分数将会相对于包含块高度计算
- 不允许对border属性使用百分数