The trick

Put two copies of the content side by side in a track. Animate the track from no offset to minus one group's width. At the end of the animation the second copy is exactly where the first one began, so when the animation starts over nothing visibly changes. A transform animation does this on the compositor, which is why it is smooth.

Break one: content shorter than the strip

If one group is narrower than the strip, the far end of the strip is empty for part of each loop. The fix is to repeat the items until one group is at least as wide as the strip. Ribbonfly Marquee does it in the page script and gives up at sixty copies.

Break two: late images

The distance to move is the width of a group, and an image with no size attributes has no width until it has loaded. The strip is measured too short and a gap opens. The fix is to measure again when an image has loaded, and, because fonts change widths too, when the fonts are ready.

Break three: resizing

Resizing changes the width of items set in percentages, so the distance changes with it. Restarting the animation makes the strip leap. The fix is to note where the strip was within the loop, rebuild the distance and put it back there.

Work out what your strip needs

Speed, loop time and copies

Pixels per second, seconds per loop, and how many copies it takes to fill the strip. Nothing you type leaves this page.

Why a plugin and not a snippet?

A snippet can do the first part in ten lines of CSS. The three fixes are what turn a demonstration into something you can put on a client's site, and they are what the script is for. It is 11 KB of unminified code and uses nothing else.

For the speed, see the speed guide.