Jump to content


Included in TweenMax: YES

With the help of the CSSPlugin, GSAP can animate almost any css-related property of DOM elements including the obvious things like width, height, margin, padding, top, left, and more plus more interesting things like transforms (rotation, scaleX, scaleY, skewX, skewY, x, y, rotationX, and rotationY), colors, opacity, and lots more.

Note: a common mistake is to forget to use camel case representations of the properties, so instead of "font-size", you'd use "fontSize". "background-color" should be "backgroundColor".

You can even define properties that are not generally tweenable and GSAP will apply the property for you (like position:"absolute" or borderStyle:"solid"). These non-tweenable properties will be set at the beginning of the tween (except display:"none" which will be applied at the end of the tween for obvious reasons).

It is typically a good idea to define a unit of measurement (like "24px" instead of "24" or "50%" rather than "50") but the default in most cases is pixels (px), so you can omit the unit if you prefer. And even if the unit of measurement doesn't match the current one, GSAP will attempt to convert them for you. So, for example, you could tween a width from "50%" to "200px".

CSSPlugin can animate complex values like boxShadow:"0px 0px 20px 20px red" and borderRadius:"50% 50%" and border:"5px solid rgb(0,255,0)". When necessary, it attempts to figure out if the property needs a vendor prefix and applies it accordingly. There may be a very small subset of complex or bleeding-edge css properties that CSSPlugin can't handle yet, but that's rare - it handles virtually all css properties you throw at it.

In addition to almost all of the standard css properties, CSSPlugin recognizes some special ones that can be quite convenient:

2D Transforms

CSS Transforms pose some unique challenges when it comes to animating them. A lot of work went into making sure that GSAP could overcome these challenges and provide easy-to-use solutions for animators. Be sure to check out the video below.

Top 10 Reasons to Use GSAP to Animate Transforms

One of the most convenient things about the CSSPlugin is that it greatly simplifies transforms (rotation, scaleX, scaleY, scale, skewX, skewY, x, y, xPercent and yPercent) in the various browsers including IE back through version 6! No need to mess with various browser prefixes or funky matrix filters in IE. GSAP exclusive: they even work on SVG elements! You can animate 2D transform properties intuitively:

//much simpler
TweenLite.to(element, 2, {rotation:30, scaleX:0.8});

By default, rotation, skewX, and skewY use degrees but you can use radians if you prefer. Simply append one of the standard suffixes ("rad" or "deg") like this:

//use "deg" or "rad"
TweenLite.to(element, 2, {rotation:"1.25rad", skewX:"30deg"});

To be clear, this is like setting the element's css to: transform:rotate(1.25rad) skewX(30deg) along with all the other browser prefix values and the necessary IE filter which would be much more verbose.

Notes about transforms

  1. To do percentage-based translation use xPercent and yPercent (added in version 1.13.0) instead of x or y which are typically px-based. Why does GSAP have special properties just for percentage-based translation? Because it allows you to COMBINE them to accomplish useful tasks, like perhaps you want to build your own "world" where everything has its origin in the very center of the world and then you move things in a px-based fashion from there - you could set xPercent and yPercent to -50 and position:"absolute" so that everything starts with their centers in the same spot, and then use x and y to move them from there. If you set x or y to a percent-based value like 50%", GSAP will recognize that and funnel that value to xPercent or yPercent appropriately as a convenience. Our 1.13.1 Release Notes have some great demos showing how xPercent and yPercent can help with responsive layouts.
  2. You can use scale as a shortcut to control both the scaleX and scaleY properties identically.
  3. You can define relative values, like rotation:"+=30"
  4. The order in which you declare the transform properties makes no difference.
  5. GSAP has nothing to do with the rendering quality of the element in the browser. Some browsers seem to render transformed elements beautifully while others don't handle anti-aliasing as well.
  6. IE6, IE7, and IE8 transforms don't apply to child elements (that's a browser limitation).
  7. By default, CSSPlugin uses a skewType of "compensated" which affects the skewX/skewY values in a slightly different (arguably more intuitive) way because visually the object isn't stretched. For example, if you set transform:skewX(85deg) in the browser via CSS, the object would become EXTREMELY long (stretched) whereas with skewType:"compensated", it would look more like it sheared in 3D space. This was a purposeful design decision because this behavior is more likely what animators desire. If you prefer the uncompensated behavior, you can set CSSPlugin.defaultSkewType = "simple" which affects the default for all skew tweens, or for an individual tween you can set the special property skewType:"simple".
  8. Percentage-based x/y translations also work on SVG elements. Caveat: it's calculated and then baked into the matrix(), so it's not "live" meaning if you later change the width/height of the SVG element, it doesn't alter the translation but you could certainly just re-apply the translation if you need to.
  9. For more info on how CSSPlugin handles transforms on SVG elements be sure to read our SVG Tips article.

