0%

HTML 与 CSS 基础(5):浮动与定位

这篇文章继续学习 CSS 的基础知识,主要学习 CSS 的浮动、定位等网页布局相关知识。

浮动

标准流

网页布局的本质就是利用 CSS 来摆放盒子:把盒子摆放到相应位置上。CSS 提供了三种传统布局方式,即如何对盒子进行排列:

  • 普通流(标准流)
  • 浮动
  • 定位

所谓标准流就是标签按照默认方式进行排列:

  • 块级元素会独占一行,从上向下顺序排列
  • 行内元素会按照顺序,从左到右顺序排列,碰到父元素边缘则自动换行

标准流是最基本的布局方式。但实际开发中,一个页面通常会同时使用以上 3 种布局方式。

什么是浮动

有很多布局效果,单纯依赖标准流没有办法完成,这时就可以利用浮动来完成布局。浮动可以改变元素标签默认的排列方式。浮动最典型的应用:可以让多个块级元素一行内排列显示。网页布局的第一准则:多个块元素纵向排列找标准流,多个块元素横向排列找浮动。

float 属性可以创建浮动框,将其移动到一边,直至左边缘或右边缘触及包含块或者另一个浮动块的边缘。它的语法如下:

1
float: none | left | right;
  • none:默认值,不浮动
  • left:元素向左浮动
  • right:元素向右浮动

如下是一个浮动布局的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<head>
<style>
div {
width: 100px;
height: 100px;
float: left;
}

.red {
background-color: red;
}

.blue {
background-color: blue;
}
</style>
</head>
<body>
<div class="red"></div>
<div class="blue"></div>
</body>

效果如下:

如果浮动属性按照如下配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<style>
div {
width: 100px;
height: 100px;
}

.red {
background-color: red;
float: left;
}

.blue {
background-color: blue;
float: right;
}
</style>

则效果如下所示:

加了浮动之后的元素,会具有很多特性:

  • 浮动元素会脱离标准流:

    • 浮动元素会脱离标准流的控制,移动到指定位置
    • 而且浮动的盒子不在保留原先的位置
    • 设置了浮动的元素,会漂浮在普通流块元素的上面,不占位置
      • 这里的前提是:先是浮动元素,再是标准流元素,此时标准流元素和浮动元素会在同一行显示,浮动元素会漂浮在标准流元素的上面
      • 如果先是标准流元素,再是浮动元素,则标准流元素独占一行,浮动元素在另一个行进行顶部对齐
      • 总结一下:浮动的盒子只影响浮动盒子后面的标准流,不会影响前面的标准流
      • 实际开发中,一个元素浮动了,理论上其余的兄弟元素也要浮动,这样可以避免各种稀奇古怪的问题
  • 浮动的元素会一行内显示并且元素顶部对齐:

    • 如果多个盒子都设置了浮动,则会按照他们的浮动属性值一行内显示并且顶端对齐排列
    • 浮动的元素是互相贴在一起的(不会有缝隙)
    • 如果父级元素宽度装不下这些盒子,多出的盒子会另起一行对齐
  • 浮动元素会具有行内块元素的特性

    • 任何元素都可以浮动,不管原先是什么模式的元素,添加浮动之后具有行内块元素相似的特性
    • 如果是块级元素没有设置宽度,默认宽度和父级一样宽,但是添加浮动之后,则它的宽度根据内容来决定

浮动元素经常和标准流父级搭配使用:

  • 为了约束浮动元素位置,常会为浮动元素添加一个标准流的父级
  • 先用标准流的父元素排列上下位置,之后内部元素采取浮动排列左右位置,这也符合网页布局的第一准则
  • 先设置盒子的大小,之后再设置盒子的位置,这也是网页布局的第二准则

另外需要注意,浮动的元素不会有外边距合并的问题

清除浮动

由于父级盒子很多情况下,不方便给高度,但是子盒子浮动又不占有位置,最后导致父级盒子的高度为 0,这就会影响之后的标流盒子布局。为了解决这个问题,就需要清除浮动。清除浮动的本质就是清除浮动元素造成的影响。如果父盒子本身就有高度,则不需要清除浮动。

清除浮动之后,父级就会根据浮动的子盒子自动检测高度,父级有了高度,就不会影响下面的标准流。清除浮动的语法如下:

