CSS 转换不适用于高内容
CSS Transform not working with tall content
当使用变换使内容垂直居中时,如果内容不高于视口则效果很好,但如果它更高,则无法滚动查看最顶部。有修复吗?
See example of content being pushed off screen.
CSS
.center {
position: $position;
top: 50%;
transform: translateY(-50%);
}
p{
height: 1500px;
}
HTML
<div class="center">
<h1>I am pushed off screen!?</h1>
<p>Tall Content...</p>
</div>
请查看 CSS 转换渲染模型(来自 W3C 规范):
Specifying a value other than none
for the transform
property
establishes a new local coordinate system at the element that it is
applied to. The mapping from where the element would have rendered
into that local coordinate system is given by the element’s
transformation matrix. Transformations are cumulative. That is,
elements establish their local coordinate system within the coordinate
system of their parent. From the perspective of the user, an element
effectively accumulates all the transform properties of its ancestors
as well as any local transform applied to it. The accumulation of
these transforms defines a current transformation matrix (CTM) for the
element.
进一步阅读:https://www.w3.org/TR/css3-transforms/#transform-rendering
让我们从基础开始,这是 parent:
中 child 的默认行为
.parent {
width:200px;
height:200px;
border: 1px dashed #666;
}
.child {
border: 1px solid red;
width:100px;
height:100px;
}
<p>Container: 200 x 200 px</p>
<div class="parent">
<div class="child">
<h4>100 x 100</h4>
</div>
</div>
现在如果我们想使用top
偏移量,我们需要使用定位。
.parent {
width:200px;
height:200px;
border: 1px dashed #666;
}
.child {
border: 1px solid red;
width:100px;
height:100px;
position: relative;
top:50%;
}
<p>Container: 200 x 200 px</p>
<div class="parent">
<div class="child">
<h4>100 x 100</h4>
</div>
</div>
此时,您想通过添加 transform: translateY(-50%);
来垂直对齐 child 但在我们这样做之前,让我们看看如果 parent
没有定义 height
会发生什么], IE。高度是动态的,基于 child:
.parent {
width:200px;
border: 1px dashed #666;
}
.child {
border: 1px solid red;
width:100px;
height:100px;
position: relative;
top:50%;
}
<p>Container: 200 x AUTO px</p>
<div class="parent">
<div class="child">
<h4>100 x 100</h4>
</div>
</div>
如您所见,top
偏移几乎被忽略了,因为浏览器无法计算 auto
高度的百分比。因此,当您尝试添加 transform: translateY
属性 时,该元素将超出 parent:
的范围
.parent {
width:200px;
border: 1px dashed #666;
}
.child {
border: 1px solid red;
width:100px;
height:100px;
position:relative;
top:50%;
transform:translateY(-50%);
}
<p>Container: 200 x AUTO px</p>
<div class="parent">
<div class="child">
<h4>100 x 100</h4>
</div>
</div>
总而言之,transform
属性无法正常工作,因为当 position
偏移量以百分比表示时无法计算,而 parent 具有 auto
/ 动态高度。如果您使用固定高度,它应该按预期工作:
.parent {
width:200px;
border: 1px dashed #666;
}
.child {
border: 1px solid red;
width:100px;
height:100px;
position:relative;
top:50px; /* half of 100px is 50px - instead of 50% */
transform:translateY(-50%);
}
<p>Container: 200 x AUTO px</p>
<div class="parent">
<div class="child">
<h4>100 x 100</h4>
</div>
</div>
当然,这不是动态的。您可以使用 JavaScript 到 get/update 固定像素尺寸。
正如 W3C 规范所解释的那样,由于转换后的元素创建了一个相对于元素本身的坐标,如果元素溢出视口或其 parent,则不会创建滚动条,参见示例:
div {
width:100px;
height:100px;
border:1px dashed #666;
position: fixed;
}
div.red {
background:red;
transform:translate(-50px, -50px);
}
<div></div>
<div class="red"></div>
如果你想保留它,你必须使用 JavaScript 到 运行 计算动态高度,否则,你可以使用 vertical-align: middle
[=139] 垂直对齐项目=],parent 设置为 table-cell
,即 display: table
的 child。因此,例如,如果您知道确切的最高值,它将起作用:
.wrapper {
min-height: 100px;
width: 48%;
border: 1px dashed #666;
position: relative;
top:50px;
float:left;
}
.center {
border: 1px solid red;
width:100px;
height:150px;
}
.transform .center {
position: absolute;
top: 50%;
transform: translateY(-50%);
}
/* table wrapper */
.wrapper.table {
float:right;
display: table;
}
.table .center {
display: table-cell;
vertical-align:middle;
}
<div class="wrapper transform">
<div class="center">
<h4>I am pushed off screen!?</h4>
</div>
</div>
<div class="wrapper table">
<div class="center">
<h4>I'm smarter.</h4>
</div>
</div>
编辑:Flexbox 解决方案
除了老派 table 解决方案外,您还可以使用现代方法:Flexbox。
.flexbox {
border:1px dashed #666;
display: flex;
justify-content: center; /* horizontal centering */
align-items: center; /* vertical centering */
flex-direction: column; /* makes sure children are under each other */
min-height:200px;
}
.flexbox * {
border:1px solid red;
}
.flexbox p {
height:300px;
}
<div class="flexbox">
<h4>Flexbox Magic</h4>
<p>The center of attention!</p>
</div>
flex 容器基于其 children 进行扩展,因此它是一个非常巧妙的动态解决方案。
Flexbox 支持:Can I Use: Flexbox
当使用变换使内容垂直居中时,如果内容不高于视口则效果很好,但如果它更高,则无法滚动查看最顶部。有修复吗?
See example of content being pushed off screen.
CSS
.center {
position: $position;
top: 50%;
transform: translateY(-50%);
}
p{
height: 1500px;
}
HTML
<div class="center">
<h1>I am pushed off screen!?</h1>
<p>Tall Content...</p>
</div>
请查看 CSS 转换渲染模型(来自 W3C 规范):
Specifying a value other than
none
for thetransform
property establishes a new local coordinate system at the element that it is applied to. The mapping from where the element would have rendered into that local coordinate system is given by the element’s transformation matrix. Transformations are cumulative. That is, elements establish their local coordinate system within the coordinate system of their parent. From the perspective of the user, an element effectively accumulates all the transform properties of its ancestors as well as any local transform applied to it. The accumulation of these transforms defines a current transformation matrix (CTM) for the element.
进一步阅读:https://www.w3.org/TR/css3-transforms/#transform-rendering
让我们从基础开始,这是 parent:
中 child 的默认行为.parent {
width:200px;
height:200px;
border: 1px dashed #666;
}
.child {
border: 1px solid red;
width:100px;
height:100px;
}
<p>Container: 200 x 200 px</p>
<div class="parent">
<div class="child">
<h4>100 x 100</h4>
</div>
</div>
现在如果我们想使用top
偏移量,我们需要使用定位。
.parent {
width:200px;
height:200px;
border: 1px dashed #666;
}
.child {
border: 1px solid red;
width:100px;
height:100px;
position: relative;
top:50%;
}
<p>Container: 200 x 200 px</p>
<div class="parent">
<div class="child">
<h4>100 x 100</h4>
</div>
</div>
此时,您想通过添加 transform: translateY(-50%);
来垂直对齐 child 但在我们这样做之前,让我们看看如果 parent
没有定义 height
会发生什么], IE。高度是动态的,基于 child:
.parent {
width:200px;
border: 1px dashed #666;
}
.child {
border: 1px solid red;
width:100px;
height:100px;
position: relative;
top:50%;
}
<p>Container: 200 x AUTO px</p>
<div class="parent">
<div class="child">
<h4>100 x 100</h4>
</div>
</div>
如您所见,top
偏移几乎被忽略了,因为浏览器无法计算 auto
高度的百分比。因此,当您尝试添加 transform: translateY
属性 时,该元素将超出 parent:
.parent {
width:200px;
border: 1px dashed #666;
}
.child {
border: 1px solid red;
width:100px;
height:100px;
position:relative;
top:50%;
transform:translateY(-50%);
}
<p>Container: 200 x AUTO px</p>
<div class="parent">
<div class="child">
<h4>100 x 100</h4>
</div>
</div>
总而言之,transform
属性无法正常工作,因为当 position
偏移量以百分比表示时无法计算,而 parent 具有 auto
/ 动态高度。如果您使用固定高度,它应该按预期工作:
.parent {
width:200px;
border: 1px dashed #666;
}
.child {
border: 1px solid red;
width:100px;
height:100px;
position:relative;
top:50px; /* half of 100px is 50px - instead of 50% */
transform:translateY(-50%);
}
<p>Container: 200 x AUTO px</p>
<div class="parent">
<div class="child">
<h4>100 x 100</h4>
</div>
</div>
当然,这不是动态的。您可以使用 JavaScript 到 get/update 固定像素尺寸。
正如 W3C 规范所解释的那样,由于转换后的元素创建了一个相对于元素本身的坐标,如果元素溢出视口或其 parent,则不会创建滚动条,参见示例:
div {
width:100px;
height:100px;
border:1px dashed #666;
position: fixed;
}
div.red {
background:red;
transform:translate(-50px, -50px);
}
<div></div>
<div class="red"></div>
如果你想保留它,你必须使用 JavaScript 到 运行 计算动态高度,否则,你可以使用 vertical-align: middle
[=139] 垂直对齐项目=],parent 设置为 table-cell
,即 display: table
的 child。因此,例如,如果您知道确切的最高值,它将起作用:
.wrapper {
min-height: 100px;
width: 48%;
border: 1px dashed #666;
position: relative;
top:50px;
float:left;
}
.center {
border: 1px solid red;
width:100px;
height:150px;
}
.transform .center {
position: absolute;
top: 50%;
transform: translateY(-50%);
}
/* table wrapper */
.wrapper.table {
float:right;
display: table;
}
.table .center {
display: table-cell;
vertical-align:middle;
}
<div class="wrapper transform">
<div class="center">
<h4>I am pushed off screen!?</h4>
</div>
</div>
<div class="wrapper table">
<div class="center">
<h4>I'm smarter.</h4>
</div>
</div>
编辑:Flexbox 解决方案
除了老派 table 解决方案外,您还可以使用现代方法:Flexbox。
.flexbox {
border:1px dashed #666;
display: flex;
justify-content: center; /* horizontal centering */
align-items: center; /* vertical centering */
flex-direction: column; /* makes sure children are under each other */
min-height:200px;
}
.flexbox * {
border:1px solid red;
}
.flexbox p {
height:300px;
}
<div class="flexbox">
<h4>Flexbox Magic</h4>
<p>The center of attention!</p>
</div>
flex 容器基于其 children 进行扩展,因此它是一个非常巧妙的动态解决方案。
Flexbox 支持:Can I Use: Flexbox