CSS 带定位图层的背景图像灰度
CSS Greyscale On Background Image with Positioned Layers
我正在使用 flexbox 构建一个具有 3-by-whatever 网格的 16x9 视频缩略图的网站。我想在彩色缩略图变成单调(灰度 + x% 透明颜色层)的地方创建翻转,上面有一个白色徽标。
尽管我尽了最大努力,灰度也会影响单独的颜色层。
这是我希望它的工作方式:我只希望彩色视频缩略图显示为网格。然后,当您将鼠标悬停在它们上方时,它们会降低饱和度,变成单调的颜色,每个缩略图都以白色 SVG 徽标为中心。
我这样做的方式(可能是完全错误的)是这样的:
1) 创建一个 3-by-whatever 个缩略图的 flexbox,每个缩略图设置为 16x9 的固定比例。 (为此,我使用的是高度:0,填充 56.25 技术,可在此处找到:https://css-tricks.com/aspect-ratio-boxes/)
2) 通过给它自己的 id 标签并在相应的 css 中设置每个 individual flexbox 来设置背景图像。 (背景:url(example.png)左上/100%;)同时将位置设置为相对。悬停时,过滤器:灰度(100%)。
3) 创建一个child div inside 一个绝对位置和一个top:0, left: 0, height & width 为100%。悬停时,为该层提供不透明度背景并将其设置为 z-index 至 2.
我读过许多其他堆栈溢出,您应该能够为一层设置 z-index 以防止过滤器影响另一层。但是每当我尝试它时,过滤器只会影响 divs.
相关html:
<main class="site-content">
<section class="video-thumbs">
<div class="stills-photo" id="client-1-photo"><div class="stills-logo" id="client-1-logo"></div></div>
<div class="stills-photo" id="client-2-photo"><div class="stills-logo" id="client-2-logo"></div></div>
<div class="stills-photo" id="client-3-photo"><div class="stills-logo" id="client-3-logo"></div></div>
</section>
</main>
.site-content {
/* Establishes a main div for video thumbnails, with a max-width of 1300px. */
margin: auto;
width: 95%;
max-width: 1300px;
}
.video-thumbs {
/* Flexbox for a grid of video thumbnails. Left-most and right-most thumbnails
are flush with the walls of .siteContent. */
width: 100%;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.stills-photo {
/* Sets up flex containers to flow 3 thumbnails per line,
with a "margin" of 30px between each thumbnail. */
margin-bottom: 30px;
line-height: 0;
width: calc(1/3*100% - (1 - 1/3)*30px);
height: 0;
padding: calc(1/3*56.25% - (1 - 1/3)*30px) 0 0 0;
position: relative;
}
.stills-logo {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
}
#client-1-logo:hover {
background: url(https://upload.wikimedia.org/wikipedia/commons/e/ed/Wikipedia-logo-white.svg) center center / 45% no-repeat, rgb(255, 0, 0, .3);
transition: .3s;
transition-property: background-color;
z-index: 99;
}
#client-1-photo {
background: url(https://i.ibb.co/4dKVVXd/example-photo-1.png) top left / 100%;
filter: grayscale(100%);
z-index: 1;
}
#client-2-logo:hover {
background: url(https://upload.wikimedia.org/wikipedia/commons/e/ed/Wikipedia-logo-white.svg) center center / 45% no-repeat, rgb(255, 0, 0, .3);
transition: .3s;
transition-property: background-color;
z-index: 99;
}
#client-2-photo {
background: url(https://i.ibb.co/rft8jSV/example-photo-2.png) top left / 100%;
filter: grayscale(100%);
z-index: 1;
}
#client-3-logo:hover {
background: url(https://upload.wikimedia.org/wikipedia/commons/e/ed/Wikipedia-logo-white.svg) center center / 45% no-repeat, rgb(255, 0, 0, .3);
transition: .3s;
transition-property: background-color;
z-index: 99;
}
#client-3-photo {
background: url(https://i.ibb.co/Ryjkryn/example-photo-3.png) top left / 100%;
filter: grayscale(100%);
z-index: 1;
}
我在 codepen 中进行了设置以更好地查看问题:
https://codepen.io/czeins/pen/OKxBBL
我认为过滤父级也会影响其子级是有道理的。我还没有听说过可以做任何不同的事情来阻止它,如果可以的话,它会有点棘手和复杂。
更简单的方法是尝试分离不同的图层并单独控制它们。伪元素可以帮助我们避免在这里引入几个新的div。
方法:
::after
伪元素获取背景图片和filter
过渡
::before
伪元素获得叠加徽标和 opacity
过渡
- 当我们悬停缩略图时,
::after
过渡到灰度,而 ::before
淡入
完成所有这些操作,同时将重复的样式组合在一起以干化您的代码(相关代码已移至顶部):
.stills-logo {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
}
.stills-logo::before,
.stills-logo::after {
content: '';
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
}
.stills-logo::before {
z-index: 2;
background: url(https://upload.wikimedia.org/wikipedia/commons/e/ed/Wikipedia-logo-white.svg) center center / 45% no-repeat;
opacity: 0;
transition: opacity .3s ease;
}
.stills-logo::after {
z-index: 1;
transition: filter .3s ease;
}
.stills-logo:hover::before {
opacity: 1;
}
.stills-logo:hover::after {
filter: grayscale(100%);
}
#client-1-photo .stills-logo::after {
background: url(https://i.ibb.co/4dKVVXd/example-photo-1.png) top left / 100%;
}
#client-2-photo .stills-logo::after {
background: url(https://i.ibb.co/rft8jSV/example-photo-2.png) top left / 100%;
}
#client-3-photo .stills-logo::after {
background: url(https://i.ibb.co/Ryjkryn/example-photo-3.png) top left / 100%;
}
/* layout stuff not related to the hover effect */
.site-content {
/* Establishes a main div for video thumbnails, with a max-width of 1300px. */
margin: auto;
width: 95%;
max-width: 1300px;
}
.video-thumbs {
/* Flexbox for a grid of video thumbnails. Left-most and right-most thumbnails
are flush with the walls of .siteContent. */
width: 100%;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.stills-photo {
/* Sets up flex containers to flow 3 thumbnails per line,
with a "margin" of 30px between each thumbnail.
If I just used a width of calc(1/3*100%), all 3 thumbnails
would be perfectly flush with one another.
There are three thumbnails with two spaces between (AKA two gutters):
one between the first and second thumbnail, and one between the
second and third thumbnail.
If you subtract 30px from the width, calc(1/3*100%), that amounts
to 90px of blank space (one for each of the three videos) split
between two gutters (remember: "space-between"). Since I only want
to specify what the length two gutters (and not three), I multiply by 2/3.
To keep a responsive ratio without placing an image in the div,
I've set the padding to 56.25%, which is 9/16.
(More info: https://css-tricks.com/aspect-ratio-boxes/) */
margin-bottom: 30px;
line-height: 0;
width: calc(1/3*100% - (1 - 1/3)*30px);
height: 0;
padding: calc(1/3*56.25% - (1 - 1/3)*30px) 0 0 0;
position: relative;
}
<main class="site-content">
<section class="video-thumbs">
<div class="stills-photo" id="client-1-photo">
<div class="stills-logo" id="client-1-logo"></div>
</div>
<div class="stills-photo" id="client-2-photo">
<div class="stills-logo" id="client-2-logo"></div>
</div>
<div class="stills-photo" id="client-3-photo">
<div class="stills-logo" id="client-3-logo"></div>
</div>
</section>
</main>
我正在使用 flexbox 构建一个具有 3-by-whatever 网格的 16x9 视频缩略图的网站。我想在彩色缩略图变成单调(灰度 + x% 透明颜色层)的地方创建翻转,上面有一个白色徽标。
尽管我尽了最大努力,灰度也会影响单独的颜色层。
这是我希望它的工作方式:我只希望彩色视频缩略图显示为网格。然后,当您将鼠标悬停在它们上方时,它们会降低饱和度,变成单调的颜色,每个缩略图都以白色 SVG 徽标为中心。
我这样做的方式(可能是完全错误的)是这样的: 1) 创建一个 3-by-whatever 个缩略图的 flexbox,每个缩略图设置为 16x9 的固定比例。 (为此,我使用的是高度:0,填充 56.25 技术,可在此处找到:https://css-tricks.com/aspect-ratio-boxes/)
2) 通过给它自己的 id 标签并在相应的 css 中设置每个 individual flexbox 来设置背景图像。 (背景:url(example.png)左上/100%;)同时将位置设置为相对。悬停时,过滤器:灰度(100%)。
3) 创建一个child div inside 一个绝对位置和一个top:0, left: 0, height & width 为100%。悬停时,为该层提供不透明度背景并将其设置为 z-index 至 2.
我读过许多其他堆栈溢出,您应该能够为一层设置 z-index 以防止过滤器影响另一层。但是每当我尝试它时,过滤器只会影响 divs.
相关html:
<main class="site-content">
<section class="video-thumbs">
<div class="stills-photo" id="client-1-photo"><div class="stills-logo" id="client-1-logo"></div></div>
<div class="stills-photo" id="client-2-photo"><div class="stills-logo" id="client-2-logo"></div></div>
<div class="stills-photo" id="client-3-photo"><div class="stills-logo" id="client-3-logo"></div></div>
</section>
</main>
.site-content {
/* Establishes a main div for video thumbnails, with a max-width of 1300px. */
margin: auto;
width: 95%;
max-width: 1300px;
}
.video-thumbs {
/* Flexbox for a grid of video thumbnails. Left-most and right-most thumbnails
are flush with the walls of .siteContent. */
width: 100%;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.stills-photo {
/* Sets up flex containers to flow 3 thumbnails per line,
with a "margin" of 30px between each thumbnail. */
margin-bottom: 30px;
line-height: 0;
width: calc(1/3*100% - (1 - 1/3)*30px);
height: 0;
padding: calc(1/3*56.25% - (1 - 1/3)*30px) 0 0 0;
position: relative;
}
.stills-logo {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
}
#client-1-logo:hover {
background: url(https://upload.wikimedia.org/wikipedia/commons/e/ed/Wikipedia-logo-white.svg) center center / 45% no-repeat, rgb(255, 0, 0, .3);
transition: .3s;
transition-property: background-color;
z-index: 99;
}
#client-1-photo {
background: url(https://i.ibb.co/4dKVVXd/example-photo-1.png) top left / 100%;
filter: grayscale(100%);
z-index: 1;
}
#client-2-logo:hover {
background: url(https://upload.wikimedia.org/wikipedia/commons/e/ed/Wikipedia-logo-white.svg) center center / 45% no-repeat, rgb(255, 0, 0, .3);
transition: .3s;
transition-property: background-color;
z-index: 99;
}
#client-2-photo {
background: url(https://i.ibb.co/rft8jSV/example-photo-2.png) top left / 100%;
filter: grayscale(100%);
z-index: 1;
}
#client-3-logo:hover {
background: url(https://upload.wikimedia.org/wikipedia/commons/e/ed/Wikipedia-logo-white.svg) center center / 45% no-repeat, rgb(255, 0, 0, .3);
transition: .3s;
transition-property: background-color;
z-index: 99;
}
#client-3-photo {
background: url(https://i.ibb.co/Ryjkryn/example-photo-3.png) top left / 100%;
filter: grayscale(100%);
z-index: 1;
}
我在 codepen 中进行了设置以更好地查看问题: https://codepen.io/czeins/pen/OKxBBL
我认为过滤父级也会影响其子级是有道理的。我还没有听说过可以做任何不同的事情来阻止它,如果可以的话,它会有点棘手和复杂。
更简单的方法是尝试分离不同的图层并单独控制它们。伪元素可以帮助我们避免在这里引入几个新的div。
方法:
::after
伪元素获取背景图片和filter
过渡::before
伪元素获得叠加徽标和opacity
过渡- 当我们悬停缩略图时,
::after
过渡到灰度,而::before
淡入
完成所有这些操作,同时将重复的样式组合在一起以干化您的代码(相关代码已移至顶部):
.stills-logo {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
}
.stills-logo::before,
.stills-logo::after {
content: '';
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
}
.stills-logo::before {
z-index: 2;
background: url(https://upload.wikimedia.org/wikipedia/commons/e/ed/Wikipedia-logo-white.svg) center center / 45% no-repeat;
opacity: 0;
transition: opacity .3s ease;
}
.stills-logo::after {
z-index: 1;
transition: filter .3s ease;
}
.stills-logo:hover::before {
opacity: 1;
}
.stills-logo:hover::after {
filter: grayscale(100%);
}
#client-1-photo .stills-logo::after {
background: url(https://i.ibb.co/4dKVVXd/example-photo-1.png) top left / 100%;
}
#client-2-photo .stills-logo::after {
background: url(https://i.ibb.co/rft8jSV/example-photo-2.png) top left / 100%;
}
#client-3-photo .stills-logo::after {
background: url(https://i.ibb.co/Ryjkryn/example-photo-3.png) top left / 100%;
}
/* layout stuff not related to the hover effect */
.site-content {
/* Establishes a main div for video thumbnails, with a max-width of 1300px. */
margin: auto;
width: 95%;
max-width: 1300px;
}
.video-thumbs {
/* Flexbox for a grid of video thumbnails. Left-most and right-most thumbnails
are flush with the walls of .siteContent. */
width: 100%;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.stills-photo {
/* Sets up flex containers to flow 3 thumbnails per line,
with a "margin" of 30px between each thumbnail.
If I just used a width of calc(1/3*100%), all 3 thumbnails
would be perfectly flush with one another.
There are three thumbnails with two spaces between (AKA two gutters):
one between the first and second thumbnail, and one between the
second and third thumbnail.
If you subtract 30px from the width, calc(1/3*100%), that amounts
to 90px of blank space (one for each of the three videos) split
between two gutters (remember: "space-between"). Since I only want
to specify what the length two gutters (and not three), I multiply by 2/3.
To keep a responsive ratio without placing an image in the div,
I've set the padding to 56.25%, which is 9/16.
(More info: https://css-tricks.com/aspect-ratio-boxes/) */
margin-bottom: 30px;
line-height: 0;
width: calc(1/3*100% - (1 - 1/3)*30px);
height: 0;
padding: calc(1/3*56.25% - (1 - 1/3)*30px) 0 0 0;
position: relative;
}
<main class="site-content">
<section class="video-thumbs">
<div class="stills-photo" id="client-1-photo">
<div class="stills-logo" id="client-1-logo"></div>
</div>
<div class="stills-photo" id="client-2-photo">
<div class="stills-logo" id="client-2-logo"></div>
</div>
<div class="stills-photo" id="client-3-photo">
<div class="stills-logo" id="client-3-logo"></div>
</div>
</section>
</main>