How to Move an Element in a Circular Path with CSS

Moving an element along a circular path is an interesting problem to solve using CSS. It can be achieved by animating the CSS transform property.

Demo #1 - Moving Along a Circe by 120 Degrees from the Starting Point

Demo #2 - Moving Along a Circle by 120 Degrees Each Time

This is similar to Demo #1, except that the sum of rotation angles is saved. On each click, the element moves from X degrees to X+120 degrees.

How Circular Motion is Achieved

The element which is to be rotated must have a parent element. To rotate the child by 60 degrees, first rotate the parent by 60 degrees. At the same time, rotate the child by minus(-) 60 degrees. The child must be rotated by an equal opposite angle so that it does look inverted when the animation is completed.

You can animate using CSS transition, CSS animation or the new Web Animations API.

Step 1 : CSS of the Parent Element

The child is going to have absolute position, so the parent must have relative position (or absolute position). Give equal height and width, and make its border-radius as 50% so that it becomes circular in shape. Add the initial value of transform property. Also add transition property for animating the transform property.

#parent {
	position: relative;
	width: 300px;
	height: 300px;
	border: 1px solid rgba(0,0,0,0.1);
	border-radius: 50%;
	transform: rotate(0deg);
	transition: transform 0.7s linear;
}

Step 2 : CSS of the Child Element

The child is absolutely positioned. Place the child at an appropriate starting position, in this case at the top center of the parent.

Add transform and transition properties.

#child {
	position: absolute;
	width: 80px;
	height: 80px;
	transform: rotate(0deg);
	transition: transform 0.7s linear;
	top: -40px;   /* -child size/2 */
	left: 110px;   /* parent size/2 - child size/2 */
}

#child img {
	max-width: 100%;
	border-radius: 50%;
}

In this example case, the child contains an image.

Step 3 : Showing the Animation

Assume that you have a button, which on clicked is supposed to move the child by 120 degrees. In the event handler, rotate the parent by 120 degrees and rotate the child by -120 degrees.

$("#button").on('click', function() {
	$("#parent").css({ transform: 'rotate(120deg)' });
	$("#child").css({ transform: 'rotate(-120deg)' });
});

This is how the circular motion in Demo #1 is achieved.

In Demo #2, the total angle moved is saved in a variable. Upon click, rotation happens from the old angle to the newly incremented angle.

var _CURRENT_ANGLE = 0;

$("#button").on('click', function() {
	_CURRENT_ANGLE += 120;

	$("#parent-2").css({ transform: 'rotate(' + _CURRENT_ANGLE + 'deg)' });
	$("#child-2").css({ transform: 'rotate(-' + _CURRENT_ANGLE + 'deg)' });
});

Using Web Animations API

The animation can also be done with the new Web Animations API, except that the syntax is a little different and the performance of the animation will be better.

Of course you don't need to add transition property here to perform the animation. In this case animate method will perform the animation.

Using Web Animations API, the code would be like :

$("#button").on('click', function() {
	$("#parent").get(0).animate([
			{ transform: 'rotate(0deg)' },
			{ transform: 'rotate(120deg)' },
		], 
		{
			duration: 700,
			easing: 'linear',
			iterations: 1,
			fill: 'forwards'
		}
	);

	$("#child").get(0).animate([
			{ transform: 'rotate(0deg)' },
			{ transform: 'rotate(-120deg)' },
		], 
		{
			duration: 700,
			easing: 'linear',
			iterations: 1,
			fill: 'forwards'
		}
	);
});

Note that Web Animations API is available only in the latest versions of Chrome & Opera.

How to Move an Element in a Circular Path with CSS Offset-Path (Motion Path)