8
头图

I read an article before: CSS magic trick | Magical use of blending mode to achieve text hollow wave effect , very clever, integrating CSS animation into the text, mainly using the blending mode, the effect is like this

Kapture 2022-02-24 at 11.09.36

Why use blend mode? Because this is text, it is impossible to put HTML nodes inside the text, so the following will introduce another way. In the case of completely limited HTML, this effect can also be easily achieved with the help of SVG foreignObject, and it will be better. The effect, let's see it together

1. What is SVG foreignObject

First, foreignObject is an element in SVG that allows to include elements from different XML namespaces. In the context of a browser, this is generally XHTML / HTML . What does that mean? For example, the SVG that we usually export in various design software may be like this

<svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.1785 10.9999C2.1785 6.12799..." fill="#7A7A7A"/>
</svg>

If you save directly as map.svg , then put it in the browser

image-20220223195703834

Note that SVG has an attribute xmlns , which is the namespace , which specifies how this content is rendered in the browser, where http://www.w3.org/2000/svg is the namespace of SVG . If there is no such attribute, the browser will directly render the normal xml document, as follows

image-20220223195609625

However, there is a situation where you don't need to specify this namespace: If our SVG file is directly inlined in the XHTML page or directly with .html as the suffix name , it is not necessary to specify the namespace, and the browser will recognize it automatically.

image-20220223200559613

So, back here, what can foreignObject do? As you may have guessed, the HTML tag can be rendered inside SVG ! The specific method is to add the namespace of xml to the foreignObject , for example

<svg xmlns="http://www.w3.org/2000/svg">
  <foreignObject width="100%" height="100%">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <style>
          p{
            color: red
          }
        </style>
        <p>xboxyan</p>
      </body>
    </foreignObject>
</svg>

Note that the body tag has an attribute xmlns="http://www.w3.org/1999/xhtml" , which is the namespace of html , and the rendering result is as follows

image-20220223201530308

Almost the same as normal HTML, is highlighted below , and some CSS animations can be added.

<svg xmlns="http://www.w3.org/2000/svg">
  <foreignObject width="100%" height="100%">
      <body xmlns="http://www.w3.org/1999/xhtml">
        <style>
          p{
            color: red;
            animation: hue 5s infinite
          }
          @keyframes hue{
              to {
                  filter: hue-rotate(1turn)
              }
          }
        </style>
        <p>xboxyan</p>
      </body>
    </foreignObject>
</svg>

This gives an animated SVG

Kapture 2022-02-23 at 20.24.00

In general, we can use SVG as a kind of image, which can be easily used in various places in web pages, such as the img attribute of src , or directly as a CSS background image. a simple sentence, with the help of foreignObject , you can easily convert a piece of HTML into a picture, including CSS animation .

This is interesting, many scenarios limited by HTML structure can be solved in this way, such as the text hollow wave animation mentioned at the beginning of the article

Second, the text background image

There is a fixed routine for embedding background images in text. With the help of -webkit-background-clip cropping and transparent text, any background can be easily placed in the text, such as