1
2
3
选择器 {
clear: left | right | both;
}
  • left:清除左侧浮动的影响
  • right:清除右侧浮动的影响
  • both:同时清除两侧浮动的影响

清除浮动的策略总体来说是 闭合浮动:只让浮动在父盒子内部影响,不影响父盒子外面的其他盒子。接下来再介绍清除浮动的具体方法。

额外标签法

额外标签法会在浮动元素末尾添加一个空的标签(这个新的空标签必须是块级元素),为该空标签设置 清除浮动样式。例如:

1
<div style="clear:both"></div>
  • 优点:通俗易懂,书写方便
  • 缺点:添加了很多无意义的标签,结构化较差

父级添加 overflow

可以为父级添加 overflow 属性,其属性值设置为 hidden、auto 或者 scroll:

  • 优点:代码简洁
  • 缺点:无法显示溢出的部分

overflow 属性的具体含义我们后面详细介绍。

:after 伪元素法

:after 方式额外标签的升级版本,它的实现如下:

1
2
3
4
5
6
7
8
9
10
11
.clearfix:after {
content: "";
display: block;
height: 0;
clear: both;
visibility: hidden;
}

.clearfix {
*zoom: 1; /* 兼容 IE6/7 */
}

之后只需要为父元素的 class 属性添加 clearfix 即可实现清除浮动。这种方式利用了 :after 伪元素,这样就不需要手动添加一个额外的标签,所以可以认为这种方法是 额外标签法 的升级版。

  • 优点:没有添加额外标签,结构更清晰
  • 缺点:照顾低版本的浏览器

关于伪元素,我们后面会详细介绍。

双伪元素清除浮动

这种方法会添加 2 个伪元素,分别是 :before:after。代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
.clearfix:before, .clearfix:after {
content:"";
display:table;
}

.clearfix:after {
clear:both;
}

.clearfix {
*zoom: 1; /* 兼容 IE6/7 */
}

同样为父元素的 class 属性添加 clearfix 即可实现清除浮动。

  • 优点:没有增加标签,结构更清晰
  • 缺点:照顾低版本的浏览器

定位

之前我们已经学习过标准流和定位,但是这两种布局方式都难以实现一下效果:

  • 某个元素可以自由的在一个盒子内移动位置,并且压住其他盒子
  • 当滚动窗口时,某个盒子元素需要固定在屏幕的某个位置上

标准流通常用于纵向排列盒子,浮动通常用于横向排列盒子,而定位则可以让盒子自由地在某个盒子内移动位置或者固定到屏幕中的某个位置,并且可以压住其他盒子。

定位的组成

定位就是将盒子定在某一个位置上,所以定位也是摆放盒子。定位由 定位模式边偏移 两部分组成:

  • 定位模式用于指定一个元素在文档中的定位方式
  • 边偏移则决定了该元素的最终位置

定位模式通过 CSS 的 position 属性来设置,有以下几种取值:

  • static:静态定位
  • relative:相对定位
  • abosulte:绝对定位
  • fixted:固定定位

边偏移就是将待定位的盒子移动到最终位置,通过 CSS 的 topbottomleftright 属性来设置

  • top:顶部偏移量,定义元素相对于其父元素上边线的距离
  • bottom:底部偏移量,定义元素相对于其父元素下边线的距离
  • left:左侧偏移量,定义元素相对于其父元素左边线的距离
  • rigth:右侧偏移量,定义元素相对于其父元素右边线的距离

静态定位 static

静态定位是元素的默认定位方式,它表示无定位的意思,语法为:

1
2
3
选择器 {
position: static;
}
  • 静态定位按照标准流特性摆件位置,它没有边偏移
  • 静态定位在布局时很少用到

相对定位 relative

相对定位是元素在移动位置时,相对于它原来的位置进行偏移。语法为:

1
2
3
4
5
选择器 {
position: relative;
top: 10px;
left: 20px;
}

相对定位的特点:

  • 它是相对于原来的位置进行移动的(移动位置的参照点是自己原来的位置)
  • 原来在标准流的位置继续占有,后面的盒子仍然以标准流的方式来对待它

绝对定位 absolute

绝对定位是元素在移动位置时,相对于它祖先元素进行偏移。语法为:

