[{"data":1,"prerenderedAt":1115},["ShallowReactive",2],{"guide-css-transform-vs-css-animation":3},{"id":4,"title":5,"body":6,"date":1107,"description":1108,"extension":1109,"meta":1110,"navigation":211,"path":1111,"readingTime":237,"seo":1112,"stem":1113,"__hash__":1114},"guides\u002Fguides\u002Fcss-transform-vs-css-animation.md","CSS Transform vs CSS Animation",{"type":7,"value":8,"toc":1085},"minimark",[9,14,27,43,46,50,58,123,126,131,151,155,161,284,287,291,322,326,340,344,350,452,456,499,503,517,521,529,608,632,636,639,669,673,775,779,782,813,1010,1014,1044,1048,1057,1061,1081],[10,11,13],"h2",{"id":12},"the-core-distinction","The Core Distinction",[15,16,17,18,22,23,26],"p",{},"CSS ",[19,20,21],"strong",{},"transforms"," change how an element looks — move it, rotate it, scale it, skew it. CSS ",[19,24,25],{},"animations and transitions"," change properties over time — making those transforms happen smoothly across frames.",[15,28,29,30,34,35,38,39,42],{},"They are not alternatives. They are complementary tools. Transforms describe ",[31,32,33],"em",{},"what"," changes. Animations and transitions describe ",[31,36,37],{},"when"," and ",[31,40,41],{},"how"," it changes.",[15,44,45],{},"Understanding this distinction prevents you from reaching for the wrong tool.",[10,47,49],{"id":48},"css-transforms-the-what","CSS Transforms: The What",[15,51,52,53,57],{},"A ",[54,55,56],"code",{},"transform"," applies a visual modification without affecting document flow. The element still occupies its original space — only its rendering changes.",[59,60,65],"pre",{"className":61,"code":62,"language":63,"meta":64,"style":64},"language-css shiki shiki-themes github-light github-dark",".card:hover {\n  transform: scale(1.05) translateY(-2px);\n}\n","css","",[54,66,67,80,117],{"__ignoreMap":64},[68,69,72,76],"span",{"class":70,"line":71},"line",1,[68,73,75],{"class":74},"sScJk",".card:hover",[68,77,79],{"class":78},"sVt8B"," {\n",[68,81,83,87,90,93,96,99,102,105,107,110,114],{"class":70,"line":82},2,[68,84,86],{"class":85},"sj4cs","  transform",[68,88,89],{"class":78},": ",[68,91,92],{"class":85},"scale",[68,94,95],{"class":78},"(",[68,97,98],{"class":85},"1.05",[68,100,101],{"class":78},") ",[68,103,104],{"class":85},"translateY",[68,106,95],{"class":78},[68,108,109],{"class":85},"-2",[68,111,113],{"class":112},"szBVR","px",[68,115,116],{"class":78},");\n",[68,118,120],{"class":70,"line":119},3,[68,121,122],{"class":78},"}\n",[15,124,125],{},"This instantly jumps the card to its new size and position. No motion. No smoothness. Just a state change.",[127,128,130],"h3",{"id":129},"when-transforms-alone-are-enough","When transforms alone are enough",[132,133,134,138,141,144],"ul",{},[135,136,137],"li",{},"State changes triggered by hover, focus, or class toggles",[135,139,140],{},"Instant visual feedback where animation would feel sluggish",[135,142,143],{},"Print layouts where motion is irrelevant",[135,145,146,147,150],{},"Reducing an element to zero size with ",[54,148,149],{},"scale(0)"," for removal",[10,152,154],{"id":153},"css-transitions-the-simple-how","CSS Transitions: The Simple How",[15,156,52,157,160],{},[54,158,159],{},"transition"," animates a property change between two states. You define duration, timing function, and delay on the element itself.",[59,162,164],{"className":61,"code":163,"language":63,"meta":64,"style":64},".card {\n  transition: transform 0.3s ease, box-shadow 0.3s ease;\n}\n\n.card:hover {\n  transform: scale(1.05);\n  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);\n}\n",[54,165,166,173,202,206,213,220,235,279],{"__ignoreMap":64},[68,167,168,171],{"class":70,"line":71},[68,169,170],{"class":74},".card",[68,172,79],{"class":78},[68,174,175,178,181,184,187,190,193,195,197,199],{"class":70,"line":82},[68,176,177],{"class":85},"  transition",[68,179,180],{"class":78},": transform ",[68,182,183],{"class":85},"0.3",[68,185,186],{"class":112},"s",[68,188,189],{"class":85}," ease",[68,191,192],{"class":78},", box-shadow ",[68,194,183],{"class":85},[68,196,186],{"class":112},[68,198,189],{"class":85},[68,200,201],{"class":78},";\n",[68,203,204],{"class":70,"line":119},[68,205,122],{"class":78},[68,207,209],{"class":70,"line":208},4,[68,210,212],{"emptyLinePlaceholder":211},true,"\n",[68,214,216,218],{"class":70,"line":215},5,[68,217,75],{"class":74},[68,219,79],{"class":78},[68,221,223,225,227,229,231,233],{"class":70,"line":222},6,[68,224,86],{"class":85},[68,226,89],{"class":78},[68,228,92],{"class":85},[68,230,95],{"class":78},[68,232,98],{"class":85},[68,234,116],{"class":78},[68,236,238,241,243,246,249,251,254,256,259,261,263,266,268,270,272,274,277],{"class":70,"line":237},7,[68,239,240],{"class":85},"  box-shadow",[68,242,89],{"class":78},[68,244,245],{"class":85},"0",[68,247,248],{"class":85}," 8",[68,250,113],{"class":112},[68,252,253],{"class":85}," 24",[68,255,113],{"class":112},[68,257,258],{"class":85}," rgba",[68,260,95],{"class":78},[68,262,245],{"class":85},[68,264,265],{"class":78},", ",[68,267,245],{"class":85},[68,269,265],{"class":78},[68,271,245],{"class":85},[68,273,265],{"class":78},[68,275,276],{"class":85},"0.15",[68,278,116],{"class":78},[68,280,282],{"class":70,"line":281},8,[68,283,122],{"class":78},[15,285,286],{},"The browser interpolates between the resting state and the hover state over 0.3 seconds.",[127,288,290],{"id":289},"transition-strengths","Transition strengths",[132,292,293,299,305,311],{},[135,294,295,298],{},[19,296,297],{},"Simple to write"," — one line per property",[135,300,301,304],{},[19,302,303],{},"Automatic reversal"," — moving the mouse away transitions back",[135,306,307,310],{},[19,308,309],{},"No keyframes needed"," — two states only",[135,312,313,316,317,38,319],{},[19,314,315],{},"Performant"," — when limited to ",[54,318,56],{},[54,320,321],{},"opacity",[127,323,325],{"id":324},"transition-limitations","Transition limitations",[132,327,328,331,334,337],{},[135,329,330],{},"Cannot chain multiple steps",[135,332,333],{},"Cannot loop or pause mid-animation",[135,335,336],{},"Cannot describe complex sequences",[135,338,339],{},"Only interpolate between two values — no intermediate stops",[10,341,343],{"id":342},"css-animations-the-full-control-how","CSS Animations: The Full Control How",[15,345,346,349],{},[54,347,348],{},"@keyframes"," animations give you full control over every frame of the motion — multiple stops, loops, directions, and playback states.",[59,351,353],{"className":61,"code":352,"language":63,"meta":64,"style":64},"@keyframes pulse {\n  0%, 100% { transform: scale(1); }\n  50% { transform: scale(1.08); }\n}\n\n.badge {\n  animation: pulse 2s ease-in-out infinite;\n}\n",[54,354,355,365,392,412,416,420,427,448],{"__ignoreMap":64},[68,356,357,359,363],{"class":70,"line":71},[68,358,348],{"class":112},[68,360,362],{"class":361},"s4XuR"," pulse",[68,364,79],{"class":78},[68,366,367,370,372,375,378,380,382,384,386,389],{"class":70,"line":82},[68,368,369],{"class":74},"  0%",[68,371,265],{"class":78},[68,373,374],{"class":74},"100%",[68,376,377],{"class":78}," { ",[68,379,56],{"class":85},[68,381,89],{"class":78},[68,383,92],{"class":85},[68,385,95],{"class":78},[68,387,388],{"class":85},"1",[68,390,391],{"class":78},"); }\n",[68,393,394,397,399,401,403,405,407,410],{"class":70,"line":119},[68,395,396],{"class":74},"  50%",[68,398,377],{"class":78},[68,400,56],{"class":85},[68,402,89],{"class":78},[68,404,92],{"class":85},[68,406,95],{"class":78},[68,408,409],{"class":85},"1.08",[68,411,391],{"class":78},[68,413,414],{"class":70,"line":208},[68,415,122],{"class":78},[68,417,418],{"class":70,"line":215},[68,419,212],{"emptyLinePlaceholder":211},[68,421,422,425],{"class":70,"line":222},[68,423,424],{"class":74},".badge",[68,426,79],{"class":78},[68,428,429,432,435,438,440,443,446],{"class":70,"line":237},[68,430,431],{"class":85},"  animation",[68,433,434],{"class":78},": pulse ",[68,436,437],{"class":85},"2",[68,439,186],{"class":112},[68,441,442],{"class":85}," ease-in-out",[68,444,445],{"class":85}," infinite",[68,447,201],{"class":78},[68,449,450],{"class":70,"line":281},[68,451,122],{"class":78},[127,453,455],{"id":454},"animation-strengths","Animation strengths",[132,457,458,464,474,485,493],{},[135,459,460,463],{},[19,461,462],{},"Multi-step sequences"," — as many keyframe stops as you need",[135,465,466,469,470,473],{},[19,467,468],{},"Looping"," — ",[54,471,472],{},"infinite"," or a fixed count",[135,475,476,469,479,265,482],{},[19,477,478],{},"Direction control",[54,480,481],{},"alternate",[54,483,484],{},"reverse",[135,486,487,469,490],{},[19,488,489],{},"Playback control",[54,491,492],{},"animation-play-state: paused",[135,494,495,498],{},[19,496,497],{},"Independent of state changes"," — runs regardless of hover or focus",[127,500,502],{"id":501},"animation-limitations","Animation limitations",[132,504,505,508,511],{},[135,506,507],{},"More verbose syntax",[135,509,510],{},"Harder to reverse on interaction without JavaScript",[135,512,513,514],{},"Infinite animations consume resources even when off-screen unless you manage ",[54,515,516],{},"animation-play-state",[10,518,520],{"id":519},"performance-comparison","Performance Comparison",[15,522,523,524,38,526,528],{},"All three — transforms, transitions, and animations — can run on the compositor thread when you limit yourself to ",[54,525,56],{},[54,527,321],{},". But the cost profile differs.",[530,531,532,551],"table",{},[533,534,535],"thead",{},[536,537,538,542,545,548],"tr",{},[539,540,541],"th",{},"Technique",[539,543,544],{},"Compositor-friendly?",[539,546,547],{},"Main-thread cost",[539,549,550],{},"Memory overhead",[552,553,554,571,590],"tbody",{},[536,555,556,562,565,568],{},[557,558,559,561],"td",{},[54,560,56],{}," (instant)",[557,563,564],{},"Yes",[557,566,567],{},"Near zero",[557,569,570],{},"Layer creation",[536,572,573,577,586,588],{},[557,574,575],{},[54,576,159],{},[557,578,579,580,582,583,585],{},"Yes (if ",[54,581,56],{},"\u002F",[54,584,321],{},")",[557,587,567],{},[557,589,570],{},[536,591,592,597,603,605],{},[557,593,594,596],{},[54,595,348],{}," animation",[557,598,579,599,582,601,585],{},[54,600,56],{},[54,602,321],{},[557,604,567],{},[557,606,607],{},"Layer creation + keyframe storage",[15,609,610,611,614,615,265,618,265,621,265,624,627,628,631],{},"The performance trap is not the technique you choose — it is the ",[19,612,613],{},"properties you animate",". Animating ",[54,616,617],{},"width",[54,619,620],{},"height",[54,622,623],{},"margin",[54,625,626],{},"top",", or ",[54,629,630],{},"left"," triggers layout recalculation on every frame, regardless of whether you use transitions or keyframes.",[127,633,635],{"id":634},"the-compositor-checklist","The compositor checklist",[15,637,638],{},"For 60fps animation:",[640,641,642,649,656,663,666],"ol",{},[135,643,644,645,38,647],{},"Animate only ",[54,646,56],{},[54,648,321],{},[135,650,651,652,655],{},"Set ",[54,653,654],{},"will-change: transform"," before animation starts",[135,657,658,659,662],{},"Remove ",[54,660,661],{},"will-change"," after it ends",[135,664,665],{},"Keep animated elements small in surface area",[135,667,668],{},"Test on mobile devices, not just desktop",[10,670,672],{"id":671},"when-to-use-each","When to Use Each",[530,674,675,688],{},[533,676,677],{},[536,678,679,682,685],{},[539,680,681],{},"Scenario",[539,683,684],{},"Best choice",[539,686,687],{},"Why",[552,689,690,701,711,722,733,743,754,765],{},[536,691,692,695,698],{},[557,693,694],{},"Hover lift on a button",[557,696,697],{},"Transition",[557,699,700],{},"Two states, simple, auto-reverses",[536,702,703,706,708],{},[557,704,705],{},"Focus ring grow",[557,707,697],{},[557,709,710],{},"Follows user interaction naturally",[536,712,713,716,719],{},[557,714,715],{},"Loading spinner",[557,717,718],{},"Keyframe animation",[557,720,721],{},"Loops infinitely, state-independent",[536,723,724,727,730],{},[557,725,726],{},"Card flip on click",[557,728,729],{},"Transition + transform",[557,731,732],{},"Two states, JS toggles class",[536,734,735,738,740],{},[557,736,737],{},"Complex onboarding sequence",[557,739,718],{},[557,741,742],{},"Multiple steps with timing",[536,744,745,748,751],{},[557,746,747],{},"Instant button press effect",[557,749,750],{},"Transform only",[557,752,753],{},"No motion desired, just a state",[536,755,756,759,762],{},[557,757,758],{},"Parallax scroll effect",[557,760,761],{},"JS + transform",[557,763,764],{},"Scroll position drives transform",[536,766,767,770,772],{},[557,768,769],{},"Notification badge pulse",[557,771,718],{},[557,773,774],{},"Loops until dismissed",[10,776,778],{"id":777},"combining-them-effectively","Combining Them Effectively",[15,780,781],{},"Real interfaces often combine all three. A notification card might:",[640,783,784,795,804],{},[135,785,786,788,789,265,792,585],{},[19,787,697],{}," into view on mount (",[54,790,791],{},"opacity 0 → 1",[54,793,794],{},"translateY(20px → 0)",[135,796,797,800,801,585],{},[19,798,799],{},"Animate"," a pulse on the badge (",[54,802,803],{},"@keyframes pulse",[135,805,806,809,810,585],{},[19,807,808],{},"Transform"," instantly on click to indicate press (",[54,811,812],{},"scale(0.95)",[59,814,816],{"className":61,"code":815,"language":63,"meta":64,"style":64},".notification {\n  transition: opacity 0.4s ease, transform 0.4s ease;\n  opacity: 0;\n  transform: translateY(20px);\n}\n\n.notification.visible {\n  opacity: 1;\n  transform: translateY(0);\n}\n\n.notification:active {\n  transform: scale(0.95);\n  transition: transform 0.1s ease;\n}\n\n.notification .badge {\n  animation: pulse 2s ease-in-out infinite;\n}\n",[54,817,818,825,850,861,878,882,886,893,903,918,923,928,936,952,968,973,978,988,1005],{"__ignoreMap":64},[68,819,820,823],{"class":70,"line":71},[68,821,822],{"class":74},".notification",[68,824,79],{"class":78},[68,826,827,829,832,835,837,839,842,844,846,848],{"class":70,"line":82},[68,828,177],{"class":85},[68,830,831],{"class":78},": opacity ",[68,833,834],{"class":85},"0.4",[68,836,186],{"class":112},[68,838,189],{"class":85},[68,840,841],{"class":78},", transform ",[68,843,834],{"class":85},[68,845,186],{"class":112},[68,847,189],{"class":85},[68,849,201],{"class":78},[68,851,852,855,857,859],{"class":70,"line":119},[68,853,854],{"class":85},"  opacity",[68,856,89],{"class":78},[68,858,245],{"class":85},[68,860,201],{"class":78},[68,862,863,865,867,869,871,874,876],{"class":70,"line":208},[68,864,86],{"class":85},[68,866,89],{"class":78},[68,868,104],{"class":85},[68,870,95],{"class":78},[68,872,873],{"class":85},"20",[68,875,113],{"class":112},[68,877,116],{"class":78},[68,879,880],{"class":70,"line":215},[68,881,122],{"class":78},[68,883,884],{"class":70,"line":222},[68,885,212],{"emptyLinePlaceholder":211},[68,887,888,891],{"class":70,"line":237},[68,889,890],{"class":74},".notification.visible",[68,892,79],{"class":78},[68,894,895,897,899,901],{"class":70,"line":281},[68,896,854],{"class":85},[68,898,89],{"class":78},[68,900,388],{"class":85},[68,902,201],{"class":78},[68,904,906,908,910,912,914,916],{"class":70,"line":905},9,[68,907,86],{"class":85},[68,909,89],{"class":78},[68,911,104],{"class":85},[68,913,95],{"class":78},[68,915,245],{"class":85},[68,917,116],{"class":78},[68,919,921],{"class":70,"line":920},10,[68,922,122],{"class":78},[68,924,926],{"class":70,"line":925},11,[68,927,212],{"emptyLinePlaceholder":211},[68,929,931,934],{"class":70,"line":930},12,[68,932,933],{"class":74},".notification:active",[68,935,79],{"class":78},[68,937,939,941,943,945,947,950],{"class":70,"line":938},13,[68,940,86],{"class":85},[68,942,89],{"class":78},[68,944,92],{"class":85},[68,946,95],{"class":78},[68,948,949],{"class":85},"0.95",[68,951,116],{"class":78},[68,953,955,957,959,962,964,966],{"class":70,"line":954},14,[68,956,177],{"class":85},[68,958,180],{"class":78},[68,960,961],{"class":85},"0.1",[68,963,186],{"class":112},[68,965,189],{"class":85},[68,967,201],{"class":78},[68,969,971],{"class":70,"line":970},15,[68,972,122],{"class":78},[68,974,976],{"class":70,"line":975},16,[68,977,212],{"emptyLinePlaceholder":211},[68,979,981,983,986],{"class":70,"line":980},17,[68,982,822],{"class":74},[68,984,985],{"class":74}," .badge",[68,987,79],{"class":78},[68,989,991,993,995,997,999,1001,1003],{"class":70,"line":990},18,[68,992,431],{"class":85},[68,994,434],{"class":78},[68,996,437],{"class":85},[68,998,186],{"class":112},[68,1000,442],{"class":85},[68,1002,445],{"class":85},[68,1004,201],{"class":78},[68,1006,1008],{"class":70,"line":1007},19,[68,1009,122],{"class":78},[10,1011,1013],{"id":1012},"key-takeaways","Key Takeaways",[132,1015,1016,1025,1028,1031,1038,1041],{},[135,1017,1018,1019,1021,1022,1024],{},"Transforms describe ",[31,1020,33],{}," changes; transitions and animations describe ",[31,1023,41],{}," it changes over time",[135,1026,1027],{},"Use transitions for simple two-state change animations — hover, focus, class toggles",[135,1029,1030],{},"Use keyframe animations for multi-step sequences, loops, and state-independent motion",[135,1032,1033,1034,38,1036],{},"Performance depends on the properties you animate, not the technique — stick to ",[54,1035,56],{},[54,1037,321],{},[135,1039,1040],{},"Combining all three techniques is normal and expected in production interfaces",[135,1042,1043],{},"Always test animations on mid-range mobile devices to catch performance issues early",[10,1045,1047],{"id":1046},"try-it-yourself","Try It Yourself",[15,1049,1050,1051,1056],{},"Build and preview CSS transforms with smooth transitions using our ",[1052,1053,1055],"a",{"href":1054},"\u002Ftools\u002Fcss-transform","CSS Transform Tool",". Adjust values visually and copy production-ready code directly into your project.",[10,1058,1060],{"id":1059},"related-guides","Related Guides",[132,1062,1063,1069,1075],{},[135,1064,1065],{},[1052,1066,1068],{"href":1067},"\u002Fguides\u002Fcss-transform-guide","CSS Transform Guide",[135,1070,1071],{},[1052,1072,1074],{"href":1073},"\u002Fguides\u002Fcss-visual-effects","CSS Visual Effects",[135,1076,1077],{},[1052,1078,1080],{"href":1079},"\u002Fguides\u002Fcss-animation-tools","CSS Animation Tools",[1082,1083,1084],"style",{},"html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}",{"title":64,"searchDepth":82,"depth":82,"links":1086},[1087,1088,1091,1095,1099,1102,1103,1104,1105,1106],{"id":12,"depth":82,"text":13},{"id":48,"depth":82,"text":49,"children":1089},[1090],{"id":129,"depth":119,"text":130},{"id":153,"depth":82,"text":154,"children":1092},[1093,1094],{"id":289,"depth":119,"text":290},{"id":324,"depth":119,"text":325},{"id":342,"depth":82,"text":343,"children":1096},[1097,1098],{"id":454,"depth":119,"text":455},{"id":501,"depth":119,"text":502},{"id":519,"depth":82,"text":520,"children":1100},[1101],{"id":634,"depth":119,"text":635},{"id":671,"depth":82,"text":672},{"id":777,"depth":82,"text":778},{"id":1012,"depth":82,"text":1013},{"id":1046,"depth":82,"text":1047},{"id":1059,"depth":82,"text":1060},"2026-05-28","When to use CSS transforms versus CSS animations and transitions — performance, use cases, and practical comparison for front-end developers.","md",{"immutable":211},"\u002Fguides\u002Fcss-transform-vs-css-animation",{"title":5,"description":1108},"guides\u002Fcss-transform-vs-css-animation","PsDJV5ANryFYQirhH76wycvM1qGSdhTQswhZzcHZIDo",1780401333170]