<p>CSS TEXT</p>
p{
    -webkit-background-clip: text;
    color: transparent;
      background: linear-gradient( #f44336, #ffc107);
}

The effect is as follows

image-20220224112835213

Just imagine, if the above wave animation is made into a picture, can it be used directly here?

p{
    -webkit-background-clip: text;
    color: transparent;
      background: url(wave.svg);
}

3. CSS animation to SVG image

Assuming that we have implemented such a wave animation (the focus of this article is not here), the detailed principle can refer to the article pure CSS to achieve wave effect in coco , which is slightly modified here

body::before, body::after {
  content: "";
  position: absolute;
  bottom: 50%;
  left: 50%;
  width: 400vw;
  height: 400vw;
  border-radius: 45% 48% 43% 47%;
  transform: translate(-50%, 0);
  box-shadow: 0 0 0 50vw #54caff9e;
  animation: rotate 10s infinite linear;
}
body::after {
  border-radius: 43% 47% 44% 48%;
  animation: rotate 10s infinite -1s linear;
}

@keyframes rotate {
  0% {
    transform: translate(-50%, 0) rotate(0);
  }
  100% {
    transform: translate(-50%, 0) rotate(360deg);
  }
}

can get this effect

Kapture 2022-02-24 at 15.09.13

Then put this into an SVG foreignObject and it becomes like this

<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">
  <foreignObject width="100%" height="100%">
    <style>
      html,body{
          width: 100%;
          height: 100%
      }
        body{
            margin: 0;
            background:transparent;
            transition: .3s;
        }
        body::before, body::after {
        content: '';
        position: absolute;
        bottom: 50%;
        left: 50%;
        width: 400vw;
        height: 400vw;
        border-radius: 45% 48% 43% 47%;
        transform: translate(-50%, 0);
        box-shadow: 0 0 0 50vw #54caff9e;
                animation: rotate 10s infinite linear;
      }
      body::after {
        border-radius: 43% 47% 44% 48%;
        animation: rotate 10s infinite -1s linear;
      }
      @keyframes rotate {
        0% {
          transform: translate(-50%, 0) rotate(0);
        }
        100% {
          transform: translate(-50%, 0) rotate(360deg);
        }
      }
    </style>
      <body xmlns="http://www.w3.org/1999/xhtml">
      </body>
    </foreignObject>
</svg>

Save this SVG as wave.svg , and you can open the preview directly in the browser!

Kapture 2022-02-24 at 15.18.22

This gets a "moving picture"

Fourth, the use of SVG images

Go back to the previous text and change the gradient directly to this image.

p{
      -webkit-text-stroke: 1px #333;
    -webkit-background-clip: text;
    color: transparent;
      background: url(wave.svg);
}

The effect is as follows

Kapture 2022-02-24 at 15.27.32

Of course, you can also directly convert this SVG into base 64 format (recommended to use Zhang Xinxu's SVG conversion tool , very good)

image-20220224153123161

After the conversion is like this, there is no dependency at all (can still be seen vaguely)

p{
      -webkit-text-stroke: 1px #333;
    -webkit-background-clip: text;
    color: transparent;
      background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3CforeignObject width='100%25' height='100%25'%3E%3Cstyle%3E@keyframes rotate%7B0%25%7Btransform:translate(-50%25,0) rotate(0)%7Dto%7Btransform:translate(-50%25,0) rotate(360deg)%7D%7Dbody%7Bwidth:100%25;height:100%25;margin:0;background:0 0;transition:.3s%7Dbody::after,body::before%7Bcontent:'';position:absolute;bottom:50%25;left:50%25;width:400vw;height:400vw;border-radius:45%25 48%25 43%25 47%25;transform:translate(-50%25,0);box-shadow:0 0 0 50vw %2354caff9e;animation:rotate 10s infinite linear;z-index:1%7Dbody::after%7Bborder-radius:43%25 47%25 44%25 48%25;animation:rotate 10s infinite -1s linear%7D%3C/style%3E%3Cbody xmlns='http://www.w3.org/1999/xhtml'/%3E%3C/foreignObject%3E%3C/svg%3E");
}

This is also completely fine (if the preview is wrong, it may be a problem with single and double quotes in CSS, such as content:'')

image-20220224170137009

The full code can be accessed at CSS wave text (codepen.io)

5. Advantages and Limitations

The advantage is actually very obvious. Because it is a picture, it belongs to the real text hollow effect, so it will not be easily affected by the background layer like the blending mode (the original implementation can only be a white background), for example, change a color here

image-20220224161914981

The limitation is that because it becomes a picture, some attribute styles are fixed and cannot be modified dynamically. The related interaction of hover is also invalid, and the speed of animation cannot be controlled, etc. (It is possible to use SVG directly in the page)

6. Other applications

In many cases where HTML is strictly limited, it can be implemented in this way. For example, what if there are not enough pseudo-elements, you can use SVG to generate it, so that you have countless pseudo-elements available.

There is also a very important application scenario, pure front-end screenshot function, the famous front-end screenshot library rasterizeHTML is the principle

img

7. Summary and Explanation

The above is the whole content of this article. It is a practical little trick. It uses a little feature of SVG. It is mainly to solve the problem of HTML structure limitation. The rest is related to traditional CSS. Here is a summary.

  1. SVG foreignObject can embed HTML tags
  2. Pay attention to the namespace of SVG and HTML, it will be automatically recognized in HTML
  3. The text background image is implemented with -webkit-background-clip combined with transparent text
  4. SVG is essentially a picture
  5. SVG can be escaped to inline base 64 without affecting the original animation
  6. When SVG is used as an image, it does not support dynamic modification of styles
  7. SVG foreignObject can realize screenshot function

Many times, if there is a need for pictures, you can think in the direction of SVG. After all, SVG is an image language. There are many useful features of SVG, which will be introduced later. Finally, if you think it's good and helpful to you, please like, bookmark, and forward ❤❤❤


XboxYan
18.1k 声望14.1k 粉丝