界面布局 - 基本规则
CSS 一个重点应用就是: 页面布局
页面布局就是:设置 网页元素 的位置、以及和周围的其他元素位置关系。
通俗的说,就是怎么摆放页面元素。
block 和 inline
元素的显示模式 分为: block
(块模式) 和 inline
(内联模式)
两种显示模式决定了元素不同的展示结果
不同的元素,有不同的默认显示模式,比如 p 默认就是 block模式, span 默认就是 inline模式
block模式 和 inline模式 最直观的差别是,前者会独占一行显示,后者尽量跟随前面的元素显示在一行中
<p>块元素1</p>
<span>内联元素1</span>
<p>块元素2</p>
<span>内联元素3</span>
<span>内联元素4</span>
<p>块元素3</p>
我们可以设置 css属性 display
的值为 block
或者 inline
, 从而改变显示模式。
<p>块元素1</p>
<span>内联元素1</span>
<p>块元素2</p>
<span>内联元素3</span>
<span>内联元素4</span>
<p style='display:inline'>块元素3</p>
block 模式
如果一个元素 是 block 模式,显示特征如下:
-
新开一行 显示该元素
块级元素会
新开一行
显示,不管前面的元素是 内联元素 还是 块级元素。 -
水平方向,占满它的父元素可用空间
所以块级元素 通常会和上层元素一样宽
-
垂直方向,占据的空间由其内容大小决定
-
可以通过 css 属性
width
、height
设置该元素的宽和高
- css 属性
padding
、margin
、border
决定其他元素 和 该元素的间隔
缺省就是 block 模式的 元素有如下这些
address
article
aside
blockquote
dd
div
dl
dt
footer
form
h1 h2 h3 h4 h5 h6
header
hr
li
main
nav
ol
p
pre
section
table
ul
另外,浏览器 缺省把 body 元素 也显示为 block
inline 模式
如果一个元素 是 inline 模式,显示特征如下:
-
不会新开一行 显示该元素
只要 当前行有剩余空间可以容纳自身内容,就会显示在里面。如果没有剩余空间,才会移到下一行。
如果前面的兄弟元素是inline模式,往往会在同行显示
如果前面的兄弟元素是block模式,则会在不同行显示
-
css 属性 width 、 height 不起作用
内联元素的大小就是其内容的大小,无法通过 width 、 height 属性进行设置
除非你通过修改display属性值为 block 或者 inline-block 改变其内联本质。
-
垂直方向的 属性 padding、 margin 、 border 有效果,但是不能把其他的inline元素 隔开
-
水平方向的 属性 padding、 margin 、 border 决定其他元素 和 该元素的间隔
缺省就是 inline 模式的 元素很多,常见的有
a
audio
b
br
button
canvas
em
embed
i
iframe
img
input
label
select
span
strong
svg
textarea
video
inline-block
inline-block
也是常用的display模式
通常用在 按钮 之类的方块状元素上
好处是,让这些元素既有inline的不换行的特征, 也可像block元素一样设置 width 、 height、margin、padding
比如
<head>
<style>
ul {
list-style-type:none;
}
li {
display:inline-block;
margin: 2em;
width: 150px;
background-color: #755ac3;
color: #fff;
border-radius: 100px;
text-align: center;
}
</style>
</head>
<body>
<ul class="wrapper">
<li>自动化软件测试</li>
<li>性能测试</li>
<li>QT</li>
<li>Django</li>
<li>爬虫数据处理</li>
<li>web前端开发</li>
</ul>
</body>
li 默认是 block 模式的, 如果不设置为 inline-block, 所有的元素都是单独一行, 就可能不符合设计者的要求。
包含块
浏览器呈现界面时,每个html 元素(不管是block模式还是inline模式)都对应一个 显示 方块区。
这个方块区 被称为 包含块 (containing block)
由内到外,这个包含块 区域可以分为四部分:
-
Content区
也就是实际内容区
-
Padding 区
又被称为 内边距 区
-
Border 区
又被称为 边框 区
-
Margin 区
又被称为 外边距 区
如下图所示
如果一个block元素,没有其它兄弟元素,它的 包含块 就是其 最近的
块级(非inline元素)上级元素
的 Content区。
初始包含块(initial containing block) ,范围是 整个浏览器 内容窗口区(viewport)
HTML文档中最上层的 html
标签元素 的包含块 就被包含在 初始包含块
里面,(范围小于初始包含块)
看一下这个例子
<!DOCTYPE html>
<html>
<head>
<style>
html {
border: 5px dashed green;
}
body {
border: 5px dashed red;
margin : 20px
}
</style>
</head>
<body>
1
<br>
2
<br>
3
</body>
</html>
可以发现 html 并没有占满所有的viewport高度。
因为html也是块级元素, 显示宽度是 上级viewport 的 整个宽度,高度却是由自身的内容决定的。
如果要让 html、body 占满所有的viewport高度,可以这样设置
body {
margin : 0;
height: 100vh;
}
100vh
就是 100% 的 viewport高度
宽度和高度
可以通过 width
和 height
分别指定 block模式元素的 宽度
和 高度
width
和 height
的值可以是任何的长度单位,比如 10px, 1em,1rem,1vh
等等
比如
{
width : 10px;
height : 2em;
}
缺省情况下,width
和 height
是设置元素 Content区 的宽度和高度
比如
<html>
<head>
<style>
#container {
border : 1px solid blue;
}
#target {
border: 5px solid green;
width : 200px;
height : 100px;
padding: 5px;
margin: 8px;
}
</style>
</head>
<body>
<div id='container'>
<div id='target'>
</div>
</div>
</body>
</html>
你可以为该元素设置 box-sizing: border-box
,这样 width,height设置的就是 可见区
的 宽度和高度, 也就是Border区的外边缘
内间距 padding
padding
属性指定了元素 内边距
,也就是 元素 border内边线
和 元素自身content边界
之间的距离
padding 的值可以是任何的长度单位,比如 10px, 1em, 1rem 等等
指定 padding 的时候,包括 上、下、左、右 四个边的间距
可以用 padding-top
、 padding-bottom
、 padding-left
、 padding-right
分别指定 上、下、左、右 四个边的间距
比如
padding-top : 10px;
padding-bottom : 2em;
padding-left : 2rem;
padding-right : 20px;
也可以直接用 padding
一起指定,常见的有如下这些写法
padding: 10px
四个边的 padding 都是 10px
padding: 10px 20px
第1个参数 指定 上下
两个边的 padding,
第2个参数 指定 左右
两个边的 padding,
padding: 10px 20px 30px
第1个参数 指定 上边
的 padding,
第2个参数 指定 左右
两个边的 padding,
第3个参数 指定 下边
的 padding
padding: 10px 20px 30px 40px
第1个参数 指定 上边
的 padding,
第2个参数 指定 右边
的 padding,
第3个参数 指定 下边
的 padding,
第4个参数 指定 左边
的 padding
外间距 margin
margin
属性指定了元素的 外边距
,也就是 元素 border外边线
和 父元素content边界
之间的距离
margin 的值可以是任何的长度单位,比如 10px, 1em, 1rem 等等
指定margin的时候,包括 上、下、左、右 四个边的间距
可以用 margin-top
、 margin-bottom
、 margin-left
、 margin-right
分别指定 上、下、左、右 四个边的间距
比如
{
margin-top : 10px;
margin-bottom : 2em;
margin-left : 2rem;
margin-right : 20px;
}
也可以直接用 margin
一起指定,常见的有如下这些写法
margin: 10px
四个边的 margin 都是 10px
margin: 10px 20px
第1个参数 指定 上下
两个边的 margin,
第2个参数 指定 左右
两个边的 margin,
margin: 10px 20px 30px
第1个参数 指定 上边
的 margin,
第2个参数 指定 左右
两个边的 margin,
第3个参数 指定 下边
的 margin
margin: 10px 20px 30px 40px
第1个参数 指定 上边
的 margin,
第2个参数 指定 右边
的 margin,
第3个参数 指定 下边
的 margin,
第4个参数 指定 左边
的 margin
有些 HTML 元素有 预置的 非 0 margin 值 (比如: body, h1 - h6, p, fieldset, form, ul, ol, dl, dir, menu, blockquote dd).
body 缺省 margin 为 8px, 会导致 设置为 占满 浏览器窗口高度的 body 出现 垂直滚动条,
比如,下面的示例
<!DOCTYPE html>
<html>
<head>
<style>
body{
height:100vh;
}
div {
height:100px;
border:1px solid blue
}
</style>
</head>
<body>
<div>
1
<br>
2
</div>
</body>
</html>
可以,像这样把 margin改为 0
<style>
body {
height: 100vh;
margin : 0;
}
</style>
调试css
可以在浏览器DevTools 窗口中查看 元素的 宽、高、padding、margin 等等
还可以临时修改添加删除CSS属性,查看效果
详见视频讲解。
百分比
我们常常使用 百分比 指定 宽度、高度、 padding、margin
比如 width: 90%
这个百分比到底是谁 的 百分比呢?是 包含块
的
就是该元素 上级元素中 最贴近的块级 元素 的 Content区。
比如
<html>
<head>
<style>
#container {
border : 1px solid blue;
width : 200px;
height : 400px;
}
#target {
border: 1px solid green;
/* 包含块 宽度的 80% */
width: 80% ;
/* 包含块 高度的 60% */
height: 60% ;
/* 包含块 宽度 的 10% 20% */
padding: 10% 20%;
/* 包含块 宽度 的 5% 10% */
margin: 5% 10%;
}
</style>
</head>
<body>
<div id='container'>
<div id='target'>
</div>
</div>
</body>
</html>
auto
我们经常会看到css设置 margin、padding、height、width 的值为 auto
比如
{
margin: 5% auto;
width: auto;
}
简单的说,auto 就是浏览器会自动选择一个合适的值。
width,height 的默认值(不指定)就是 auto
水平方向
水平方向的 auto 有种含义:占据尽量多的空间
看这个例子
<head>
<style>
#container {
border : 1px solid blue;
height: 300px;
width: 400px;
}
#target {
border: 1px solid green;
margin: 5px;
padding: 5px;
/* width: auto; */
height: 125px;
}
</style>
</head>
<body>
<div id='container'>
<div id='target'>
</div>
</div>
</body>
因为 target元素的 width 值没有指定, 缺省为 auto,
auto含义是占据尽量多的空间,所以水平方向贴满了包含块的可用长度(除了边框本身的宽度和margin)
再看一个例子
<html>
<head>
<style>
#container {
border : 1px solid blue;
height: 300px;
width: 400px;
}
#target {
border: 1px solid green;
margin-left: auto;
width: 250px;
height: 125px;
}
</style>
</head>
<body>
<div id='container'>
<div id='target'>
</div>
</div>
</body>
</html>
margin-left: auto
让里面的target元素左边的margin占据尽可能多的空间,元素就靠右贴边了。
如果改为 margin-right: auto
让target元素右边的margin占据尽可能多的空间,元素就靠左贴边了。
如果改为 margin: auto
, target元素左右margin同时尽可能的占据空间,就会各占一半
所以水平方向居中了,左右的margin各为 74px (要减去border本身1px )
垂直方向
垂直方向和 水平方向的规则不一样。
W3C规范指出:
如果 margin-top
或 margin-bottom
值 为 auto
,则它们的实际值为 0
前面的代码示例,如果改为 margin: auto
, 那么 margin-top
和 margin-bottom
值 都为 auto
,则它们的实际值为 0
从浏览器开发者工具栏也可用看到 target 元素的 上下 margin都是0
由于排布元素的规律是从上到下,从左到右。 所以 target 元素 出现在上方
如果 height
的值为 auto
, 就比较复杂了,
通常来说,是该元素自身的内容决定的。
如果元素本身内容为空,实际的高度为 0
看这个例子
<head>
<style>
#container {
border : 1px solid blue;
height: 300px;
width: 400px;
}
#target {
border: 1px solid green;
margin: 5px;
padding: 5px;
}
</style>
</head>
<body>
<div id='container'>
<div id='target'>
</div>
</div>
</body>
target元素 width、height都没有指定,都是缺省值 auto
水平方向占据了尽可能多的空间
而垂直方向,高度却是 0 ,因为它没有内容
如果给target 元素添加 一个 内部元素,比如
<head>
<style>
#container {
border : 1px solid blue;
height: 300px;
width: 400px;
}
#target {
border: 1px solid green;
margin: 5px;
padding: 5px;
}
</style>
</head>
<body>
<div id='container'>
<div id='target'>
<p> sdfsdf </p>
</div>
</div>
</body>
结果发现,target元素的高度,就是其内部 p元素的的高度
最大/最小 宽度高度
min-width
、 max-width
、min-height
、 max-height
分别用来指定元素的最小宽度、最大宽度、最小高度、最大高度
它们的优先级高于 width
和 height
的优先级
<head>
<style>
.c-modal {
margin: 2em auto;
width:80%;
min-width: 400px;
max-width: 600px;
padding: 1rem;
background: #e2deed;
}
</style>
</head>
<body>
<div class="c-modal">
<p>
hytest 是白月黑羽自己研发的自动化测试框架,
它非常适合 做 系统测试 自动化,
而相比之下,pytest、unittest 更适合白盒的单元测试、集成测试。
</p>
它有如下优点:
<p>
上手非常简单 -
hytest 让大家直接用 Python 来写测试用例。
如果你有 Python编程经验,1小时就可以上手,1天就可以灵活使用。
</p>
<p>
操作直观易懂 - 测试用例以 目录文件结构存放,清晰明了
</p>
<p>
初始化清除 清晰灵活 -
可以灵活地 挑选 要执行的测试用例
</p>
<p>
漂亮的测试报告
</p>
</div>
</body>
可用发现,div.c-modal元素 受 min-width
、 max-width
的影响。
这样,随着窗口的缩放 不至于太长,也不至于太短,否则就会比较难看
可用对比去掉 min-width
、 max-width
的效果
min-height
、 max-height
在高度方面也是有同样的效果
背景色范围
设置一个元素的背景色,有效区域包括这个元素的 内容区、padding部分、border部分。也就是包含块除了margin部分
看这个例子
<!DOCTYPE html>
<html>
<body>
<p style='margin:20px;padding:20px;border: 5px dashed red;
background:lightblue'>
1
<br>
2
<br>
3
</p>
</body>
</html>
但是,如果背景色设置的是根元素 html
,背景色会占据 整个浏览器画布(canvas)。
如下:
<!DOCTYPE html>
<html style='margin:20px;padding:20px;border: 10px dashed gray;background:lightblue'>
<body>
<p>
1
<br>
2
<br>
3
</p>
</body>
</html>
而且如果html没有设置背景色,设置body的背景色会占据整个浏览器画布(canvas)
这样的规则是 W3C的规范 确定的
元素的背景色属性并不会传递给后代元素,
但是, 如果后代元素不重新设置背景色,后代元素背景色 也会显示为 最近设置背景色 上级元素的 颜色。
这是因为, 背景色的缺省值是 transparent
透明。