Although I've found similar questions, none explicitly match my goal.
I'm trying to display text with a gradient colour, with low opacity (so you can see the background through it), but also with a (matching) solid gradient border (i.e. text-stroke). I've discovered that answers to similar questions develop a workaround by creating a ::before
underlay state that replicates a (gradient) border effect, but changing the opacity on the text's natural state just displays the colour of the ::before
underlay text instead of the background colour (the desired result).
What I'm wondering is, is there any workaround to effectively create a solid gradient text-stroke with (internal) gradient text that has an opacity lower than 1?
Using the aforementioned other similar questions, I've developed the following code over a period of hours but can't quite figure out how it can be done. You'll notice in my code that I've used different rgba
values - this was simply done to view the result more easily and see if I acheived my intended goal of making the (internal) text have opacity (to enable the background to be seen), as opposed to using identical colours. The more opacity I apply, the more you can see the gradient colours of the workaround/makeshift text-stroke.
body {
background: #000000;
}
h1 {
font-size: 60px;
font-weight: 800;
font-family: arial;
color: rgb(255, 255, 255);
background-image: linear-gradient(to left,
rgba(255, 0, 0, 0.7),
rgba(0, 0, 255, 0.7),
rgba(255, 0, 0, 0.7));
-webkit-text-fill-color: transparent;
-webkit-background-clip: text;
margin: 10px;
}
h1::before {
content: attr(data-text);
background: -webkit-linear-gradient(-180deg, #3399ff, #82ed89, #3399ff);
-webkit-background-clip: text;
-webkit-text-stroke: 5px transparent;
position: absolute;
z-index: -1;
}
<h1 data-text="Text">Text</h1>
Actually the only way i can think about using CSS and without SVG is to rely on element()
combined with mask
but still the support is too low:
Here is an example that will only work in Firefox. The trick is to create a text with only stroke and transparent color as a reference that will be used inside a mask of the same text where we have the same stroke to keep only the stroke visible and get the needed effect. Yes, it's a bit crazy as idea but it works.
body {
background: #000000;
}
h1 {
font-size: 80px;
font-weight: 800;
font-family: arial;
color:#fff;
}
#ref {
-webkit-text-stroke: 5px red;
color:transparent;
display:inline-block;
}
h1.grad {
background-image: linear-gradient(to left,
rgba(255, 0, 0, 0.3),
rgba(0, 0, 255, 0.4),
rgba(255, 0, 0, 0.5));
-webkit-text-fill-color: transparent;
-webkit-background-clip: text;
margin: 10px;
}
h1.grad::after {
content: attr(data-text);
}
h1.grad::before {
content: attr(data-text);
background: linear-gradient(-180deg, #3399ff, #82ed89, #3399ff);
-webkit-background-clip: text;
-webkit-text-stroke: 5px transparent;
position: absolute;
z-index: -1;
-webkit-mask:element(#ref);
mask:-moz-element(#ref);
mask:element(#ref);
}
body {
background:url(https://picsum.photos/id/107/1000/1000) center/cover;
}
<h1 data-text="Some Text" class="grad"></h1>
<div style="height:0;overflow:hidden;">
<h1 id="ref">Some Text</h1>
</div>
Below how it should look:
Another idea is to consider background-attachment:fixed
and use the same background twice. This should work everywhere but you background will be fixed:
body {
background: #000000;
}
h1 {
font-size: 80px;
font-weight: 800;
font-family: arial;
color:#fff;
}
h1.grad {
background: linear-gradient(to left,
rgba(255, 0, 0, 0.3),
rgba(0, 0, 255, 0.4),
rgba(255, 0, 0, 0.5)),
url(https://picsum.photos/id/110/1000/1200) center/cover fixed;
-webkit-text-fill-color: transparent;
-webkit-background-clip: text;
background-clip: text;
margin: 10px;
}
h1.grad::after {
content: attr(data-text);
}
h1.grad::before {
content: attr(data-text);
background: linear-gradient(-180deg, #3399ff, #82ed89, #3399ff);
-webkit-background-clip: text;
-webkit-text-stroke: 5px transparent;
position: absolute;
z-index: -1;
}
body {
background:url(https://picsum.photos/id/110/1000/1200) center/cover fixed;
}
<h1 data-text="Some Text" class="grad"></h1>