使用 css-transforms 为遇到定位问题的所有浏览器创建掩码

Creating a mask for all browsers using css-transforms encountering issues with positioning

我需要根据 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;
}

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

基本上,当元素变换(在此处旋转)时,它们会从流中取出 - 因此尺寸不会像您不这样做时那样表现。

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

  • 如果你旋转边长 a 的正方形 45 度(这里有一个 70vh 的正方形),那么 对角线 将是 √2 * a ~ 1.414 * a,
  • 因为 transform-origin 在这里是 center,这意味着您的 溢出宽度或高度 等于 (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 移动到 reset-tri 容器中的 background-image 并且

  • 添加一个 scale(1.414) 转换为 fill 原来的 un-transformed 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>


使用图像元素

要获得近乎完美的 masking 而无需使用 background-image,您可以返回到之前的标记并将 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>