Animate Transform Opacity Only
CSS transitions and animations MUST target only `transform` and `opacity`. Animating layout properties (width, height, padding, margin, top, left, border-width) triggers browser layout recalculation on every frame, causi…
$ prime install @anthropic-impeccable/rule-animate-transform-opacity-only Projection
Always in _index.xml · the agent never has to ask for this.
AnimateTransformOpacityOnly [rule] v1.0.0
CSS transitions and animations MUST target only
transformandopacity. Animating layout properties (width, height, padding, margin, top, left, border-width) triggers browser layout recalculation on every frame, causing forced reflows and dropped frames. For height animations (accordions, disclosures), usegrid-template-rows: 0fr → 1frinstead ofheight: 0 → auto.
Loaded when retrieval picks the atom as adjacent / supporting.
AnimateTransformOpacityOnly [rule] v1.0.0
CSS transitions and animations MUST target only
transformandopacity. Animating layout properties (width, height, padding, margin, top, left, border-width) triggers browser layout recalculation on every frame, causing forced reflows and dropped frames. For height animations (accordions, disclosures), usegrid-template-rows: 0fr → 1frinstead ofheight: 0 → auto.
Label
Animate Only transform and opacity — Never Layout Properties
Code
/* CORRECT: GPU-composited, no layout recalculation */
.card {
transition: transform 200ms cubic-bezier(0.25, 1, 0.5, 1),
opacity 200ms ease-out;
}
.card:hover {
transform: translateY(-4px);
opacity: 0.92;
}
/* CORRECT: accordion height via grid-template-rows */
.accordion-content {
display: grid;
grid-template-rows: 0fr;
transition: grid-template-rows 300ms cubic-bezier(0.25, 1, 0.5, 1);
}
.accordion-content[aria-hidden="false"] {
grid-template-rows: 1fr;
}
.accordion-inner { overflow: hidden; }
/* WRONG: triggers layout on every frame */
.bad-accordion { transition: height 300ms ease; height: 0; overflow: hidden; }
.bad-card:hover { margin-top: -4px; }
Severity
high
Loaded when retrieval picks the atom as a focal / direct hit.
AnimateTransformOpacityOnly [rule] v1.0.0
CSS transitions and animations MUST target only
transformandopacity. Animating layout properties (width, height, padding, margin, top, left, border-width) triggers browser layout recalculation on every frame, causing forced reflows and dropped frames. For height animations (accordions, disclosures), usegrid-template-rows: 0fr → 1frinstead ofheight: 0 → auto.
Label
Animate Only transform and opacity — Never Layout Properties
Code
/* CORRECT: GPU-composited, no layout recalculation */
.card {
transition: transform 200ms cubic-bezier(0.25, 1, 0.5, 1),
opacity 200ms ease-out;
}
.card:hover {
transform: translateY(-4px);
opacity: 0.92;
}
/* CORRECT: accordion height via grid-template-rows */
.accordion-content {
display: grid;
grid-template-rows: 0fr;
transition: grid-template-rows 300ms cubic-bezier(0.25, 1, 0.5, 1);
}
.accordion-content[aria-hidden="false"] {
grid-template-rows: 1fr;
}
.accordion-inner { overflow: hidden; }
/* WRONG: triggers layout on every frame */
.bad-accordion { transition: height 300ms ease; height: 0; overflow: hidden; }
.bad-card:hover { margin-top: -4px; }
Severity
high
Sources
Rationale
GPU-composited properties (transform, opacity) are handled by the compositor thread — they do not require style recalculation or layout. Animating any box-model property (width, height, padding, margin) forces a full layout pass (recalculate style → layout → paint → composite) on every animation frame. At 60fps this is 16ms per frame; a full layout pass can consume 4-8ms, leaving no headroom. The grid-template-rows trick is the correct solution for height: 0 → auto because the grid layout engine handles fractional row expansion without exposing a layout-blocking animated height property.
Label
Animate Only transform and opacity — Never Layout Properties
Code
/* CORRECT: GPU-composited, no layout recalculation */
.card {
transition: transform 200ms cubic-bezier(0.25, 1, 0.5, 1),
opacity 200ms ease-out;
}
.card:hover {
transform: translateY(-4px);
opacity: 0.92;
}
/* CORRECT: accordion height via grid-template-rows */
.accordion-content {
display: grid;
grid-template-rows: 0fr;
transition: grid-template-rows 300ms cubic-bezier(0.25, 1, 0.5, 1);
}
.accordion-content[aria-hidden="false"] {
grid-template-rows: 1fr;
}
.accordion-inner { overflow: hidden; }
/* WRONG: triggers layout on every frame */
.bad-accordion { transition: height 300ms ease; height: 0; overflow: hidden; }
.bad-card:hover { margin-top: -4px; }
Severity
high
Source
prime-system/examples/frontend-design/primes/compiled/@anthropic-impeccable/rule-animate-transform-opacity-only/atom.yaml