【问题标题】:Creating a mask for all browsers using css-transforms encountering issues with positioning使用 css-transforms 为遇到定位问题的所有浏览器创建掩码
【发布时间】:2019-08-25 03:35:21
【问题描述】:

我需要基于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;
}

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

【问题讨论】:

  • 如果您转到链接,您会看到图像未在左上角的菱形内对齐
  • 菱形内部的 img 应该与左上角对齐,而不是空间中的任意点
  • 链接是现在的样子......不是它应该看起来的样子。
  • 你一直在重复同样的事情。告诉我们它应该是什么样子。
  • ibb.co/VvB7DMh 粉色 - IMG 黑色 - 内蓝色 - 三容器 - 深紫色

标签: html css css-position css-transforms


【解决方案1】:

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

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

  • 如果您将边 a 的正方形旋转 45 度(这里有一个 70vh 正方形),那么 对角线 将是 √2 * a ~ 1.414 * a
  • 因为这里的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 移动到reset-tri 容器中的background-image

  • 添加一个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 的近乎完美的屏蔽,您可以返回上一个标记并将object-fit: cover 添加到填充其包装器尺寸的img 元素,@ 987654343@ - 见下面的演示:

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>

【讨论】:

  • 感谢您的全面回答。然而,img 元素的定位仍然是这里的问题。它不与其父对象的左上角对齐
  • 感谢背景图片解决方案。但是,我仍然看不到如何在其中定位元素
  • @jwtea 抱歉回复晚了,我以为我昨天已经更新了答案...添加了 background-imageimage 元素 i> 上面的选项...
  • 非常感谢 kukkuz。我已经设法避免使用 object-fit 为此在 IE 中工作,感谢您的帮助! jsfiddle.net/m3p2vacy/1
猜你喜欢
  • 1970-01-01
  • 2020-11-27
  • 1970-01-01
  • 2012-04-08
  • 2014-07-16
  • 1970-01-01
  • 2011-05-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多