固定元素行为不符合预期
Fixed element bahaviour isn't as expected
我有一个例子,固定元素是 'positioned' - 在某种程度上 - 相对于父容器而不是浏览器 window...
.container {
position: relative;
width: 640px;
margin: 0 auto;
}
.options {
position: fixed;
bottom: 0;
width: 100%;
}
.options button {
float: left;
box-sizing: border-box;
width: 25%;
}
<div class="container">
<div class="options">
<button>1</button>
<button>2</button>
<button>3</button>
<button>4</button>
</div>
</div>
包含按钮的div是固定的,底部偏移设置为0。但是,div偏移了一定距离,并从与父级相同的水平距离开始容器。现在,一旦我将左偏移值设置为“0”,元素就会按预期定位自己,从视口的边缘开始。所以我知道这实际上并不是相对于父容器定位的。但是为什么一开始会有偏移呢?我猜默认的 'auto' 设置会计算出该值不为零。但是这个值是怎么计算出来的呢?
另外,当宽度值是 100% 与继承时,宽度值的计算方式引起了另一个混淆点。查了一下,发现两者的区别在于,'width: 100%' 将宽度设置为父元素计算值的 100%,而 'width: inherit' 占用了 CSS 的值parent 字面上并将其应用于元素。因此,在我上面分享的示例中,前者会将包含按钮的 div 的宽度设置为其父级计算宽度的 100%,而后者会将宽度设置为“640px”,这是父项的 CSS 值。我遇到的问题是,在第一种情况下,宽度以百分比设置,元素比预期的要宽。计算的宽度似乎是根据视口宽度计算的,即视口的 100%,而不是父元素,这正是我所期望的。
如果'width: inherit'从父元素获取到640px的宽度,那为什么width设置为100%时继承的是viewport的宽度,而不是父元素的计算值。为什么在一种情况下,前面的容器被认为是从其继承值的父级,而在另一种情况下,视口是从其计算值的父级?
body
默认有一个填充。您可以添加 padding: 0
以使您的固定元素尽可能向左移动,或将 left: 0
添加到您的固定 .options
元素。
您不应使用固定宽度 (640px),因为您在编写代码时应考虑到响应能力。
你不应该在布局中使用浮动,因为它会弄乱对象的框大小。如果您希望文本在图像周围“浮动”,则仅在图像上使用它。
html, body { /* ADDED */
margin: 0;
padding: 0;
}
.container {
position: relative;
width: 100%; /* CHANGED */
margin: 0 auto;
/* ADDED */
min-width: 640px;
}
.options {
position: fixed;
bottom: 0;
width: 100%;
/*left: 0; if you don't want to change the padding for the body */
/* ADDED */
display: flex;
}
.options button {
/*float: left;*/
box-sizing: border-box;
/* width: 25%; */
/* ADDED */
flex: 1 1 auto; /* grow / shrink / auto-adjust in width */
}
<div class="container">
<div class="options">
<button>1</button>
<button>2</button>
<button>3</button>
<button>4</button>
</div>
</div>
但是为什么一开始会有偏移呢?
除静态和粘性(固定、绝对)之外的位置值就是这种情况,它们会保留其父偏移量。
演示:
*,
*:after,
*:before {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body * {
padding: 10px;
border: 1px solid;
}
body {
text-align: center;
}
[container] {
position: relative;
width: 120px;
margin: 50px;
padding: 30px;
display: inline-block;
}
[absolute] {
position: absolute;
}
[fixed] {
position: fixed;
}
<div container>
<div absolute>absolute</div>
</div>
<br/>
<div container>
<div fixed>fixed</div>
</div>
如您所见,即使应用了位置,元素也不会突然跳到它们预期的位置。您可以尝试添加 left:0
添加看看它们如何移动。
宽度:继承或100%; ?
就像我之前说的:
percentage is relative to the containing block, that changes according to css rules, inherit keyword is relative to the parent element defined in the markup and that never changes with css
更准确的 MDN 解释
Percentage values that are applied to the width, height, padding, margin, and offset properties of an absolutely positioned element (i.e., which has its position set to absolute or fixed) are computed from the element's containing block.
演示
[container] {
background: orange;
position: relative;
width: 300px;
height: 100px;
transform: translate(0)
}
[fixed] {
background: red;
position: fixed;
width: 100%;
left: 0;
}
<div container>
<div fixed>fixed</div>
</div>
在此示例中,width:100%
表现正常,因为我们使用 transform: translate(0)
更改了固定元素的连接块
有很多方法可以更改元素的 containing block 我建议您阅读 MDN 文章。
我有一个例子,固定元素是 'positioned' - 在某种程度上 - 相对于父容器而不是浏览器 window...
.container {
position: relative;
width: 640px;
margin: 0 auto;
}
.options {
position: fixed;
bottom: 0;
width: 100%;
}
.options button {
float: left;
box-sizing: border-box;
width: 25%;
}
<div class="container">
<div class="options">
<button>1</button>
<button>2</button>
<button>3</button>
<button>4</button>
</div>
</div>
包含按钮的div是固定的,底部偏移设置为0。但是,div偏移了一定距离,并从与父级相同的水平距离开始容器。现在,一旦我将左偏移值设置为“0”,元素就会按预期定位自己,从视口的边缘开始。所以我知道这实际上并不是相对于父容器定位的。但是为什么一开始会有偏移呢?我猜默认的 'auto' 设置会计算出该值不为零。但是这个值是怎么计算出来的呢?
另外,当宽度值是 100% 与继承时,宽度值的计算方式引起了另一个混淆点。查了一下,发现两者的区别在于,'width: 100%' 将宽度设置为父元素计算值的 100%,而 'width: inherit' 占用了 CSS 的值parent 字面上并将其应用于元素。因此,在我上面分享的示例中,前者会将包含按钮的 div 的宽度设置为其父级计算宽度的 100%,而后者会将宽度设置为“640px”,这是父项的 CSS 值。我遇到的问题是,在第一种情况下,宽度以百分比设置,元素比预期的要宽。计算的宽度似乎是根据视口宽度计算的,即视口的 100%,而不是父元素,这正是我所期望的。
如果'width: inherit'从父元素获取到640px的宽度,那为什么width设置为100%时继承的是viewport的宽度,而不是父元素的计算值。为什么在一种情况下,前面的容器被认为是从其继承值的父级,而在另一种情况下,视口是从其计算值的父级?
body
默认有一个填充。您可以添加padding: 0
以使您的固定元素尽可能向左移动,或将left: 0
添加到您的固定.options
元素。您不应使用固定宽度 (640px),因为您在编写代码时应考虑到响应能力。
你不应该在布局中使用浮动,因为它会弄乱对象的框大小。如果您希望文本在图像周围“浮动”,则仅在图像上使用它。
html, body { /* ADDED */
margin: 0;
padding: 0;
}
.container {
position: relative;
width: 100%; /* CHANGED */
margin: 0 auto;
/* ADDED */
min-width: 640px;
}
.options {
position: fixed;
bottom: 0;
width: 100%;
/*left: 0; if you don't want to change the padding for the body */
/* ADDED */
display: flex;
}
.options button {
/*float: left;*/
box-sizing: border-box;
/* width: 25%; */
/* ADDED */
flex: 1 1 auto; /* grow / shrink / auto-adjust in width */
}
<div class="container">
<div class="options">
<button>1</button>
<button>2</button>
<button>3</button>
<button>4</button>
</div>
</div>
但是为什么一开始会有偏移呢?
除静态和粘性(固定、绝对)之外的位置值就是这种情况,它们会保留其父偏移量。
演示:
*,
*:after,
*:before {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body * {
padding: 10px;
border: 1px solid;
}
body {
text-align: center;
}
[container] {
position: relative;
width: 120px;
margin: 50px;
padding: 30px;
display: inline-block;
}
[absolute] {
position: absolute;
}
[fixed] {
position: fixed;
}
<div container>
<div absolute>absolute</div>
</div>
<br/>
<div container>
<div fixed>fixed</div>
</div>
如您所见,即使应用了位置,元素也不会突然跳到它们预期的位置。您可以尝试添加 left:0
添加看看它们如何移动。
宽度:继承或100%; ?
就像我之前说的:
percentage is relative to the containing block, that changes according to css rules, inherit keyword is relative to the parent element defined in the markup and that never changes with css
更准确的 MDN 解释
Percentage values that are applied to the width, height, padding, margin, and offset properties of an absolutely positioned element (i.e., which has its position set to absolute or fixed) are computed from the element's containing block.
演示
[container] {
background: orange;
position: relative;
width: 300px;
height: 100px;
transform: translate(0)
}
[fixed] {
background: red;
position: fixed;
width: 100%;
left: 0;
}
<div container>
<div fixed>fixed</div>
</div>
在此示例中,width:100%
表现正常,因为我们使用 transform: translate(0)
有很多方法可以更改元素的 containing block 我建议您阅读 MDN 文章。