使用css-transforms为所有浏览器创建遮罩,遇到定位问题

时间:2019-04-03 14:46:04

标签: html css css-position css-transforms

我需要创建一个遮罩,以基于vh(否clip-path)在所有浏览器中覆盖图像

我正在使用带有旋转变换的div作为蒙版,然后在内部反转旋转。

我遇到的问题是内部内容的位置不正确。图片需要对齐到内部容器的左上方。

我尝试过:

  • 使用顶部和左侧的值定位无效。
  • 使用变换移动内部容器有效,但是我找不到所需的值是如何计算的。

https://jsfiddle.net/owfgLnv7/5/

.container {
  width: 70vh;
  height: 100vh;
  background-color: blue;
  position: absolute;
  left: 0;
  top: 0;
  z-index: 0;
}

.tri {
  position: absolute;
  width: 70vh;
  height: 70vh;
  transform: rotate(45deg);
  top: calc((100vh - 70vh) / 2);
  transform-origin: center center;
  background-color: transparent;
  z-index: 2;
  overflow: hidden;
}

.reset-tri {
  position: relative;
  z-index: 1;
  transform: rotate(-45deg);
  transform-origin: center center;
}

.inner-container {
  background: black;
}

需要获取图像以使其左上对齐并正常流动

1 个答案:

答案 0 :(得分:2)

基本上,当对元素进行转换(在此处旋转)时,它们会从流程中删除-因此尺寸不会像您不执行的那样表现。

一种方法只是使用简单的数学:

  • 如果您将a边的方形旋转45度(此处为70vh方形),则对角线将为√2 * a1.414 * a,< / li>
  • 因为此处的transform-origincenter,这意味着溢出宽度或高度等于(1.414 * a - a) / 2(1.414 - 1) * a / 2
  • 可以为container的宽度声明
  • 相似的论点,其宽度等于width: calc(1.414 * 70vh)

请参见下面的演示

body {
  margin: 0;
}

.page {
  width: 100vw;
  height: 100vh;
  background: grey;
}

.container {
  width: calc(1.414 * 70vh); /* changed */
  height: 100vh;
  background-color: blue;
  position: absolute;
  left: 0;
  top: 0;
  z-index: 0;
}

.tri {
  position: absolute;
  width: 70vh;
  height: 70vh;
  transform: rotate(45deg);
  top: calc(0.414 * 70vh / 2); /* changed */
  left: calc(0.414 * 70vh / 2); /* added */
  transform-origin: center center;
  background-color: transparent;
  z-index: 2;
  overflow: hidden;
}

.reset-tri {
  position: relative;
  z-index: 1;
  transform: rotate(-45deg);
  transform-origin: center center;
}

.inner-container {
  background: black;
}
<div class="page">
  <div class="container">
    <div class="tri">
      <div class="reset-tri">
        <div class="inner-container">
          <img src="https://openclipart.org/download/230732/360sj3.svg" />
        </div>
      </div>
    </div>
  </div>
</div>


使用背景图片

对于近乎完美的遮罩,您可以:

  • image移到background-image容器中的reset-tri

  • 添加一个scale(1.414)转换以完全填充原始的未转换 tri容器。

请参见下面的演示

body {
  margin: 0;
}

.page {
  width: 100vw;
  height: 100vh;
  background: grey;
}

.container {
  width: calc(1.414 * 70vh); /* changed */
  height: 100vh;
  background-color: blue;
  position: absolute;
  left: 0;
  top: 0;
  z-index: 0;
}

.tri {
  position: absolute;
  width: 70vh;
  height: 70vh;
  transform: rotate(45deg);
  top: calc(0.414 * 70vh / 2); /* changed */
  left: calc(0.414 * 70vh / 2); /* added */
  transform-origin: center center;
  background-color: transparent;
  z-index: 2;
  overflow: hidden;
}

.reset-tri {
  position: relative;
  z-index: 1;
  transform: rotate(-45deg) scale(1.414); /* scale by √2 */
  transform-origin: center center;
  width: 70vh;
  height: 70vh;
  /* use a bacground image */
  background-size: cover;
  background-image: url("https://openclipart.org/download/230732/360sj3.svg");
}
<div class="page">
  <div class="container">
    <div class="tri">
      <div class="reset-tri"></div>
    </div>
  </div>
</div>


使用图像元素

对于不使用background-image的近乎完美的 masking ,您可以返回上一个标记,然后将object-fit: cover添加到填充尺寸的img元素中包装inner-container的内容-参见下面的演示:

body {
  margin: 0;
}

.page {
  width: 100vw;
  height: 100vh;
  background: grey;
}

.container {
  width: calc(1.414 * 70vh); /* changed */
  height: 100vh;
  background-color: blue;
  position: absolute;
  left: 0;
  top: 0;
  z-index: 0;
}

.tri {
  position: absolute;
  width: 70vh;
  height: 70vh;
  transform: rotate(45deg);
  top: calc(0.414 * 70vh / 2); /* changed */
  left: calc(0.414 * 70vh / 2); /* added */
  transform-origin: center center;
  background-color: transparent;
  z-index: 2;
  overflow: hidden;
}

.reset-tri {
  position: relative;
  z-index: 1;
  transform: rotate(-45deg) scale(1.414); /* scale by √2 */
  transform-origin: center center;
  width: 70vh;
  height: 70vh;
}

.inner-container {
  height: 100%; /* fill the parent wrapper */
}

.inner-container > img {
  width: 100%;
  height: 100%;
  object-fit: cover; /* the image fills the parent container */
}
<div class="page">
  <div class="container">
    <div class="tri">
      <div class="reset-tri">
        <div class="inner-container">
          <img src="https://openclipart.org/download/230732/360sj3.svg" />
        </div>
      </div>
    </div>
  </div>
</div>