I am trying to add a CSS gradient line (that is slightly bended in the middle) on specific text that keeps the height the same and width should match 100% the same as "position relative" text.
What I want to achieve: https://imgur.com/a/Tdcz09q
I managed to do the following progress below, but I can't find a way to bend that line using transform.
.gradient_text {
background: linear-gradient(90.34deg, #1FA30A 0.2%, #B9D124 70.4%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
text-fill-color: transparent;
font-weight: 500;
position: relative;
}
.gradient_text:after {
content: "";
position: absolute;
top: 102%;
left: 0;
width: 100%;
height: 10px;
display: inline-block;
background: linear-gradient(90.34deg, #1FA30A 0.2%, #B9D124 70.4%);
border-radius: 10px;
}
h2 { font-size: 64px; color: #000; font-family: Arial; }
<h2>Lorem <span >ipsum</span> dolor sit!</h2>
CodePudding user response:
As a one-off solution, you can draw the "bent" line as a SVG <path>
. But that solution does not lend itself to easy reuse. Two factors limit what can be done:
Sizing the line width depends on the use of font-relative sizes, i. e.
em
. That means the SVG part needs to be part of the CSSOM or at least being able to inherit properties from document stylesheets. That precludes the use of a:after
pseudo-element withcontent: url(image:svg xml,...)
, which would encapsulate the image. The markup for the SVG has to be placed inline, intermingled with your text.Gradient definitions in CSS and SVG do not mix. They can be translated into one another, but neither will a
background: url(#gradient)
referencing a SVG gradient paint server work on a HTML element, nor can you writestroke: linear-gradient(...)
for a SVG<path>
. Both definitions need to be spelled out, despite describing the same gradient.
I've placed the SVG gradient definition and a template for the line in separate elements, so you can at least mix-and match different gradients with (potentially) different line definitions. The one defined here will stretch horizontally to always span the text length of its parent element, but maintain its stroke-width
in relation to font size. Use the .gradient_text svg
properties to fine-tune the position of the line.
h2 {
font-size: 64px;
color: #000;
font-family: Arial, sans-serif;
line-height: 1.5em;
margin: 0;
}
#gradient-line {
overflow: visible;
}
#gradient-line path {
vector-effect: non-scaling-stroke;
fill: none;
stroke-width: 0.2em;
stroke-linecap: round;
}
.gradient_text {
background: linear-gradient(90deg, #1FA30A 0.2%, #B9D124 70.4%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
color: transparent;
font-weight: 500;
position: relative;
}
.gradient_text svg {
position: absolute;
overflow: visible;
left: 0.1em;
top: 1em;
width: calc(100% - 0.2em);
height: 0.5em;
}
.gradient_text.green svg {
stroke: url(#gradient-green);
}
<svg width="0" height="0">
<linearGradient id="gradient-green">
<stop offset="0.002" stop-color="#1FA30A" />
<stop offset="0.704" stop-color="#B9D124" />
</linearGradient>
<symbol id="gradient-line" viewBox="0 0 10 5" preserveAspectRatio="none">
<path d="M0,4Q5,1 10,1" />
</symbol>
</svg>
<h2>Lorem <span >ipsum<svg><use href="#gradient-line" /></svg></span> dolor sit!</h2>