How to Animate a SVG with border-image
Create dynamic border effects using CSS's border-image
attribute and animated SVG
This article will introduce how to combine the border-image
attribute of CSS and animated SVG to create a dynamic SVG animation effect surrounding the border. We will learn how to hand-made resizable nine-grid animated SVGs that can not only reproduce this effect, but also customize it according to your needs.
The final effect is as follows:
This animation is actually part of a flag-taking puzzle I'm developing called "The Skull" to explore the internal structure of the Arduino and its microcontroller. I searched for how to create an animated border like this, but couldn't find any useful examples. Most of the content I found is related to the "Ant March" effect, but unfortunately the stroke-dasharray
trick doesn't work with skulls, let alone more complex shapes.
Therefore, in the spirit of learning and sharing, I will share my experience with you here!
Should I use background
or border-image
?
At first, I didn't even know the existence of border-image
attribute. In my first attempt, I tried to use ::before
pseudo-element and animate its background-position
attribute. The results are as follows:
As you can see, this method works, but to complete the entire border, at least eight different elements (or pseudo-elements) are required. This will confuse HTML code and is not ideal.
I posted a question in the Israeli CSS Developer Facebook group and everyone pointed out border-image
attribute to me. It fits exactly what it's called: use an image (or CSS gradient) as the border of the element.
To use border-image
you have to provide an image that is used in a nine-grid fashion (imagine overlaying a tic toe grid on the image). Each of these nine areas represents a different part of the border: the top, right, left and bottom, four corners, and the middle (the middle part will be ignored).
For example, if we only need static skulls, we can use the SVG pattern to repeat the skulls nine times. First, we use the path of the skull to define a 24×24 pattern, and then use this pattern as a fill for the 72×72 rectangle:
<svg height="72" version="1.1" width="72" xmlns="http://www.w3.org/2000/svg"><defs><pattern height="24" patternunits="userSpaceOnUse" width="24"><path d="..." fill="red"></path></pattern></defs><rect fill="url(#skull-fill)" height="72" width="72"></rect></svg>
Next, we define a border and set border-image
of the target element:
.skulls { border: 24px solid transparent; border-image: url("https://skullctf.com/images/skull-9.svg") 24 round; }
This way we get a border consisting of skulls:
Add SVG animation
Now we can add animations to these skulls! It works fine for most of the time.
The idea is to create different animations for each area in the border image. For example, in the upper left corner, we have one skull moving from right to left, while the other skull moving from top to bottom at the same time.
We will animate transform
attributes to achieve the movement effect. We will also use SVG<use></use>
Elements to avoid repeated lengthy repetitions for each skull<path></path>
definition:
<svg height="96" version="1.1" width="96" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> @keyframes left {to {transform: translate(-32px, 0)}} @keyframes down {to {transform: translate(0, 32px)}} <defs><path d="..." fill="red"></path></defs><use href="#skull" style="animation: down .4s infinite linear" x="0" y="0"></use><use href="#skull" style="animation: left .4s infinite linear" x="32" y="0"></use></svg>
The SVG animation syntax here may look familiar, as it is not some sort of SVG-specific syntax, such as SMIL, but uses CSS animations. Very cool, right?
The final effect is as follows:
If we add a grid, we can see that this animation also covers part of the top and left edges:
After we add the remaining three edges, it looks more impressive, thus completely covering eight areas of the border image:
<svg height="96" version="1.1" width="96" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> @keyframes left {to {transform: translate(-32px, 0)}} @keyframes down {to {transform: translate(0, 32px)}} @keyframes right {to {transform: translate(32px, 0)}} @keyframes up {to {transform: translate(0, -32px)}} <defs><path d="..." fill="red"></path></defs><use href="#skull" style="animation: down .4s infinite linear" x="0" y="0"></use><use href="#skull" style="animation: left .4s infinite linear" x="32" y="0"></use><use href="#skull" style="animation: left .4s infinite linear" x="64" y="0"></use><use href="#skull" style="animation: up .4s infinite linear" x="64" y="32"></use><use href="#skull" style="animation: down .4s infinite linear" x="0" y="32"></use><use href="#skull" style="animation: right .4s infinite linear" x="0" y="64"></use><use href="#skull" style="animation: right .4s infinite linear" x="32" y="64"></use><use href="#skull" style="animation: up .4s infinite linear" x="64" y="64"></use></svg>
This provides us with a complete loop:
Put everything together and we use the animation SVG we just created as border-image
to get the desired result:
I can play this all day...
When I first got it to work, I started to adjust the animation properties. This is one of the advantages of using SVG instead of GIF: changing the nature of the animation is as simple as changing a CSS property in the SVG source file, you can see the results immediately, not to mention smaller file sizes (especially when dealing with gradients), full color support and clear scaling.
First, I try to see what it would look like if I change the animation timing function to ease
:
We can also make the skull fade between red and green:
We can even make the skull change direction as it moves around the high score table:
You can access the JavaScript tab where you can adjust the SVG source code and try it yourself.
Elephant in the room (Ahem, Firefox)
When I first got it to work, I was so happy. However, there are some things you should pay attention to. First and most important point is that for some reason, Firefox does not render animations on edges of borders, only animations on corners:
Interestingly, if I change the SVG to a GIF with the same animation, it works perfectly. However, edge animations on Chrome stop! ?♂️
Anyway, this seems to be a browser error, because Firefox does animate the edges if we change border-image-repeat
property to stretch
, but the result is a bit weird (although it might fit the topic of the page):
Changing border-image-repeat
value to space
also seems to work, but only if the width of the element is not an integer multiple of the skull size (in this case 32 pixels), which means there will be some gaps in the animation.
I also found that when the container size is not a multiple of the patch size (in this case 32 pixels), there are some visual problems like tiny black lines on the skull. I suspect this has something to do with some floating point rounding problem. It also tends to break when zoomed in.
Not perfect, but absolutely finished! If you want to see the final version, you can visit the high score page of "The Skull". Hopefully you will see your name soon!
The above is the detailed content of How to Animate a SVG with border-image. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics



It's out! Congrats to the Vue team for getting it done, I know it was a massive effort and a long time coming. All new docs, as well.

With the recent climb of Bitcoin’s price over 20k $USD, and to it recently breaking 30k, I thought it’s worth taking a deep dive back into creating Ethereum

I had someone write in with this very legit question. Lea just blogged about how you can get valid CSS properties themselves from the browser. That's like this.

I'd say "website" fits better than "mobile app" but I like this framing from Max Lynch:

The other day, I spotted this particularly lovely bit from Corey Ginnivan’s website where a collection of cards stack on top of one another as you scroll.

If we need to show documentation to the user directly in the WordPress editor, what is the best way to do it?

There are a number of these desktop apps where the goal is showing your site at different dimensions all at the same time. So you can, for example, be writing

Questions about purple slash areas in Flex layouts When using Flex layouts, you may encounter some confusing phenomena, such as in the developer tools (d...
