Jump to content
Search Community

Animating css wrap-around border

jlo test
Moderator Tag

Warning: Please note

This thread was started before GSAP 3 was released. Some information, especially the syntax, may be out of date for GSAP 3. Please see the GSAP 3 migration guide and release notes for more information about how to update the code to GSAP 3's syntax. 

Recommended Posts

Hey again Greensock guys  :) ,


I've got a brainteaser for y'all, hopefully it's an easy one. I did do a search around before asking, but the forum search won't include the word 'border' as a keyword, it's restricted, and Google only answered so much of what I needed to know.


Okay, so I'm trying to recreate this pen from CSS to JS (GSAP): 

See the Pen uHjvi by joelrodelo (@joelrodelo) on CodePen

Assumed it would be simple enough but it's proving trickier than I thought.


I've been trying to do it with an image on a page, have a quick sample here for reference (you can thank me for the working image later ;) ) : http://webslinger.com.au/dev/gs_border_animation/index.html

Some of my attempts or JS fiddles are still in the scripts.js page, just commented out, but they're there for reference.


I've just been starting with the left side of the image to begin with. The problem I run in to is that the border appears from the outside in, and any method I've tried to have the border appear from any other direction - either by 'y:' or 'height:' - has failed, moved the entire image with it, or nothing's happened at all (you can see some of my other attempts in the js file).

I figured the most logical thing to do would be to nest it, to create a new Tween variable that adds the className and then animate the variable in a new TweenMax line, but I think I've gone wrong somewhere with that approach (read back through the documentation, can we only nest new Timeline's, not new TweenMax's?).


Anyway, maybe someone's already figured out an approach to this and I've missed it, or maybe the solution's just too obvious for me to see, cause' surely it wouldn't come to having to actually draw a border line around the image would it?


Appreciate any feedback in advance.

Link to comment
Share on other sites

Hello.. It looks like in that example to what your trying to mimic.. he is using 4 nested spans inside the main div. And animating the height and width of each span, and then using CSS animation delays to control the timing. In your example  you only have one div and a trying to animate the border instead of growing height / width of span...


Carl beat me to it .. Great example Carl and FAST !!!

  • Like 1
Link to comment
Share on other sites

Hey Jonathan,


Thanks for the feedback also mate. I wasn't actually trying to mimic the Pen shown per se, just the effect, so stripped back alot of the CSS to just focus on the JS side of it. The sample I've had to work with on my side still has all the spans left in, I've just commented them out. Carl's solution is probably the simplest for this particular scenario, but I figured that since we're animating the border that's what I would initially focus on. Would that not still be a viable tactic?

I assumed since we can animate css properties like borderStyle and borderLeft etc with GS, could we not also animate how that border appears? There must be some kind of default motion set to it, since it eases in from the left without any instruction, I just made the leap to thinking we could manipulate it further, perhaps just in an indirect way.

I'm probably making it more complicated than necessary, just thinking out loud  :P


And hey Carl, with the addition/comment of the background-colour to the span group...

  /*give each border a background color of black in css so that you don't need to animate it*/

... there is still a way to animate colours in there though right? Say for instance, if you wanted the line to start with one colour at 0 height and finish with a different colour at 200? I'm guessing adding something like:

var tl = new TimelineLite();
tl.fromTo(".l1", 1, {height:0, color:#000}, {height:544, color:#fff})


var tl = new TimelineLite();
tl.fromTo(".l1", 1, {height:0, css{color:#000}}, {height:544, css{color:#fff}})

... wouldn't really work would it?


And cheers boys, your help is always well-appreciated.

Link to comment
Share on other sites

Sure, you can animate height and background color at the same time - try changing Carl's pen to this:

var tl = new TimelineLite();
tl.fromTo(".l1", 1, {height:0}, {height:200, backgroundColor:'#F24'})
  .fromTo(".l2", 1, {width:0},  {width:200,  backgroundColor:'#0AE'})
  .fromTo(".l3", 1, {height:0}, {height:200, backgroundColor:'#5B3'})
  .fromTo(".l4", 1, {width:0},  {width:200,  backgroundColor:'#FA2'})

Note: If you use the css:{} wrapper, you need to include all of the css properties inside it. In your second example GSAP would see color as the only CSS property, so it would try to tween a literal height property of the element, which would have no effect on the elements actual CSS height.


Also colors need to be defined in strings.

// BAD
var tl = new TimelineLite();
tl.fromTo(".l1", 1, {height:0, css{color:#000}}, {height:544, css{color:#fff}});

var tl = new TimelineLite();
tl.fromTo(".l1", 1, {css{height:0, color:"#000"}}, {css{height:544, color:"#fff"}});

var tl = new TimelineLite();
tl.fromTo(".l1", 1, {height:0, color:"#000"}, {height:544, color:"#fff"});
  • Like 3
Link to comment
Share on other sites

I assumed since we can animate css properties like borderStyle and borderLeft etc with GS, could we not also animate how that border appears? 



Nope. The only control you have is over the border thickness but that isn't going to help to achieve the effect of the line drawing around the box.




In regards to tweening the color, i updated the codepen example:

.fromTo(".l2", 4, {width:0, backgroundColor:"red"}, {width:200, backgroundColor:"blue"})


  • Like 2
Link to comment
Share on other sites

  • 2 years later...

Hey guys great solution !


I was wondering how to obtain a similar result with

.square {
  border-radius: 100%;
I've tried to make it work with 4 span but can seems to find a clean solution for it
Link to comment
Share on other sites

Give this a whirl


See the Pen HtIDe by GreenSock (@GreenSock) on CodePen


Thanks for providing the css version, very helpful.

This is a good approach but I prefer rotationX and Y with no prespective and transform-origin of bottom, left, top and right (for each by order) instead of width and height. GSAP uses matrix by default so as far as I've learned animating by transform gives us smoother animations, force3D: false may also help, of course Carls way also works perfectly 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...