CSS转换不适用于高内容

时间:2016-03-14 17:49:44

标签: css viewport css-transforms

当使用转换到垂直居中的内容时,如果内容不高于视​​图端口,它可以正常工作,但如果它更高,则无法滚动查看最顶部。有修复吗?

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>

1 个答案:

答案 0 :(得分:2)

请查看CSS变换渲染模型(来自W3C规范):

  

none属性指定transform以外的值   在元素处建立一个新的局部坐标系   应用于。元素将在何处呈现的映射   进入该局部坐标系由元素给出   变换矩阵。转化是累积的。那是,   元素在坐标内建立其局部坐标系   他们父母的制度。从用户的角度来看,一个元素   有效地累积其祖先的所有变换属性   以及应用于它的任何局部变换。积累的   这些变换定义了当前的变换矩阵(CTM)   元件。

进一步阅读:https://www.w3.org/TR/css3-transforms/#transform-rendering

让我们从基础开始,这是父母内部孩子的默认行为:

&#13;
&#13;
.parent {
  width:200px;
  height:200px;
  border: 1px dashed #666;
}

.child {
  border: 1px solid red;
  width:100px;
  height:100px;
}
&#13;
<p>Container: 200 x 200 px</p>
<div class="parent">
  <div class="child">
    <h4>100 x 100</h4>
  </div>
</div>
&#13;
&#13;
&#13;

现在,如果我们想要使用top偏移量,我们需要使用定位。

&#13;
&#13;
.parent {
  width:200px;
  height:200px;
  border: 1px dashed #666;
}

.child {
  border: 1px solid red;
  width:100px;
  height:100px;
  position: relative;
  top:50%;
}
&#13;
<p>Container: 200 x 200 px</p>
<div class="parent">
  <div class="child">
    <h4>100 x 100</h4>
  </div>
</div>
&#13;
&#13;
&#13;

此时,您希望通过添加transform: translateY(-50%);来垂直对齐孩子,但在我们这样做之前,让我们看看如果parent没有定义height会发生什么, IE高度是基于孩子的动态:

&#13;
&#13;
.parent {
  width:200px;
  border: 1px dashed #666;
}

.child {
  border: 1px solid red;
  width:100px;
  height:100px;
  position: relative;
  top:50%;
}
&#13;
<p>Container: 200 x AUTO px</p>
<div class="parent">
  <div class="child">
    <h4>100 x 100</h4>
  </div>
</div>
&#13;
&#13;
&#13;

如您所见,top偏移几乎被忽略,因为浏览器无法计算auto高度的百分比。因此,当您尝试添加transform: translateY属性时,该元素将超出父级的边界:

&#13;
&#13;
.parent {
  width:200px;
  border: 1px dashed #666;
}

.child {
  border: 1px solid red;
  width:100px;
  height:100px;
  position:relative;
  top:50%;
  transform:translateY(-50%);
}
&#13;
<p>Container: 200 x AUTO px</p>
<div class="parent">
  <div class="child">
    <h4>100 x 100</h4>
  </div>
</div>
&#13;
&#13;
&#13;

总而言之,transform属性无法正常运行,因为当父级具有position /动态高度时,auto偏移量的百分比无法计算。如果使用固定高度,它应该按预期工作:

&#13;
&#13;
.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%);
}
&#13;
<p>Container: 200 x AUTO px</p>
<div class="parent">
  <div class="child">
    <h4>100 x 100</h4>
  </div>
</div>
&#13;
&#13;
&#13;

但当然,这不是动态的。您可以使用JavaScript来获取/更新固定像素尺寸。

正如W3C规范所解释的那样,由于转换后的元素会相对于元素本身创建一个协调,如果元素溢出视口或其父级,则不会创建滚动条,请参见示例:

&#13;
&#13;
div {
  width:100px;
  height:100px;
  border:1px dashed #666;
  position: fixed;
}

div.red {
  background:red;
  transform:translate(-50px, -50px);
}
&#13;
<div></div>
<div class="red"></div>
&#13;
&#13;
&#13;

如果您想保留它,则必须使用JavaScript来运行动态高度的计算,否则,您可以使用vertical-align: middle属性垂直对齐项目,并将父级设置为table-cell这是display: table的孩子。因此,例如,如果您知道确切的最高值,它将起作用:

&#13;
&#13;
.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;
}
&#13;
<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>
&#13;
&#13;
&#13;

编辑:Flexbox解决方案

除了旧的学校表解决方案,您还可以使用现代方法:Flexbox。

&#13;
&#13;
.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;
}
&#13;
<div class="flexbox">
    <h4>Flexbox Magic</h4>
    <p>The center of attention!</p>
</div>
&#13;
&#13;
&#13;

Flex容器根据其子容器进行扩展,因此它是一个非常简洁的动态解决方案。

Flexbox支持:Can I Use: Flexbox