1
2
3
4
5
选择器 {
position: absolute;
top: 10px;
left: 20px;
}

绝对定位具有如下特性:

  • 如果没有祖先元素或者祖先元素没有定位,则以浏览器(Document 文档)为准进行定位
  • 如果祖先元素有定位(相对、绝对、固定定位),则以最近一级的有定位的祖先元素为参考点移动位置
  • 绝对定位不再占有原先的位置(脱离标准流的控制)

在实际开发中,一般情况下,子级是绝对定位的话,父级要用相对定位。

  • 子级绝对定位,不会占有位置,可以放到父盒子里面的任何一个地方,不会影响其他兄弟盒子
  • 父盒子需要加定位,限制子盒子在父盒子内显示
  • 父盒子布局时,需要占有位置,因此父亲只能是相对定位

因此,相对定位经常用来作为绝对定位的父级

固定定位 fixed

固定定位是元素固定于浏览器可视区的位置。主要使用场景:可以在浏览器页面滚动时元素的位置不会改变。其语法为:

1
2
3
4
5
选择器 {
position: fixed;
top: 10px;
left: 20px;
}

固定定位的特点:

  • 以浏览器的可视窗口为参照点移动元素:和父元素没有任何关系,而且不随滚动条滚动
  • 固定定位不占有原先位置,所以固定定位也是脱离标准流控制的(因此可以把固定定位看做是一种特殊的绝对定位)

由于固定定位是以可视窗口为参照点进行移动的,当可视窗口大小变化时(例如缩放浏览器),固定定位的元素也会跟着移动。有时候,我们也希望让固定元素紧贴在版心旁边,例如固定在版心右侧位置,可以通过如下小技巧实现:

  • 让固定盒子的盒子 left: 50%,这样该固定盒子就会出现在可视区的中间
  • 再设置固定定位盒子 margin-left: 版心宽度的一半,这样就可以让固定盒子出现在版心右侧

如下是一个实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<head>
<style>
* {
padding: 0;
margin: 0;
}
.w {
width: 1200px;
height: 1500px;
margin: 0 auto;
background-color: blue;
}

.fixed {
width:100px;
height: 100px;
position: fixed;
left: 50%;
top: 0;
margin-left: 600px;
background-color: pink;
}
</style>
</head>
<body>
<div class="w"></div>
<div class="fixed"></div>
</body>

粘性定位 sticky

粘性定位可以认为是相对定位和固定定位的混合。粘性定位可以实现这样的效果:当元素在可视窗口内滚动到特定位置时,它会 在那个位置,即使页面继续滚动,该元素也会保持在那里。当页面滚动使得该元素不再满足粘性条件时,它就会恢复为相对定位的状态。

它的语法如下:

1
2
3
4
选择器 {
position: sticky;
top: 10px;
}

粘性定位的特点:

  • 以浏览器的可视窗口为参照点移动元素(固定定位特点)
  • 粘性定位占有原先位置(相对定位特点)
  • 必须添加 top、bottom、left、right 其中一个才有效。例如设置为 top: 10px,则该元素在滚动到距离顶部 10px 时会粘住

定位叠放次序 z-index

在使用定位布局时,可能会出现盒子重叠的情况。此时可以使用 z-index 属性来控制盒子的前后次序(即堆叠顺序)。其语法为:

1
2
3
选择器 {
z-index: 1;
}
  • 数值可以为正数、负数和 0,默认值是 0;数值越大,盒子越靠上
  • 如果属性值相同,则按照书写顺序,后来居上
  • 数字后面不能加单位
  • 只有定位的盒子才有 z-index 属性

定位技巧

接下来再介绍一些实际开发中经常使用的一些定位技巧。

当一个元素被绝对定位后,由于其位置是通过 left、right、top、bottom 属性来确定的。此时通过设置 margin auto 属性来实现水平居中是不会生效的。为了解决这个问题,可以使用如下技巧:

  • 设置 left: 50%:让盒子移动到父级元素的水平中心位置
  • margin-left 设置为自身宽度的负值的一半:让盒子向左移动自身宽度的一半

垂直居中也是类似的原理:

  • 设置 top: 50%:让盒子移动到父级元素的垂直中心位置
  • margin-top 设置为自身高度的负值的一半:让盒子向上移动自身高度的一半

