Jump to content

3D Transforms & More CSS3 Goodies Arrive in GSAP JS

| GreenSock

Note: This page was created for GSAP version 2. We have since released GSAP 3 with many improvements. While it is backward compatible with most GSAP 2 features, some parts may need to be updated to work properly. Please see the GSAP 3 release notes for details.


GSAP's CSSPlugin is now super-charged to handle some slick new CSS3 properties like 3D transforms, boxShadow, textShadow, borderRadius and clip. Plus you don't need to worry about a litany of vendor prefixes. GSAP makes it easy to create next-generation effects today. [Note: the animation below is NOT a video - it's regular DOM elements being animated with GSAP. And yes, the scrubber works!]

  • 3D transforms
  • textShadow
  • boxShadow
  • borderRadius
  • clip

These features work in virtually all modern-day browsers (see caniuse.com for details about browser support for each feature). Generally if the browser supports the css property (browser-prefixed or not), you can animate it with GSAP's CSSPlugin. In fact, GSAP even works around several browser bugs and glitches to deliver a whole new level of consistency to your animations. It can't work miracles or, for example, permit fancy 3D transforms in IE8, but it does a bunch of work under the hood to empower these features as consistently as possible.

3D Transforms

Browser support: GOOD (Chrome 12, Safari 4, Firefox 10, IE 10, iOS 3.2, Android 3.0) see details

GSAP makes it a breeze to create amazing 3D effects. In addition to all the standard 2D transform properties like rotation, scaleX, scaleY, x, and y, you can also tween 3D properties like rotationX, rotationY, rotationZ, z, perspective and transformPerspective. You can even create multiple tweens that animate each property independently in a staggered fashion and/or with different eases (something virtually impossible to do with CSS3 transitions).

In order to get the most out of these 3D properties, it's important to understand how perspective and transformPerspective work. They both affect the amount of distortion applied in 3D space.

transformPerspective affects only the element that is being animated, making it look as though it has its own distinct vanishing point in its own 3D space. You can choose to give each element a transformPerspective specifically or use CSSPlugin.defaultTransformPerspective to set a default that will be used for all animated elements that don't have one specifically defined.



no transformPerspective
No visual distortion at all. Impossible to distinguish vanishing point or depth. DOM elements by default have no transformPerspective.


The lower the transformPerspective, the more extreme the distortion.


With a higher value the 3D effect is less pronounced.


perspective should be applied to the parent of the element(s) being animated - an element's perspective affects all of its children, allowing them to share a common vanishing point. Typically this is the best way to apply realistic perspective to multiple elements (instead of using transformPerspective on each child element). Practically speaking, you'd almost never use BOTH transformPerspective AND perspective.

transformPerspective Vs perspective

transformPerspective is applied to each box causing each box to have its own vanishing point


A single perspective is applied to the parent div of all the boxes causing each box to share the same vanishing point


transformOrigin can add some really interesting effects - think of it like a pivot point around which your transforms happen. By default, it is in the center of the element ("50% 50%"). transformOrigin is a space-delimited string of values in the following order [x-axis y-axis z-axis] (the z-axis value is optional). You can define the values using the keywords "top", "left", "right", or "bottom" or use percentages (bottom right corner would be "100% 100%") or pixels.


The negative z-index (-200) set in the transformOrigin properties of the second animation changes the effect drastically.

TweenMax.to(box1, 3, {rotationY:360, transformOrigin:"left top"})
TweenMax.to(box2, 3, {rotationY:360, transformOrigin:"left 50% -200"})


  • Performance can vary greatly between the browsers. Generally Webkit browsers like Chrome and Safari do best by far, and Firefox lags behind but updates are getting pushed out pretty aggressively by everyone so things can change fast.
  • In some browsers, you may notice a slight shift of pixels when an element starts/ends a 3D animation. This has nothing to do with GSAP - it's the browser jumping into 3D mode and working with the GPU. The only known workaround is to make sure you apply some sort of 3D transform from the beginning which you could do in your css like "transform:translateZ(0.1px);" (plus the obligatory vendor-prefixed variations).
  • Font antialiasing can appear to change when there's a 3D element on screen. Again, this is a browser issue and has nothing to do with GSAP. In Webkit browsers, you can [mostly] resolve this by setting -webkit-font-smoothing:antialiased in your css.
  • If a browser doesn't support 3D transforms, they will simply be ignored (no errors are generated).
  • In some versions of Firefox, elements with BOTH a boxShadow AND 3D transforms applied don't always render correctly (again, it's a browser issue). We're not aware of a workaround but we expect Firefox to fix the bug in a future release.
  • IE10 supports 3D transforms, but it does not support transformStyle of "preserve-3d" (see Microsoft's site for details).


Browser support: GOOD (Chrome 22, Safari 5.1, Firefox 15, IE 10, Opera 12.1, iOS 3.2, Android 2.1) see details

textShadow takes a space-delimited string consisting of up to 4 values (just like standard css)

  • h-shadow: The horizontal offset of the shadow. Negative numbers are allowed.
  • v-shadow: The vertical offset of the shadow. Negative numbers are allowed.
  • blur: Blur distance (optional).
  • color: Shadow color (optional). Use any color format: #ff000, #f00, red, rgb(255, 0, 0) or rgba(255, 0, 0, 0.5) for control over the opacity of the shadow.
TweenMax.to(element, 0.2, {
	textShadow:"10px 10px 10px rgba(255, 255, 255, 0.5)"

Move your cursor over each word to see a different textShadow effect.

TweenMax.to(glow, 0.2, {
    textShadow:"2px 2px 15px rgba(145, 233, 0, 1)",             
TweenMax.to(blackout, 0.2, {
    textShadow:"1px 1px 1px rgba(255, 255, 255, 0.5)",
TweenMax.to(ghost, 0.2, {
    textShadow:"0px 0px 15px white",
    color:"none" // IE10 unfortunately hides the shadow too


Browser support: VERY GOOD (Chrome 22, Safari 5.1, Firefox 15, IE 9, Opera 12.1, iOS 3.2, Android 2.1) see details

A nice boxShadow animation can visually lift an element off the screen or add an attention-grabbing glow effect. Repeat and yoyo a TweenMax to give it a pulsing glow easily. boxShadow takes a space-delimited string consisting of up to 5 values in standard css form:

  • h-shadow: The horizontal offset of the shadow. Negative numbers are allowed.
  • v-shadow: The vertical offset of the shadow. Negative numbers are allowed.
  • blur: Blur distance (optional).
  • spread: Expansion amount of the shadow beyond the size of the element (optional).
  • color: Shadow color (optional). Use any standard color format like #ff000, #f00, red, or rgb(255, 0, 0).
TweenMax.to(element, 0.5, {
     boxShadow:"0px 0px 10px 10px rgb(0, 204, 0)"

Move your cursor over the buttons to see a variety of boxShadow effects.

sharp shadow
blur shadow
black spread
orange glow
green pulse
white blur
TweenMax.to(sharpShadow, duration, {
    boxShadow: "10px 10px",
TweenMax.to(blurShadow, .3, {
    boxShadow: "10px 10px 10px",
TweenMax.to(blackSpread, .3, {
    boxShadow: "0px 0px 10px 6px black",
TweenMax.to(orangeGlow, .3, {
    boxShadow: "0px 0px 10px 4px #f60",
TweenMax.fromTo(greenPulse, 0.7, {
    boxShadow: "0px 0px 0px 0px rgba(0,255,0,0.3)"
}, {
    boxShadow: "0px 0px 20px 10px rgba(0,255,0,0.7)",
    repeat: -1,
    yoyo: true,
    ease: Linear.easeNone
TweenMax.to(bsBox5, 0.5, {backgroundColor:"black"});
TweenMax.to(whiteBlur, .3, {
    boxShadow: "0px 0px 24px 6px white",


Browser support: VERY GOOD (Chrome 22, Safari 5.1, Firefox 15, IE 9, Opera 12.1, iOS 3.2, Android 2.1) see details

CSSPlugin deftly handles a variety of borderRadius values, animating between them with ease. Specify the radii of all 4 corners in a single string and CSSPlugin will know exactly what to do. Use px, em, % or any unit you want, just like standard css.

//applies same value to all 4 corners:
TweenMax.to(element, 1, {borderRadius:"25px"});
//unique values for top-left, top-right, bottom-right, bottom-left
TweenMax.to(element, 1, {borderRadius:"10px, 4px, 12px, 0px"});
//top-left and bottom-right 10px | top-right and bottom-left 4px
TweenMax.to(element, 1, {borderRadius:"10px, 4px"});

The demo below illustrates a variety of ways to animate borderRadius.

Sample a variety of borderRadius animations by rolling over each grey shape.

TweenMax.to(box, .75, {
    //all 4 corners       
TweenMax.to(box, .75, {
    //all 4 corners    
TweenMax.to(box, .75, {
    //top-left and bottom-right | top-right and bottom-left
    borderRadius:"0px 20px
TweenMax.to(box, .75, {
        //top-left | top-right and bottom-left | bottom-right              
        borderRadius:"0px 20px 50px"
TweenMax.to(box, .75, {
    //top-left | top-right | bottom-right | bottom-left            
    borderRadius:"0px 20px 50px 50px"
TweenMax.to(box, .75, {
    //top-left | top-right | bottom-right | bottom-left                 
    borderRadius:"50px 50px 50px 0px"


Browser support: VERY GOOD (Chrome 2, Safari 1.3, Firefox 1, IE 9, Opera 9.2, iOS 3.2, Android 2.1) see details

The clip css property controls the clipping region for an absolutely positioned element (that's not a GSAP limitation - that's how it works in plain css too). Any part of an element that would render outside the clipping region will be invisible. This includes the content of the element and its children, backgrounds, borders, outlines, and even any visible scrolling mechanism.

You define the rectangle as "rect()" containing a comma-delimited list of four values — top, right, bottom, and left—in that order. Negative length values are allowed. The top and bottom positions are relative to the top border edge of the element’s box. The left and right positions are relative to the left border edge in a left-to-right environment, or to the right border edge in a right-to-left environment.

TweenMax.to(element, 0.5, {
    // rect(top, right, bottom, left)

Move your cursor over the images to see a variety of clip effects.

TweenMax.from(img1, 1, {clip:"rect(50px 100px 50px 0px)"})
TweenMax.from(img2, 2, {clip:"rect(100px 0px 100px 0px)"})
TweenMax.from(img3, 2, {clip:"rect(50px 50px 50px 50px)"}) 
TweenMax.from(img4, 2, {clip:"rect(0px 100px 100px 100px)"})

When doing a from() tween (as demonstrated above) that uses the css clip property the target of the tween must have a clip property applied prior to the tween running. View a simple example or the full demo code.

Note: although the sample code on this page uses TweenMax, CSSPlugin works equally well with TweenLite. Just don't forget to load CSSPlugin with TweenLite (it's already included inside TweenMax's js file for convenience).


There has never been a better time for animation in the browser. Before now, developers had to wrestle with clunky css transitions or css animations which can't accommodate even moderately complex sequences with fine-tuned control over individual properties or deliver solid control over entire sequences, plus they couldn't work around some of the browser bugs (like Safari's major transformOrigin inconsistency or Firefox's randomly disappearing 3D transforms) and they required a bunch of prefixes and redundant code. JavaScript options were very limited as well and none (that we could find) solved some key issues. With GSAP, you can finally get the control and consistency you need and it delivers solid performance as well (much better than jQuery - see the "cage match" for a detailed comparison).

Make sure you download a fresh copy of the GSAP JavaScript files from the main GSAP JS page and go have some fun (if you're a Club GreenSock member, you can download it with your bonus plugins from your GreenSock account). If you haven't used GSAP before in JavaScript, check out the Jump Start. Got questions? Drop by the forums and post there.

Get an all-access pass to premium plugins, offers, and more!

Join the Club

User Feedback

Recommended Comments

Very cool Jack! Is there a way to use an image ask a mask? Like a custom shape to reveal? Like maybe ones logo could reveal something below to a final reveal? Nevertheless, this product is amazing. Thank so much again!
Link to comment
Share on other sites

Awesome stuff can't wait to start using this. Just a quick Q, should the first TransformOrign example have that extra bracket after box1?
Link to comment
Share on other sites

In some browsers, you may notice a slight shift of pixels when an element starts/ends a 3D animation. This has nothing to do with GSAP - it's the browser jumping into 3D mode and working with the GPU. There is no known workaround. http://creativejs.com/2011/12/day-2-gpu-accelerate-your-dom-elements/
Link to comment
Share on other sites

Pav, if css3 transforms aren't supported in the browser the tweens are simply ignored just like regular css that isn't supported. There's no way to "degrade" 3D stuff (that I know of at least). And to be clear, the engine is using pure JavaScript, NOT CSS3 transitions or CSS3 animations.
Link to comment
Share on other sites

Ed, there's no way to use a custom shape as a mask consistently across browsers unless maybe you draw all your stuff to canvas. Regular DOM elements don't allow that sort of thing. If anyone knows otherwise, please chime in.
Link to comment
Share on other sites

Kudos to you, Jack. You're doing an excellent service to all Flash Developers who are struggling to create consistent, crossbrowser experiences in HTML5. Keep it up. I'm wondering if your engine matches well with three.js
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