Location>code7788 >text

Gradient border text effect?

Popularity:800 ℃/2024-07-21 01:16:40

Today, a group of friends asked me this question, if I don't want to cut the picture, is there a way to realize the font effect with gradient border? As shown below:

In this article, we will try to see how we can achieve this gradient border font effect in CSS as much as possible.

superimposition of elements (math.)

First, the easier way to think of writing this is to realize it by overlaying elements.

  1. The element itself implements the text effect itself
  2. Through the pseudo-elements of the element, in conjunction with thebackground-clip: text Implement gradient text, and implement gradient fonts by transforming or setting the text a few sizes larger
  3. Superimpose (1)(2)

Let's try this approach:

<div data-text="4"></div>
div {
    position: relative;
    width: 300px;
    height: 150px;
    font-size: 100px;
    text-align: center;
    font-weight: bold;

    &::before,
    &::after {
        content: attr(data-text);
        position: absolute;
        inset: 0;
        color: #000;
    }
    
    &::before {
        transform: scale(1.1);
        background: linear-gradient(cyan, #fc0);
        background-clip: text;
        color: transparent;
    }
}

Here, we letbefore pseudo-element cap (a poem)after pseudo-element two pseudo-elements for content-specific presentation.after pseudo-element Display only specific text with a font size of100pxbut (not)before pseudo-elementZoom in a little and superimpose it under another pseudo-element with the following effect:

As you can see, this way, the borders are not even.

And, if there were more words, it would be even less effective:

So, realizing it by overlaying it is clearly not desirable.

Implemented through SVG feMorphology filters.

By this point, I was reminded, again, of the two posts I wrote, earlier in the day:

  • CSS | Bold text and then add a border.
  • Interesting! Generation scheme for irregular borders

With the help of SVG filters we are able to erode (thinning) or expand (bolding) elements.

Let's see how it works. feMorphology is a morphological filter whose input source is usually the alpha channel of a graphic, and whose two operations can be used to erode (thin) or expand (thicken) the source graphic.

Using Propertiesoperator Determine whether you want a corrosion effect or an expansion effect. Using Attributesradius Indicates the degree of effect, which can be interpreted as the size of the stroke.

  • operator:erode corrosion mode.dilate is the expansion mode, which defaults toerode
  • radius: the size of the stroke, accepts a number indicating the degree of effect in this mode, default is 0.

Let's simply apply this filter to the text to see the effect:

<div class="g-text">
    <p>Normal Text</p>
    <p class="dilate">Normal Text</p>
    <p class="erode">Normal Text</p>
</div>

<svg width="0" height="0">
    <filter id="dilate">
        <feMorphology in="SourceAlpha" result="DILATED" operator="dilate" radius="3"></feMorphology>
    </filter>
    <filter id="erode">
        <feMorphology in="SourceAlpha" result="ERODE" operator="erode" radius="1"></feMorphology>
    </filter>
</svg>
p {
    font-size: 64px;
}
.dilate {
    filter: url(#dilate);
}
.erode {
    filter: url(#erode);
}

The effect is as follows: the leftmost is the normal text, the center is the expansion of the pattern, the right is the corrosion pattern, look at the effect, very good understanding:

If we can understand that, we can try:

  1. utilizationbackground-clip: text Implementing gradient text
  2. Text refinement using SVG feMorphology's erosion mode.
  3. Stacking the two

The code is as follows:

<div data-text="123/678"></div>
<div data-text="123/678"></div>
<div data-text="123/678"></div>
<svg width="0" height="0">
    <filter id="outline">
        <feMorphology in="SourceAlpha" result="ERODE" operator="erode" radius="2"></feMorphology>
        <feFlood flood-color="#fff" flood-opacity="1" result="flood"></feFlood>
        <feComposite in="flood" in2="ERODE" operator="in" result="OUTLINE"></feComposite>
        <feMerge>
            <feMergeNode in="OUTLINE" />
        </feMerge>
    </filter>
</svg>

div {
    position: relative;
    width: 100vw;
    height: 150px;
    font-size: 120px;
    font-weight: bold;
    text-align: center;
    
    &::before,
    &::after {
        content: attr(data-text);
        position: absolute;
        inset: 0;
    }
    &::before {
        color: transparent;
        background: linear-gradient(0deg, #da00ff, #2a79b7, #7e3eff);
        background-clip: text;
    }
    &::after {
        filter: url(#outline);
    }
}
div:nth-child(2) {
    font-family: 'Cherry Bomb One', cursive;
    font-size: 90px;
}
div:nth-child(3) {
    font-family: 'Darumadrop One', cursive;
    font-size: 150px;
}

Based on this, to see the effect, here I tried 3 different fonts:

It looks pretty good. Using SVG's ability to erode (thin) or expand (thicken) the source graphic, we've cleverly implemented a gradient border effect for the text.

For the full DEMO, you can poke here:CodePen Demo -- SVG implementation of gradient border fonts

Text border -webkit-text-stroke

Is it over? Not yet. At the beginning I had the idea of using-webkit-text-stroke to realize.

But on second thought, think-webkit-text-stroke cannot implement a gradient border, and it requires the use of the-webkit- prefix, there may be compatibility issues, and it turns out that in the course of the discussion, the bullish groupie gave the idea of using the-webkit-text-stroke The way it was realized:

<div class="wrapper">
  <span class="text" data-text="1234567890"></span>
  <span class="text" data-text="I can swallow glass without hurting myself"></span>
</div>
.wrapper {
  position: relative;
  font-size: 128px;
  
  --stroke-width: 12px;
  --background-gradient: linear-gradient(red 0%, green 100%);
  --text-gradient: linear-gradient(white 0%, cyan 100%);
}

.text {
  position: relative;
}
.text::before,
.text::after {
  content: attr(data-text);
  display: block;
  background-clip: text;
  color: transparent;
}
.text::before {
  position: absolute;
  inset: 0;
  background-image: var(--background-gradient);
  -webkit-text-stroke: var(--stroke-width);
}
.text::after {
  position: relative;
  z-index: 1;
  background-image: var(--text-gradient);
}

-webkit-text-stroke The solution idea is essentially to use its background color as well, using the pseudo-element of stroke just to make its words a little bigger so that the background color can be revealed.

And.-webkit-text-stroke The border color can be supported by setting the gradient color directly, so that we get a very perfect effect:

And, fromCanIUse - text-stroke, to this day.-webkit-text-stroke The compatibility is already very good:

We can use it with complete confidence-webkit-text-stroke Set various types of border effects for text.

For the full DEMO, you can poke here:CodePen Demo -- CSS text stroke with gradient By Rex Zeng

ultimate

To summarize briefly, in summary, the fact that-webkit-text-stroke is the easiest and most convenient way to realize gradient text border. Of course, SVG method also has its advantages, if you need multiple border effects, or even multiple gradient text border effects, at this time, SVG will be more powerful.

Well, that's the end of this article, I hope this article has been helpful 😃

More great CSS technical articles are summarized in myGithub -- iCSS The newest version of the book is the one with the most updated version, so feel free to subscribe and bookmark it with a star.

If there are any questions or suggestions, you can communicate more, the original article, the writing is limited, shallow, the text if there is not correct, I hope to inform.