绝对定位和固定定位和浮动有一些相似的特性:

  • 行内元素添加绝对或者固定定位,可以直接设置高度和宽度
  • 块级元素添加绝对或者固定定位,如果没有设置宽度或者高度,默认大小是内容的大小
  • 浮动元素、绝对定位(固定定位)元素都不会触发外边距合并的问题,因为这些元素都脱离标准流控制

但是也要注意和浮动元素某些特性上的区别:

  • 浮动元素只会压住它下面标准流的盒子,但是不会压住下面标准流盒子里面的文字(图片)
  • 但是绝对定位/固定定位会压住下面标准流所有内容

如下是一个示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<head>
<style>

div {
width: 300px;
height: 300px;
background-color: pink;
float: left;
}
</style>
</head>
<body>
<div></div>
<p>hello,css</p>
</body>

浮动元素虽然压住了 p 段落盒子,但是压不住其中的文字:

而绝对定位(以及固定定位)则会压住下面标准流的所有内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<head>
<style>

div {
width: 300px;
height: 300px;
background-color: pink;
position: absolute;
}
</style>
</head>
<body>
<div></div>
<p>hello,css</p>
</body>

浮动之所以不会压住文字,是因为浮动最开始的目的就是为了实现文字环绕的效果,文字会围绕浮动元素。

元素的显示和隐藏

CSS 可以让一个元素在页面中隐藏或显示出来。

display 属性

display 属性用于设置一个元素应如何显示:

  • display: none 隐藏元素
  • display: block 除了转换为块级元素外,还具有显示元素的意思

diplay 隐藏元素后(注意是隐藏,不是删除),不再占有原来的位置

visibility 属性

visibility 属性用于设置一个元素应可见还是隐藏。其语法为:

  • visibility: visible; 元素可见
  • visibility: hidden; 元素隐藏

visiility 隐藏元素后,仍然占有原来的位置

overflow 属性

overflow 属性指定了如果内容溢出了一个元素的框(超过其高度或宽度)时的行为:

  • visible:不剪切内容也不添加滚动条,默认
  • hiddden:超出部分被隐藏
  • scroll:不管是否超出,总是添加滚动条
  • auto:自动判断是否需要滚动条,如果超出则添加滚动条,否则不添加滚动条

如下展示一个 CSS 示例,它实现了在鼠标经过 div 时,显示该 div 上所覆盖的一个黑色透明效果的盒子,这个案例常见于视频播放的封面效果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<style>
.video {
width: 444px;
height: 320px;
margin: 30px auto;
position: relative;
}

.video img {
width: 100%;
height: 100%;
}

.video .play {
background: rgba(0, 0, 0, .4) url(images/arr.png) no-repeat center;
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
display: none;
}

.video:hover .play {
display: block;
}

</style>

网页布局总结

CSS 属性书写顺序

在实际开发中,为了提高 CSS 的可维护性,我们通常会按照一定顺序来书写 CSS 属性。具体如下:

  • 布局定位属性
  • 自身属性
  • 文本属性
  • 其他属性(CSS3)

页面布局分析

为了提高网页制作的效率,布局时通常会遵循以下流程:

  • 必须确定页面的版心(可视区)
  • 分析页面中的行模块,以及每个行模块中的列模块。这也是布局的第一准则
  • 一行中的列模块经常浮动布局,先确定每个列的大小,之后确定列的位置,这也是布局的第二准则
  • 制作 HTML 结构,遵循现有结构,后有样式的原则,结构最重要
  • 先理清布局结构,再写代码
  • 运用盒子模型原理,通过 DIV+CSS 布局来控制网页中的各个模块

小结

通过盒子模型,我们知道大部分 HTML 标签都是一个盒子。而网页布局的本质,就是通过标准流、浮动、定位一起来摆放盒子,从而完成网页布局:

  • 标准流:可以让盒子上下排列(块级元素)或者左右排列(行内元素),垂直的块级盒子显示就用标准流布局
  • 浮动:可以让多个块级盒子水平排列,多个块级盒子水平显示就用浮动布局
  • 定位:可以让多个盒子层叠显示,如果想要元素自由地在某个盒子内移动就用定位布局