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
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
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
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.
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
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
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
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
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!
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
Of course, you can also directly convert this SVG into base 64 format (recommended to use Zhang Xinxu's SVG conversion tool , very good)
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:'')
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
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
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.
- SVG foreignObject can embed HTML tags
- Pay attention to the namespace of SVG and HTML, it will be automatically recognized in HTML
- The text background image is implemented with -webkit-background-clip combined with transparent text
- SVG is essentially a picture
- SVG can be escaped to inline base 64 without affecting the original animation
- When SVG is used as an image, it does not support dynamic modification of styles
- 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 ❤❤❤
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。