百度前端技术学院 第七天学习笔记(CSS position)

position属性

position属性用于指定一个元素在文档中的定位方式top,right,bottom 和 left 属性则决定了该元素的最终位置。

注意
行内元素进行绝对定位/固定定位后会变成inline-block元素,所以虽然对外表现的像是块级元素,但还是可以使用行内元素的line-height属性实现垂直居中。
不论之前什么类型的元素display:none除外),
只要设置了position:absolute/fixed、 float中任意一个,都会让元素以display:inline-block的方式显示

属性值 含义
absolute 生成绝对定位的元素,不为元素预留空间
通过指定元素相对于最近的非 static定位祖先元素的偏移,来确定元素位置。(如果所有父元素都没是默认position值则绝对定位相对浏览器窗口进行定位
绝对定位的元素可以设置外边距(margins),且不会与其他边距合并。
元素的位置通过 “left”, “top”, “right” 以及 “bottom” 属性进行规定。
fixed 生成固定定位的元素,不为元素预留空间
相对于浏览器窗口进行定位。
元素的位置在屏幕滚动时不会改变。打印时,元素会出现在的每页的固定位置。
元素的位置通过 “left”, “top”, “right” 以及 “bottom” 属性进行规定。
relative 生成相对定位的元素,相对于其正常位置进行定位。
元素的位置通过 “left”, “top”, “right” 以及 “bottom” 属性进行规定。
该关键字下,元素先放置在未添加定位时的位置,再在不改变页面布局的前提下调整元素位置(因此会在此元素未添加定位时所在位置留下空白)【即会为元素预留空间
static 默认值。没有定位,元素出现在正常的流中(此时 top, right, bottom, leftz-index 属性无效)。
sticky 基本上是相对位置和固定位置之间的混合,其允许定位的元件像它被相对定位一样动作,直到其滚动到某一阈值点(例如,从浏览器窗口顶部10像素)之后它变得固定
必须指定 top, right, bottom 或 left 四个阈值其中之一,才可使粘性定位生效。否则其行为与相对定位相同。
常用于定位字母列表的头部元素

默认值static

  • 该关键字指定元素使用正常的布局行为,即元素在文档常规流中当前的布局位置。此时 top, right, bottom, leftz-index 属性无效。

相对定位relative

  • 生成相对定位的元素,文档流中将为元素预留空间
  • 相对定位会相对元素的原始位置对该元素进行移动。

top, bottom, left, right属性

除默认值static外,其他属性值都要配合使用top, bottom, left, 和 right属性值来精确指定要将定位元素移动到的位置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<body>
<h1>Basic document flow</h1>

<p>I am a basic block level element. My adjacent block level elements sit on new lines below me.</p>

<p class="positioned">By default we span 100% of the width of our parent element, and we are as tall as our child content. Our total width and height is our content + padding + border width/height.</p>

<p>We are separated by our margins. Because of margin collapsing, we are separated by the width of one of our margins, not both.</p>

<p>inline elements
<span>like this one</span> and <span>this one</span> sit on the same line as one another, and adjacent text nodes, if there is space on the same line. Overflowing inline elements will <span>wrap onto a new line if possible (like this one containing text)</span>, or just go on to a new line if not, much like this image will do:
<img src="https://mdn.mozillademos.org/files/13360/long.jpg">
</p>
</body>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
body {
width: 500px;
margin: 0 auto;
}

p {
background: aqua;
border: 3px solid blue;
padding: 10px;
margin: 10px;
}

span {
background: red;
border: 1px solid black;
}

.positioned {
position: relative;
background: yellow;
top: 30px;
left: 30px;
}

相对定位效果图


绝对定位absolute

  • 使用position:absolute;生成绝对定位的元素,它会相对于第一个非 static 的父元素进行定位
  • 生成绝对定位的元素,不为元素预留空间
  • 如果所有的父元素都没有显式地定义position属性(即全部是默认值),那么所有的父元素默认情况下position属性都是static。结果,绝对定位元素会被包含在初始块容器中。这个初始块容器有着和浏览器窗口一样的尺寸,并且<html>元素也被包含在这个容器里面。简单来说,绝对定位元素会被放在<html>元素的外面,并且根据浏览器窗口来定位。(可以通过子绝父相来解决这一问题)
  • 将上面例子中的position值改为absolute:
    1
    position: absolute;
    效果图
  • 绝对定位元素在HTML源代码中,是被放在<body>中的,但是在最终的布局里面,它是离浏览器窗口页面的左边界、上边界有30px的距离。(而不是<body>)

定位上下文(子绝父相)

  • 上面的例子绝对定位元素会被放在<html>元素的外面,并且根据浏览器窗口来定位。(可以通过子绝父相来解决这一问题)
  • 可以通过**设置绝对定位元素的其中一个父元素的定位属性为相对定位relative**来使得绝对定位元素不相对初始块容器进行定位,比如下面例子中将body的css样式设为position: relative;就可以使得body中绝对定位的p元素相对body进行定位。(如果不这么做,子元素就会相对body或浏览器定位,产生不好的效果)
  • 【子绝父相】:我们可以改变定位上下文(绝对定位的元素的相对位置元素)使绝对元素相对于我们给定的父元素进行定位,而不是相对于浏览器窗口进行定位。也就是**设置绝对定位元素的其中一个父元素的定位属性为相对定位relative**,比如:给父元素body添加css样式:
    1
    position: relative;
    使绝对元素相对于body进行定位

z-index更改堆叠顺序

  • 可以通过修改z-index属性值更改元素堆叠顺序
  • 我们使用水平(x轴)和垂直(y轴)坐标来讨论网页,以确定像背景图像和阴影偏移之类的东西的位置。(0,0)位于页面(或元素)的左上角,x和y轴跨页面向右和向下(适合从左到右的语言)。
  • 网页也有一个z轴:一条从屏幕表面到你的脸的虚线z-index 值影响定位元素位于该轴上的位置;正值将它们移动到堆栈上方,负值将它们向下移动到堆栈中。默认情况下,定位的元素都具有z-index为auto,实际上为0。
  • 注意z-index只接受无单位索引值;你不能指定你想要一个元素是Z轴上23像素。较高的值将高于较低的值,但使用2和3将产生与300和40000相同的效果。

例子

  • 当出现多个绝对定位元素时,源顺序中排在后面的元素将出现在排在前面的元素的顶部,比如给上面的例子加上下面代码,使得第一段文字也变成绝对定位(之前是只有第二段文字绝对定位):
    1
    2
    3
    4
    5
    6
    p:nth-of-type(1) {
    position: absolute;
    background: lime;
    top: 10px;
    right: 30px;
    }
    效果图
  • 可以看到第一段文字绿色绝对定位出现在了第一段文字黄色绝对定位的下方。
  • 修改z-index值,使得第一段文字绿色绝对定位出现在了第一段文字黄色绝对定位的上方,将以下声明添加到 p:nth-of-type(1) 规则中:
    1
    z-index: 1;
    修改z-index值后

固定定位fixed

  • fixedabsolute的工作方式完全相同,只有一个主要区别:父元素都是默认position时,absolute固定元素是相对于浏览器窗口本身的, 但“子绝父相”,当父元素有相对定位时将相对其最近的相对定位祖先来固定元素。而fixed固定元素则一直是相对于浏览器窗口本身
  • 生成固定定位的元素,也不为元素预留空间
  • 这意味着您可以创建固定的有用的UI项目,如持久导航菜单

粘性定位sticky

  • sticky是一个比其他属性要新一些的属性。这基本上是相对位置和固定位置之间的混合,其允许定位的元件像它被相对定位一样动作,直到其滚动到某一阈值点(例如,从浏览器窗口顶部10像素)之后它变得固定
  • 粘性定位常用于定位字母列表的头部元素。标示 B 部分开始的头部元素在滚动 A 部分时,始终处于 A 的下方。而在开始滚动 B 部分时,B 的头部会固定在屏幕顶部,直到所有 B 的项均完成滚动后,才被 C 的头部替代。
  • 必须指定 top, right, bottom 或 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
    29
    30
    <div>
    <dl>
    <dt>A</dt>
    <dd>Andrew W.K.</dd>
    <dd>Apparat</dd>
    <dd>Arcade Fire</dd>
    <dd>At The Drive-In</dd>
    <dd>Aziz Ansari</dd>
    </dl>
    <dl>
    <dt>C</dt>
    <dd>Chromeo</dd>
    <dd>Common</dd>
    <dd>Converge</dd>
    <dd>Crystal Castles</dd>
    <dd>Cursive</dd>
    </dl>
    <dl>
    <dt>E</dt>
    <dd>Explosions In The Sky</dd>
    </dl>
    <dl>
    <dt>T</dt>
    <dd>Ted Leo & The Pharmacists</dd>
    <dd>T-Pain</dd>
    <dd>Thrice</dd>
    <dd>TV On The Radio</dd>
    <dd>Two Gallants</dd>
    </dl>
    </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
    29
    30
    31
    * {
    box-sizing: border-box;
    }

    dl {
    margin: 0;
    padding: 24px 0 0 0;
    }

    dt {
    background: #B8C1C8;
    border-bottom: 1px solid #989EA4;
    border-top: 1px solid #717D85;
    color: #FFF;
    font: bold 18px/21px Helvetica, Arial, sans-serif;
    margin: 0;
    padding: 2px 0 0 12px;
    position: sticky;
    top: -1px;
    }

    dd {
    font: bold 20px/45px Helvetica, Arial, sans-serif;
    margin: 0;
    padding: 0 0 0 12px;
    white-space: nowrap;
    }

    dd + dd {
    border-top: 1px solid #CCC
    }
    完整例子

另一个例子

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
29
30
31
32
33
34
35
36
37
38
39
40
<body>
<div class="con">
<div class="samecon">
<h2>标题一</h2>
<p>这是一段文本</p>
<p>这是一段文本</p>
<p>这是一段文本</p>
</div>
<div class="samecon">
<h2>标题二</h2>
<p>这是一段文本</p>
<p>这是一段文本</p>
<p>这是一段文本</p>
</div>
<div class="samecon">
<h2>标题三</h2>
<p>这是一段文本</p>
<p>这是一段文本</p>
<p>这是一段文本</p>
</div>
<div class="samecon">
<h2>标题四</h2>
<p>这是一段文本</p>
<p>这是一段文本</p>
<p>这是一段文本</p>
</div>
<div class="samecon">
<h2>标题五</h2>
<p>这是一段文本</p>
<p>这是一段文本</p>
<p>这是一段文本</p>
</div>
<div class="samecon">
<h2>标题五六</h2>
<p>这是一段文本</p>
<p>这是一段文本</p>
<p>这是一段文本</p>
</div>
</div>
</body>
1
2
3
4
5
6
7
.samecon h2{
/* position: -webkit-sticky; */
position: sticky;
top: 0;
background:#ccc;
padding:10px 0;
}

如果没有div将h2与p元素框起来则被滚动过去的标题并不会消失。


position实例

MDN position实例练习


补充:HTML <section>元素

  • <section>元素表示一个包含在HTML文档中的独立部分,它没有更具体的语义元素来表示,一般来说会有包含一个标题。
  • 例如,导航菜单应该包含在<nav>元素中,但搜索结果列表和地图显示及其控件没有特定元素,可以放在<section>里。
  • MDN 关于<section>元素

注意

  1. 如果元素的内容作为一个独立的有意义的集合,即元素内容可以分为几个部分的话,应该**使用<article>**而不是 <section>
  2. 不要把 <section> 元素作为一个普通的容器来使用,这本应该是<div>的用法(特别是当片段(the sectioning )仅仅是为了美化样式的时候)。
  3. 一般来说,在文档大纲中应该出现**不少于一个 <section>**。

补充:HTML <article>元素

  • <article>元素表示文档、页面、应用或网站中的独立结构,其意在成为可独立分配的或可复用的结构。如在发布中,它可能是论坛帖子、杂志或新闻文章、博客、用户提交的评论、交互式组件,或者其他独立的内容项目。
  • 例如: 阅读器在博客上滚动时一个接一个地显示每篇文章的文本,每个帖子将包含在<article>元素中,可能包含一个或多个<section>
  • 每个<article>通常包括标题(<h1> - <h6>元素)作为<article>元素的子元素。
  • <article>元素嵌套使用时,则该元素代表与外层元素有关的文章。例如,代表博客评论的<article>元素可嵌套在代表博客文章的<article>元素中
  • <article>元素的作者信息可通过<address>元素提供,但是不适用于嵌套的<article>元素。
  • <article>元素的发布日期和时间可通过<time>元素的pubdate属性表示,但请注意<time>pubdate 属性不再是W3C HTML5标准。
  • MDN 关于<article>元素

例子1与例子2

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style type="text/css">
html {
font-family: sans-serif;
/* Sans-serif是专指西文中没有衬线的字体,与汉字字体中的黑体相对应 */
}

* {
box-sizing: border-box;
/* 使用 box-sizing 模型 */
}

body {
margin: 0;
/* 去掉 <body> 默认外边距 */
}

.info-box {
width: 452px;/* 要给ul列表的框border留出2px的宽度,否则位置不够会换行 */
height: 400px;
position: fixed;
top: 0;
}

.info-box ul {
/* 从无序列表中移除默认的padding-left和margin-top值 */
border: 1px solid #b60000;
height: 50px;
margin: 0;
padding: 0;

}

.info-box li {
float: left;
/* 列表项都要左浮动确保三个li元素能在一行合起来 */
list-style-type: none;
/* 去除项目符号 */
width: 150px;
/* info-box宽度为450px,三个li元素平铺info-box */
}

.info-box li a {
display: inline-block;
/* 使链接在一行显示并保持样式可设置 */
text-decoration: none;
/* 去除链接下划线 */
width: 100%;
/* 可点击宽度 */
line-height: 3;
background-color: white;
color: #a60000;
font-weight: 800;
text-align: center;
}

.info-box li a:focus,
.info-box li a:hover {
/* 获得焦点/鼠标悬浮使红底白字 */
background-color: #a60000;
color: white;
}

.info-box li a.active {
/* 使用JavaScript来设置,当一个标签被点击时(当某个选项卡的类( class )出现 active 时) */
background-color: #a60000;
color: white;
}

.info-box .panels {
height: 352px;
position: relative;
clear: both;
}

.info-box article {
position: absolute;
/* 子绝父相:子元素根据父元素进行定位 */
top: 0;
left: 0;
height: 352px;
padding: 10px;
color: white;
background-color: #a60000;
}

.info-box .active-panel {
/* 使段落位于最上方 */
z-index: 1;
}

.fake-content {
background-color: #a60000;
color: white;
padding: 10px;
height: 2000px;
margin-left: 470px;
}
</style>
</head>

<body>
<section class="info-box">
<ul>
<li><a href="#" class="active">Tab 1</a></li>
<li><a href="#">Tab 2</a></li>
<li><a href="#">Tab 3</a></li>
</ul>
<div class="panels">
<article class="active-panel">
<h2>The first tab</h2>

<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque turpis nibh, porttitor nec
venenatis eu, pulvinar in augue. Vestibulum et orci scelerisque, vulputate tellus quis, lobortis
dui. Vivamus varius libero at ipsum mattis efficitur ut nec nisl. Nullam eget tincidunt metus. Donec
ultrices, urna maximus consequat aliquet, dui neque eleifend lorem, a auctor libero turpis at sem.
Aliquam ut porttitor urna. Nulla facilisi.</p>
</article>
<article>
<h2>The second tab</h2>

<p>This tab hasn't got any Lorem Ipsum in it. But the content isn't very exciting all the same.</p>
</article>
<article>
<h2>The third tab</h2>

<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque turpis nibh, porttitor nec
venenatis eu, pulvinar in augue. And now an ordered list: how exciting!</p>

<ol>
<li>dui neque eleifend lorem, a auctor libero turpis at sem.</li>
<li>Aliquam ut porttitor urna.</li>
<li>Nulla facilisi</li>
</ol>
</article>
</div>
</section>

<section class="fake-content">
<h1>Fake content</h1>
<p>This is fake content. Your main web page contents would probably go here.</p>
<p>This is fake content. Your main web page contents would probably go here.</p>
<p>This is fake content. Your main web page contents would probably go here.</p>
<p>This is fake content. Your main web page contents would probably go here.</p>
<p>This is fake content. Your main web page contents would probably go here.</p>
<p>This is fake content. Your main web page contents would probably go here.</p>
<p>This is fake content. Your main web page contents would probably go here.</p>
<p>This is fake content. Your main web page contents would probably go here.</p>
</section>

<script type="text/javascript">
/* 首先我们保存所有的选项卡和所有的面板引用到两个变量中,名为 tabs 和 panels,这样此后我们可以容易地为它们做事。 */
var tabs = document.querySelectorAll('.info-box li a');
var panels = document.querySelectorAll('.info-box article');

/* 遍历所有的选项卡(a标签),并且在每一个上运行叫做setTabHandler() 的函数,此函数建立当每个选项卡被点击时应该发生的功能。 */
for (i = 0; i < tabs.length; i++) {
/* 函数被传递选项卡(a标签)tab和一个索引数i,指明选项卡在tabs 数组中的位置 */
var tab = tabs[i];
setTabHandler(tab, i);
}

function setTabHandler(tab, tabPos) {
/* 创建了一个 onclick 事件来处理点击 */
tab.onclick = function () {
/* 用一个 for 循环清除所有标签当前存在的类 */
for (i = 0; i < tabs.length; i++) {
/* 实际上清除的是a标签的active类(红底白字) */
if (tabs[i].getAttribute('class')) {
tabs[i].removeAttribute('class');
}
}

/* 在当前a标签上创建一个 active 类以便从相关联的元素中继承CSS的一些属性(红底白字) */
tab.setAttribute('class', 'active');

/* 用一个 for 循环清除所有面板当前存在的类。 */
for (i = 0; i < panels.length; i++) {
if (panels[i].getAttribute('class')) {
panels[i].removeAttribute('class');
}
}

/* 当标签被点击的时候在和标签相对应的面板上创建了一个 active-panel 类以便从相关联的元素中继承了CSS的一些属性(使其 z-index 属性被设置为1,让它能位于所有的面板的上面)。 */
panels[tabPos].setAttribute('class', 'active-panel');
}
}
</script>
</body>

</html>

例子1、例子2效果


例子3

  • 复习<label><aside>标签的使用方法。
  • 复习:
margin与padding属性值数量 含义
4 上 右 下 左
3 上 左右 下
2 上下 左右
1 4个方向
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
<!DOCTYPE html>
<html lang="en-us">

<head>
<meta charset="utf-8">
<title>Hidden info panel</title>

<style>
/* || Checkbox hack to control information box display */
label[for="toggle"] {
font-size: 3rem;/* 设置更大的 font-size 使图标更大更美观。 */
position: absolute;/* 设置 position 为 absolute,使用 top 和 right 属性让他能合适的位于右上角。 */
top: 4px;
right: 5px;
z-index: 1;/* 设置其 z-index 为1——因此当信息面板被赋予样式和显示的时候,不会覆盖我们的图标;相反图标依然会位于最上层能够再次被按下来隐藏信息平板。 */
cursor: pointer;/* 使用 cursor 属性来改变鼠标的指针,当鼠标悬浮在图标上面的时候变成一个手形指针(就像你看到的当悬浮在链接上一样),作为一个额外的可视化线索告诉用户这个图标可以做一些有趣的事情。 */
}

input[type="checkbox"] {/* 在实际的 <input> 元素的checkbox 上设置position 属性为 absolute,并从屏幕上方隐藏掉它,我们并不希望在我们的用户界面里看到它。 */
position: absolute;
top: -100px;
}

/* information box styling */
aside {
background-color: #a60000;
color: white;
/* 填充整个浏览器窗口的视口 */
width: 340px;
height: 98%;
padding: 10px 1%;/*padding2个属性值:上下 左右 */
/* 设置fixed,即使页面的内容在滚动,他也总是显示在同一个位置。设置 top 属性,使其粘在视口顶部,设置 right 属性使其默认情况下位于屏幕的右边隐藏大部分。 */
position: fixed;
top: 0;
right: -370px;
/* Transitions是一个有意思的特性,允许你在状态改变的时候平滑的过渡,而不是粗暴的“开”或“关”。在这个例子中我们尝试在checkbox被选中时让面板平滑的滚动。 */
transition: 0.6s all;
}

/* Second part of the checkbox hack — the checked state */
/* 选择与 <input> 元素邻接的 <aside> 元素,但是仅仅在它被选择时(请注意使用 :checked 伪类来实现此目的)*/
input[type=checkbox]:checked+aside {
right: 0px;/* 将 <aside> 的 right 属性设置为0px,会造成面板再次出现在屏幕上(由于过渡属性会平滑的出现) */
}
/* 再一次点击这个标签会取消选中checkbox,面板将会跟着再一次消失。 */
</style>

</head>

<body>

<!-- label通过for属性绑定id到了<input>标签的checkbox元素上,这样点击问号相当于点击checkbox -->
<label for="toggle"></label>
<input type="checkbox" id="toggle">
<aside>
<h2>Information</h2>

<p>Some very important information about your app:</p>

<ol>
<li>It has a really cool slide-out information box.</li>
<li>This information box uses a combination of fixed positioning and a CSS transition for the smooth
sliding.</li>
<li>It also uses a cool technique called the <a href="https://css-tricks.com/the-checkbox-hack/">checkbox
hack</a>.</li>
<li>This allows you to create a nice "toggle on/toggle off" UI effect without using any JavaScript, which
will work in IE9 and above (the smooth transition will work in IE10 and above.)</li>

</ol>

</aside>
</body>

</html>
,