使用 css-transforms 为遇到定位问题的所有浏览器创建掩码
Creating a mask for all browsers using css-transforms encountering issues with positioning
我需要根据 vh
(无 clip-path
)
创建一个遮罩以覆盖所有浏览器中的图像
我正在使用带有旋转变换的 div 作为蒙版,然后在内部反转旋转。
我遇到的问题是内部内容没有正确定位。图像需要与内部容器的左上角对齐。
我试过:
- 使用 top 和 left 值定位无效。
- 使用变换移动内部容器是可行的,但我无法找到所需值的计算方式。
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>
我需要根据 vh
(无 clip-path
)
我正在使用带有旋转变换的 div 作为蒙版,然后在内部反转旋转。
我遇到的问题是内部内容没有正确定位。图像需要与内部容器的左上角对齐。
我试过:
- 使用 top 和 left 值定位无效。
- 使用变换移动内部容器是可行的,但我无法找到所需值的计算方式。
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-transformedtri
容器.
参见下面的演示:
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>