3D Transforms

In addition to all of the regular 2D properties (x, y, scaleX, scaleY, scale, rotation, skewX, skewY, xPercent, and yPercent) that work in all browsers, you can animate 3D properties too like rotationXrotationYrotationZ (identical to regular rotation), zperspective, and transformPerspective in all modern browsers (see http://caniuse.com/transforms3d for details about browser support for 3D transforms). To see 3D transforms demonstrated visually in GSAP, see http://greensock.com/css3/. Again, there is no need to use browser prefixes; CSSPlugin handles all of that for you under the hood. You can animate 3D transform properties and 2D properties together intuitively:

TweenLite.to(element, 2, {rotationX:45, scaleX:0.8, z:-300});

To get your elements to have a true 3D visual perspective applied, you must either set the perspective property of the parent element or set the special transformPerspective of the element itself (common values range from around 200 to 1000, the lower the number the stronger the perspective distortion). The transformPerspective is like adding a perspective() directly inside the css "transform" style, like: transform: perspective(500px) rotateX(45deg) which only applies to that specific element whereas if you want to a group of elements share a common perspective (the same vanishing point), you should set the regular perspective property on the parent/container of those elements. For more information about perspective, see this article.

//apply a perspective to the PARENT element (the container) to make the perspective apply to all child elements (typically best)
TweenLite.set(container, {perspective:500});
//or set a default perspective that will be applied to every individual element that you tween in 3D:
CSSPlugin.defaultTransformPerspective = 500;
//or apply perspective to a single element using "transformPerspective"
TweenLite.set(element, {transformPerspective:500});

In regular CSS, the order that you list the transforms matters but GSAP always applies them in the same order for consistency: translation (x, y, z), then scale, then rotationX, then rotationY, then skew, then rotation (same as rotationZ) although in terms of constructing the matrix, the math is technically done in the reverse of that order. If you want to rotate the element around a point in 3D space other than its center, use the transformOrigin property (see below).

//sample css:
.myClass {
    transform: translate3d(10px, 0px, -200px) rotateY(45deg) scale(1.5, 1.5);
//corresponding GSAP transform (tweened over 2 seconds):
TweenLite.to(element, 2, {scale:1.5, rotationY:45, x:10, y:0, z:-200});
//sample css that uses a perspective():
.myClass {
    transform: perspective(500px) translateY(50px) rotate(120deg)
//corresponding GSAP transform (set, not tweened):
TweenLite.set(element, {transformPerspective:500, rotation:120, y:50});

Notes about 3D transforms

  1. In browsers that don't support 3D transforms, they'll be ignored. For example, rotationX may not work, but rotation would. See http://caniuse.com/transforms3d for a chart of which browser versions support 3D transforms.
  2. All transforms are cached in a _gsTransform object attached to the element, so you can tween individual properties without worrying that they'll be lost. You don't need to define all of the transform properties on every tween - only the ones you want to animate. You can read the transform-related values anytime, like element._gsTransform.scaleX. If you'd like to clear those values (including the transform applied to the inline style of the element), you can do TweenLite.set(element, {clearProps:"transform"});. If you'd like to force GSAP to re-parse the transform data from the css (rather than use the data it had recorded from previous tweens), you can pass parseTransform:true into the config object.
  3. GSAP has nothing to do with the rendering quality of the element in the browser. Some browsers seem to render transformed elements beautifully while others don't handle anti-aliasing as well.
  4. To learn more about css 3D transforms, see this article
  5. IE10 supports 3D transforms, but it does not support transformStyle of "preserve-3d" (see Microsoft's site for details).


As of 1.15.0, force3D defaults to "auto" mode which means transforms are automatically optimized for speed by using matrix3d() instead of matrix(), or translate3d() instead of translate(). This typically results in the browser putting that element onto its own compositor layer, making animation updates more efficient. In "auto" mode, GSAP will automatically switch back to 2D when the tween is done (if 3D isn't necessary) to free up more GPU memory. If you'd prefer to keep it in 3D mode, you can set force3D:true. Or, to stay in 2D mode whenever possible, set force3D:false. See http://css-tricks.com/myth-busting-css-animations-vs-javascript/ for more details about performance.


Sets the origin around which all transforms (2D and/or 3D) occur. By default, it is in the center of the element ("50% 50%"). You can define the values using the keywords "top", "left", "right", or "bottom" or you can use percentages (bottom right corner would be "100% 100%") or pixels. If, for example, you want an object to spin around its top left corner you can do this:

//spins around the element's top left corner
TweenLite.to(element, 2, {rotation:360, transformOrigin:"left top"});

The first value in the quotes corresponds to the x-axis and the second corresponds to the y-axis, so to make the object transform around exactly 50px in from its left edge and 20px from its top edge, you could do:

//spins/scales around a point offset from the top left by 50px, 20px
TweenLite.to(element, 2, {rotation:270, scale:0.5, transformOrigin:"50px 20px"});

GSAP exclusive: this even works with SVG elements!

You can define a transformOrigin as a 3D value by adding a 3rd number, like to rotate around the y-axis from a point that is offset 400px in the distance, you could do:

//rotates around a point that is 400px back in 3D space, creating an interesting effect:
TweenLite.to(element, 2, {rotationY:360, transformOrigin:"50% 50% -400px"});

Notes about transformOrigin:

  1. CSSPlugin automatically works around a bug in Safari that causes 3D transformOrigin values to incorrectly act as though they affect translateZ(). To work around the bug, when you perform a 3D tween that has a transformOrigin with a non-zero z component (like transformOrigin:"50% 50% -100px"), CSSPlugin will record the z-component (-100px in this example) internally and remove it from the transformOrigin that gets applied to the css. Everything will render correctly because the z-axis origin offset is calculated internally and applied to the matrix3d(). Just keep in mind that if you check the css value of the transformOrigin after the tween has started, it won't have the z component but that's by design.
  2. transformOrigin even works in Internet Explorer back to version 6 in 2D, although it is recommended that you set the element's position to "absolute" to avoid clipping.
  3. GSAP does make transformOrigin work on SVG elements consistently across browsers (GSAP exclusive) but keep in mind that SVG elements don't officially support 3D transforms according to the spec.


[Only for SVG elements] Works exactly like transformOrigin but it uses the SVG's global coordinate space instead of the element's local coordinate space. This can be very useful if, for example, you want to make a bunch of SVG elements rotate around a common point. You can either define an svgOrigin or a transformOrigin, not both (for obvious reasons). So you can do TweenLite.to(svgElement, 1, {rotation:270, svgOrigin:"250 100"}) if you'd like to rotate svgElement as though its origin is at x:250, y:100 in the SVG canvas's global coordinates. Units are not required. It also records the value in a data-svg-origin attribute so that it can be parsed back in. svgOrigin doesn't accommodate percentage-based values. See an example here.

smoothOrigin (for SVG only)

When changing the transformOrigin (or svgOrigin) of an SVG element, CSSPlugin will now automatically record/apply some offsets to ensure that the element doesn't "jump". You can disable this by setting CSSPlugin.defaultSmoothOrigin = false, or you can control it on a per-tween basis using smoothOrigin:true | false. Explanation: The way transforms and transform-origins work in the browser (and according to the official spec), changing the origin causes the element jump in a jarring way. For example, if you rotate 180 degrees when the transform-origin is in the element's top left corner, it ends up at a very different position than if you applied the same rotation around its bottom right corner. Since GSAP is focused on solving real-world problems for animators (most of whom prefer to smoothly alter the transformOrigin), the new smoothOrigin feature in GSAP solves this issue. This also means that if you create SVG artwork in an authoring program like Adobe Flash where it may not be easy/obvious to control where the element's origin is, things will "just work" when you define a transformOrigin via GSAP. Currently, this feature only applies to SVG elements, as that is where it is more commonly a pain-point, and we're eager to see how GSAP users employ the feature and share their feedback/suggestions before we consider adding it to "regular" DOM elements.

Video explaining smoothOrigin


Tweens rotation in a particular direction which can be either clockwise ("_cw" suffix), counter-clockwise ("_ccw" suffix), or in the shortest direction ("_short" suffix) in which case the plugin chooses the direction for you based on the shortest path. For example, if the element's rotation is currently 170 degrees and you want to tween it to -170 degrees, a normal rotation tween would travel a total of 340 degrees in the counter-clockwise direction, but if you use the _short suffix, it would travel 20 degrees in the clockwise direction instead. Example:

TweenLite.to(element, 2, {rotation:"-170_short"});
//or even use it on 3D rotations and use relative prefixes:
TweenLite.to(element, 2, {rotation:"-170_short", rotationX:"-=30_cw", rotationY:"1.5rad_ccw"});

Notice that the value is in quotes, thus a string with a particular suffix indicating the direction (_cw, _ccw, or _short). You can also use the "+=" or "-=" prefix to indicate relative values. Directional rotation suffixes are supported in all rotational properties (rotation, rotationX, and rotationY); you don't need to use directionalRotation as the property name. There is a DirectionalRotationPlugin that you can use to animate objects that aren't DOM elements, but there's no need to load that plugin if you're just animating css-related properties with CSSPlugin because it has DirectionalRotationPlugin's capabilities baked-in.

Check out an interactive example here.

Prior to version 1.9.0, directionalRotation was called shortRotation and it only handled going in the shortest direction. The new directionalRotation functionality is much more flexible and easy to use (just slap a suffix on the regular property).


Identical to opacity except that when the value hits 0 the visibility property will be set to "hidden" in order to improve browser rendering performance and prevent clicks/interactivity on the target. When the value is anything other than 0, visibility will be set to "inherit". It is not set to "visible" in order to honor inheritance (imagine the parent element is hidden - setting the child to visible explicitly would cause it to appear when that's probably not what was intended). And for convenience, if the element's visibility is initially set to "hidden" and opacity is 1, it will assume opacity should also start at 0. This makes it simple to start things out on your page as invisible (set your css visibility:hidden) and then fade them in whenever you want.

//fade out and set visibility:hidden
TweenLite.to(element, 2, {autoAlpha:0});
//in 2 seconds, fade back in with visibility:visible
TweenLite.to(element, 2, {autoAlpha:1, delay:2});


Allows you to morph between classes on an element. For example, let's say myElement has a class of "class1" currently and you want to change to "class2" and animate the differences, you could do this:

TweenLite.to(myElement, 1, {className:"class2"});

And if you want to ADD the class to the existing one, you can simply use the "+=" prefix. To remove a class, use the "-=" prefix like this:

TweenLite.to(myElement, 1, {className:"+=class2"});

Note: there are some css-related properties that don't tween like IE filters, but almost every css property is recognized and animates great. Also, there is a slight speed penalty when a className tween initializes because the engine needs to loop through all of the css properties to see which ones are different.


Animate virtually any property (or properties) along a Bezier (curved) path which you define as an array of points/values that can be interpreted in several different ways, like as points through which a Bezier should be drawn, or cubic or quadratic Bezier control and anchor points, etc. See the BezierPlugin's documentation for details and an explanation of all the features available. Don't forget to load the BezierPlugin JavaScript file in order to utilize its features from within CSSPlugin. Here is an example of a bezier tween that makes an element curve through 3 points using x and y transform properties and also automatically rotates it along the path as it goes:

TweenLite.to(element, 5, {bezier:{curviness:1.25, values:[{x:100, y:200}, {x:250, y:400}, {x:500, y:50}], autoRotate:true}, ease:Power1.easeOut});

CSS variables

As of version 1.20.0, GSAP can animate CSS variables in browsers that support them.


A comma-delimited list of property names that you want to clear from the element's "style" property when the tween completes (or use "all" to clear all properties). This can be useful if, for example, you have a class (or some other selector) that should apply certain styles to an element when the tween is over that would otherwise get overridden by the element.style-specific data that was applied during the tween. Typically you do not need to include vendor prefixes.

//tweens 3 properties and then clears only "left" and "transform" (because "scale" affects the "transform" css property. CSSPlugin automatically applies the vendor prefix if necessary too)
 TweenLite.from(element, 5, {scale:0, left:200, backgroundColor:"red", clearProps:"scale,left"});


By default, CSSPlugin will round pixel values and zIndex to the closest integer during the tween (the inbetween values) because it improves browser performance, but if you'd rather disable that behavior, pass autoRound:false in the css object. You can still use the RoundPropsPlugin to manually define properties that you want rounded.

If you need to animate numeric attributes (rather than css-related properties), you can use the AttrPlugin. And to replace the text in a DOM element, use the TextPlugin.

Note about css:{} wrapper

Originally, css-specific properties needed to be wrapped in their own object and passed in like TweenLite.to(element, 1, {css:{left:"100px", top:"50px"}}); so that the engine could determine the properties that should be funneled to CSSPlugin, but because animating DOM elements in the browser is so common, TweenLite and TweenMax (as of version 1.8.0) automatically check to see if the target is a DOM element and if so, it creates that css object for you and shifts any properties that aren't defined directly on the element or reserved (like onComplete, ease, delay, etc. or plugin keywords like scrollTo, easel, etc.) into that css object when the tween renders for the first time. In the code examples below, we'll use the more concise style that omits the css:{} object but be aware that either style is acceptable.

//as of 1.8.0 the following lines produce identical results:
TweenLite.to(element, 1, {top:"20px", backgroundColor:"#FF0000", ease:Power2.easeOut});
//longer, less convenient syntax:
TweenLite.to(element, 1, {css:{top:"20px", backgroundColor:"#FF0000"}, ease:Power2.easeOut});

Official GreenSock Training (videos and eBook)

If you want to learn all of what GSAP can do check out our official video training Learn HTML5 Animation with GreenSock which includes over 5 hours of HD video created by our Geek Ambassador, Carl Schooff. This course is packed with real-world projects and detailed step-by-step instructions.

Copyright 2017, GreenSock. All rights reserved. This work is subject to theterms of useor for Club GreenSock members, the software agreement that was issued with the membership.