英文:
Working alternative for {background-clip: text} to achieve transparent text with gradient background in browsers other than Chrome
问题
I need help with the background-clip property in Chrome vs other browsers.
I want to create a logo and header with an animated gradient background for my website. Because logo and header are two separate elements, I'd like to create one background animation for both elements (instead of one for each and positioning them so the gradient animation looks the same), and then make their content / font transparent, so the gradient creates the illusion of making up the font color.
The svg used for the logo has a transparent stroke, and I wanted to use the background-clip CSS-property for the transparent text. However, that didn't work, as setting the background of the logo-text to white (obviously) prevents displaying the gradient below the element.
In order to have this approach work, I then used {mix-blend-mode: screen}, with black font-color and white background. This works perfectly in Chrome, however, when testing with Safari or Firefox, the entire p element is transparent, instead of only the text.
What I don't understand: Setting -webkit-background-clip: text; -moz-background-clip: text;
doesn't solve the issue, but instead breaks the display in Chrome as well, not changing anything in Safari or Firefox. Setting -webkit-text-fill-color: transparent; -moz-text-fill-color: transparent;
then makes the font color white, with the background still transparent. I could use an SVG with SVG masking - but I'd prefer not to use that instead of html for the text. Why does the code behave like that?
Below is a mockup of my code. The difference can be seen by opening the code in Safari or Firefox as opposed to Chrome or Edge, where it works fine:
/* mockup CSS */
a {
font-size: 200%;
text-decoration: none;
}
.logo {
display: flex;
flex-direction: row;
align-items: center;
width: fit-content;
height: 2.7rem;
}
.logo-text {
padding: 0 0.6rem;
font-weight: 700;
font-size: 124%;
}
/* gradient animation CSS */
.logo-img {
height: 2rem;
background: transparent;
background-clip: content-box;
outline: 0.4rem solid white;
}
.logo-text.rainbow {
color: black; /* transparent with mix-blend-mode & background-color */
background: white;
background-clip: text;
mix-blend-mode: screen;
padding: 0.2rem 0.6rem;
}
.logo {
background: repeating-linear-gradient(to right, #ff0018, #ffa52c, #ffff41, #008018, #0000f9, #86007d, #ff0018);
background-repeat: repeat-x;
background-size: 400% 100%;
animation: rainbow_animation 6s linear infinite;
}
@keyframes rainbow_animation {
0% {
background-position:100% 50%
}
100% {
background-position:-33% 50%
}
}
<div class="logo" id="home-redirect">
<img src="https://www.dropbox.com/s/jvgikg1zez1c7kg/logo-test.svg?raw=1" class="logo-img" alt="Logo">
<p class="logo-text rainbow"><a href="index.html">Logo</a></p>
</div>
How it should look vs. how it looks in Webkit / Gecko:
英文:
I need help with the background-clip property in Chrome vs other browsers.
I want to create a logo and header with an animated gradient background for my website. Because logo and header are two separate elements, I'd like to create one background animation for both elements (instead of one for each and positioning them so the gradient animation looks the same), and then make their content / font transparent, so the gradient creates the illusion of making up the font color.
The svg used for the logo has a transparent stroke, and I wanted to use the background-clip CSS-property for the transparent text. However, that didn't work, as setting the background of the logo-text to white (obviously) prevents displaying the gradient below the element.
In order to have this approach work, I then used {mix-blend-mode: screen}, with black font-color and white background. This works perfectly in Chrome, however, when testing with Safari or Firefox, the entire p element is transparent, instead of only the text.
What I don't understand: Setting -webkit-background-clip: text; -moz-background-clip: text;
doesn't solve the issue, but instead breaks the display in Chrome as well, not changing anything in Safari or Firefox. Setting -webkit-text-fill-color: transparent; -moz-text-fill-color: transparent;
then makes the font color white, with the background still transparent. I could use an SVG with SVG masking - but I'd prefer not to use that instead of html for the text. Why does the code behave like that?
Below is a mockup of my code. The difference can be seen by opening the code in Safari or Firefox as opposed to Chrome or Edge, where it works fine:
https://codepen.io/alessandrov/pen/gOQYwoy
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-css -->
/* mockup CSS */
a {
font-size: 200%;
text-decoration: none;
}
.logo {
display: flex;
flex-direction: row;
align-items: center;
width: fit-content;
height: 2.7rem;
}
.logo-text {
padding: 0 0.6rem;
font-weight: 700;
font-size: 124%;
}
/* gradient animation CSS */
.logo-img {
height: 2rem;
background: transparent;
background-clip: content-box;
outline: 0.4rem solid white;
}
.logo-text.rainbow {
color: black; /* transparent with mix-blend-mode & background-color */
background: white;
background-clip: text;
mix-blend-mode: screen;
padding: 0.2rem 0.6rem;
}
.logo {
background: repeating-linear-gradient(to right, #ff0018, #ffa52c, #ffff41, #008018, #0000f9, #86007d, #ff0018);
background-repeat: repeat-x;
background-size: 400% 100%;
animation: rainbow_animation 6s linear infinite;
}
@keyframes rainbow_animation {
0% {
background-position:100% 50%
}
100% {
background-position:-33% 50%
}
}
<!-- language: lang-html -->
<div class="logo" id="home-redirect">
<img src="https://www.dropbox.com/s/jvgikg1zez1c7kg/logo-test.svg?raw=1" class="logo-img" alt="Logo">
<p class="logo-text rainbow"><a href="index.html">Logo</a></p>
</div>
<!-- end snippet -->
How it should look vs. how it looks in Webkit / Gecko:
答案1
得分: 1
我可以使用混合模式来“填充”没有文字的部分。因此,我会有一个纯色蒙版放在渐变上面。
简单来说:文字是黑色,背景是白色。我说“只显示白色”。
我们还可以用它来创建深色模式的示例。
同样的逻辑:文字是白色,背景是黑色。我说“只显示深色”。
一个使用screen
,另一个使用multiply
混合模式。
背景中有一个渐变,透明文字透过它显示出来。
英文:
I can use blend modes to "fill" the part without text. So I would have a solid color mask to put on a gradient.
Simply: text is black and bg is white. I say "show only whites"
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-css -->
.cool{
background: linear-gradient(120deg, red, blue);
}
.text{
background: #fff;
color: #000;
mix-blend-mode: screen;
}
<!-- language: lang-html -->
<span class="cool">
<span class="text">
Your gradient text <br>
goes here. That simple!
</span>
</span>
<!-- end snippet -->
we can also make a dark mode example with it.
same logic: text is white and bg is black. I say "show only darks".
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-css -->
body{
background: #000
}
.cool{
background: linear-gradient(120deg, red, blue);
}
.text{
background: #000;
color: #fff;
mix-blend-mode: multiply;
}
<!-- language: lang-html -->
<span class="cool">
<span class="text">
Your gradient text <br>
goes here. That simple!
</span>
</span>
<!-- end snippet -->
One uses screen
the other uses multiply
blend modes
there's a gradient in the back which shows up through the transparent text in both.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论