Jump to content

GreenSock Docs


Included in GSAP core: 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", 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 9! 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:

  1. //much simpler
  2. gsap.to(element, {duration: 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:

  1. //use "deg" or "rad"
  2. gsap.to(element, {duration: 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.

Notes about transforms

  1. To do percentage-based translation use xPercent and yPercent instead of x or y which are typically pixel 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.

  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. Percentage-based x/y translations also work on SVG elements.

  7. 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 rotationX, rotationY, rotationZ (identical to regular rotation), z, perspective, and transformPerspective in all modern browsers (see Can I Use for details about browser support for 3D transforms). To see 3D transforms demonstrated visually in GSAP, see this blog post. 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:

  1. gsap.to(element, {duration: 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. If you want a group of elements to 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.

  1. //apply a perspective to the PARENT element (the container) to make the perspective apply to all child elements (typically best)
  2. gsap.set(container, {perspective: 500});
  3. //or set a default perspective that will be applied to every individual element that you tween in 3D:
  4. CSSPlugin.defaultTransformPerspective = 500;
  5. //or apply perspective to a single element using "transformPerspective"
  6. gsap.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).

If you want to rotate the element around a point in 3D space other than its center, use the transformOrigin property (see below).

  1. //sample css:
  2. .myClass {
  3. transform: translate3d(10px, 0px, -200px) rotateY(45deg) scale(1.5, 1.5);
  4. }
  5. //corresponding GSAP transform (tweened over 2 seconds):
  6. gsap.to(element, {duration: 2, scale: 1.5, rotationY: 45, x: 10, y: 0, z: -200});
  7. //sample CSS that uses a perspective():
  8. .myClass {
  9. transform: perspective(500px) translateY(50px) rotate(120deg);
  10. }
  11. //corresponding GSAP transform (set, not tweened):
  12. gsap.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 https://caniuse.com/transforms3d for a chart of which browser versions support 3D transforms.

  2. All transforms are cached, 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 (or any property) anytime using the gsap.getProperty() method. If you’d like to clear those values (including the transform applied to the inline style of the element), you can do gsap.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 a transformStyle of "preserve-3d" (see Microsoft’s site for details).


force3D defaults to "auto" mode which means transforms are automatically optimized for speed by using 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 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:

  1. //spins around the element's top left corner
  2. gsap.to(element, {duration: 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:

  1. //spins/scales around a point offset from the top left by 50px, 20px
  2. gsap.to(element, {duration: 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:

  1. //rotates around a point that is 400px back in 3D space, creating an interesting effect:
  2. gsap.to(element, {duration: 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 transform. 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. 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 gsap.to(svgElement, {duration: 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. View an example.


[Only for SVG elements] 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 or smoothOrigin: 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 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.


Tweens rotation for a CSS property 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:

  1. gsap.to(element, {duration: 2, rotation: "-170_short"});
  2. //or even use it on 3D rotations and use relative prefixes:
  3. gsap.to(element, {duration: 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.


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.

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

CSS variables

GSAP can animate CSS variables in browsers that support them.


You may enter a comma-delimited list of property names into clearProps 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.

  1. //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)
  2. gsap.from(element, {duration: 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 gsap.to(element, {duration: 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, GSAP now automatically checks 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.

  1. //the following lines produce identical results:
  2. gsap.to(element, {duration: 1, top: "20px", backgroundColor: "#FF0000", ease: "Power2.easeOut"});
  3. //longer, less convenient syntax:
  4. TweenLite.to(element, {duration: 1, css: {top: "20px", backgroundColor: "#FF0000"}, ease: "Power2.easeOut"});
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.