CSS Animation Examples for Beginners

Learn to add motion to your site with pure CSS. These five examples start simple and work in any browser, no JavaScript required.

· 6 min read

A web designer types CSS code on a laptop while an animated website preview plays on the screen.
A web designer types CSS code on a laptop while an animated website preview plays on the screen.. Photo: Bibek ghosh, Pexels (Pexels License)

How do I make a button change color on hover?

You can change a button's color on hover using the :hover pseudo-class combined with the transition property. Start by giving the button a default background color, then define a different background color inside the :hover rule. Adding a transition tells the browser to animate the change smoothly instead of snapping to the new color instantly.

A basic button style sets background-color: #4a90d9 and transition: background-color 0.3s ease. The hover rule switches the background to a darker shade, such as #357abd. The 0.3s value controls the duration, and ease makes the movement start quickly and slow down at the end. You can apply the same technique to text color, border color, or box shadow.

How can I create a simple loading spinner with CSS?

A loading spinner starts with an empty div. Give it equal width and height and a border-radius of 50% to form a circle. You set a transparent border on three sides and a colored border on one side, which makes the circle look like a broken ring.

The animation rotates the div 360 degrees using a @keyframes rule named spin. Apply it to the element with the animation property: a duration of 0.8s, a linear timing function, and the infinite keyword so it never stops.

  • Set the div to display as an inline-block with a fixed width and height, such as 40px.
  • Add border-radius: 50% to turn the square into a perfect circle.
  • Use a transparent border on three sides, for example border: 4px solid transparent.
  • Color only the top border with border-top-color set to a visible shade like #3498db.
  • Define a @keyframes spin block with a to transform: rotate(360deg) rule.
  • Assign animation: spin 0.8s linear infinite to the spinner element.

How do I make text fade in when the page loads?

A fade-in effect makes text appear gradually as the page loads. You define the start and end states with a @keyframes rule, then attach it to the text element using the animation shorthand property.

Create a keyframe named fadeIn that transitions opacity from 0 to 1. Apply it to your heading or paragraph with animation: fadeIn 2s ease-in;. The browser runs the animation once as soon as the element enters the DOM.

To prevent the text from being visible before the animation starts, set opacity: 0; on the element. The animation-fill-mode: forwards; declaration keeps the final opacity value after the animation completes, though for a simple fade to fully opaque this is unnecessary.

What are the key CSS properties every animation uses?

Every CSS animation is controlled by a small set of properties that tell the browser what to do and when. The animation-name property links an element to a @keyframes rule that defines the visual states. You set how long the motion lasts with animation-duration, specified in seconds or milliseconds.

  • animation-name connects the element to the @keyframes block that holds the start and end styles.
  • animation-duration defines the length of one cycle. A value of 2s means the animation runs for two seconds.
  • animation-timing-function controls the acceleration curve. Common values are ease, linear, and ease-in-out.
  • animation-delay sets a pause before the animation begins. A negative value starts the animation partway through its first cycle.
  • animation-iteration-count sets how many times the animation repeats. Use a plain number or the keyword infinite.

The @keyframes rule sits outside the selector and maps percentage points like 0% and 100% to CSS declarations. Together these properties let you build anything from a subtle hover effect to a persistent loading spinner.

How do I make an element slide in from the side?

Sliding an element in from off-screen relies on a @keyframes rule that moves it from a hidden starting position to its final spot. You define two steps: one with transform: translateX(-100%) to place it fully to the left, and another with transform: translateX(0) where it sits naturally in the layout.

Apply the animation to the element with a name, duration, and easing function, such as animation: slideIn 0.6s ease-out. The parent container needs overflow: hidden so the element stays invisible until the animation begins rather than showing a horizontal scrollbar or a flash of content.

You can adjust the direction by changing the axis. Use translateY(-100%) for a drop from the top, or a positive value like translateX(100%) to slide in from the right edge.

Can I animate an element without using @keyframes?

The transition property animates between two states without a named keyframe. It watches for a change in a CSS value and smoothly moves from the old value to the new one over a set duration. A common trigger is the :hover pseudo-class.

Write the base styles on the element itself, then declare the changed values on :hover. The transition property goes on the base element so the browser knows what to animate when the hover state activates. The shorthand includes:

  • transition-property: the CSS property to animate, such as background-color or transform
  • transition-duration: how long the change takes, usually in seconds (0.3s is a good starting point)
  • transition-timing-function: the acceleration curve; ease and ease-in-out feel natural for interface elements
  • transition-delay: an optional pause before the animation starts

A button that shifts background color on hover needs only two rulesets. The base button holds the original color and the transition declaration. The hover ruleset holds the new color. The browser calculates every intermediate shade between the two values over the duration you set.

How do I make an animation repeat infinitely?

Set the animation-iteration-count property to infinite on the element you are animating. This tells the browser to restart the animation as soon as it finishes, creating a continuous loop. The property works with any animation defined in a @keyframes rule.

Your keyframe definition needs to end at the same visual state where it begins for a seamless loop. If the first and last frames do not match, the animation will jump back to the start on each cycle. For a smooth pulsing effect, set identical property values at 0% and 100% and place the change in the middle of the sequence.

You can combine infinite with other animation properties in the shorthand declaration. The order inside animation does not matter as long as each value is recognizable to the parser. A rotating loader uses this approach with a linear timing function to keep the motion constant.

  • Use animation-iteration-count: infinite; to loop the animation without stopping.
  • Match the starting and ending frames to avoid a visible reset between cycles.
  • Set animation-direction: alternate; to reverse the animation on every other iteration instead of restarting it.
  • Combine infinite with animation-timing-function: linear; for constant-speed motion like rotation.
  • Apply the infinite loop directly in the shorthand: animation: spin 2s linear infinite;.

Frequently asked questions

Do CSS animations work in all browsers?

Yes. CSS animations and transitions are supported in every modern browser, including Chrome, Firefox, Safari, and Edge. For older browsers, the effect simply does not play, and the element remains visible in its default state.

Can I trigger a CSS animation with JavaScript?

You can. Add or remove a class with JavaScript, and define the animation in that class. This approach keeps the motion logic in CSS and uses JavaScript only to respond to user actions like clicks or scroll position.

How many animations should I put on one page?

Stick to one or two small animations that guide attention, such as a hover state on buttons and a single entrance effect. Too much motion distracts visitors and can make a page feel slow on less powerful devices.

Do CSS animations affect page speed?

When used sparingly, the impact is negligible. Animating transform and opacity properties is hardware-accelerated and keeps the page smooth. Avoid animating properties like width or top, which trigger layout recalculations and can cause jank.

Read also