AskHandle

AskHandle Blog

Create a Smooth CSS Marquee With Keyframes

June 24, 2026Lillian Kim3 min read
  • Marquee
  • CSS
  • Websites

Create a Smooth CSS Marquee With Keyframes

A marquee effect is a simple moving strip of text or content that slides across part of a web page, often used for announcements, featured messages, partner logos, product highlights, or decorative motion. Older websites used the HTML <marquee> tag, but that tag is outdated and should not be used in modern projects. A better approach is to create the same effect with CSS animations and @keyframes, giving you more control over speed, direction, spacing, and style.

What Is a CSS Marquee?

A CSS marquee is a scrolling content effect created with animation rules. Instead of relying on old HTML behavior, you place content inside a container, hide the overflow, and animate the inner content from one side to the other.

This method works well because it keeps your HTML clean and gives your CSS full control. You can use it for plain text, buttons, badges, icons, product names, or repeated logo items.

A basic marquee has three main parts:

  1. A wrapper that acts as the visible window
  2. Inner content that moves
  3. A keyframe animation that changes the position over time

Basic HTML Structure

Start with a simple container. The outer element hides anything that moves outside its boundaries. The inner element holds the text that will slide across the screen.

html
1<div class="marquee">
2  <div class="marquee-content">
3    Simple CSS marquee animation for your website
4  </div>
5</div>

This structure is small, readable, and easy to reuse. The class named .marquee is the outer frame. The class named .marquee-content is the moving part.

Basic CSS for the Marquee

Now add the styling. The wrapper needs overflow: hidden so the moving content does not show outside the container. The content needs white-space: nowrap so the text stays on one line.

css
1.marquee {
2  width: 100%;
3  overflow: hidden;
4  background: #111827;
5  color: #ffffff;
6  padding: 14px 0;
7}
8
9.marquee-content {
10  display: inline-block;
11  white-space: nowrap;
12  padding-left: 100%;
13  animation: marquee 12s linear infinite;
14}
15
16@keyframes marquee {
17  from {
18    transform: translateX(0);
19  }
20
21  to {
22    transform: translateX(-100%);
23  }
24}

This creates a simple right-to-left marquee. The padding-left: 100% pushes the text outside the right side of the visible area at the start. The animation then moves the content left until it exits the view.

How the Keyframe Works

The @keyframes rule defines the motion. In this example, the animation starts at translateX(0) and ends at translateX(-100%).

css
1@keyframes marquee {
2  from {
3    transform: translateX(0);
4  }
5
6  to {
7    transform: translateX(-100%);
8  }
9}

The transform property is usually a good choice for animation because it performs smoothly in most browsers. It moves the element visually without changing the layout flow around it.

The animation line controls the timing:

css
1animation: marquee 12s linear infinite;

Here is what each part means:

  • marquee is the keyframe name
  • 12s is the duration
  • linear keeps the speed steady
  • infinite makes the animation repeat forever

If you want slower movement, increase the duration. If you want faster movement, reduce it.

Creating a Seamless Repeating Marquee

The simple version works, but it may leave a gap before repeating. For a smoother loop, repeat the content inside the moving element.

html
1<div class="marquee">
2  <div class="marquee-track">
3    <span>New products available now</span>
4    <span>Free shipping on selected items</span>
5    <span>Summer sale starts this week</span>
6    <span>New products available now</span>
7    <span>Free shipping on selected items</span>
8    <span>Summer sale starts this week</span>
9  </div>
10</div>

Then style the track as a flexible row.

css
1.marquee {
2  width: 100%;
3  overflow: hidden;
4  background: #0f172a;
5  color: #ffffff;
6  padding: 16px 0;
7}
8
9.marquee-track {
10  display: flex;
11  width: max-content;
12  gap: 40px;
13  animation: scroll-left 18s linear infinite;
14}
15
16.marquee-track span {
17  font-size: 18px;
18  font-weight: 600;
19  white-space: nowrap;
20}
21
22@keyframes scroll-left {
23  from {
24    transform: translateX(0);
25  }
26
27  to {
28    transform: translateX(-50%);
29  }
30}

This version works well because the content is duplicated. Moving it left by -50% creates the feeling of one continuous strip. Once the first half has moved out, the second half is in the same position, so the loop looks clean.

Making the Marquee Move in the Opposite Direction

Changing direction is easy. Use a different keyframe or reverse the animation.

css
1.marquee-track {
2  animation: scroll-right 18s linear infinite;
3}
4
5@keyframes scroll-right {
6  from {
7    transform: translateX(-50%);
8  }
9
10  to {
11    transform: translateX(0);
12  }
13}

This makes the content move from left to right. You can also use animation-direction: reverse;, but a separate keyframe can be clearer when reading your stylesheet later.

Pausing the Marquee on Hover

A marquee can be distracting if users are trying to read it. A helpful improvement is to pause the animation when someone hovers over it.

css
1.marquee:hover .marquee-track {
2  animation-play-state: paused;
3}

This small rule gives visitors more control. It is especially useful for announcement bars, news tickers, or product lists.

Adding Better Spacing and Style

A marquee does not need to be plain text. You can style each item like a small badge.

css
1.marquee-track span {
2  display: inline-flex;
3  align-items: center;
4  padding: 8px 16px;
5  border-radius: 999px;
6  background: #1e293b;
7  color: #e5e7eb;
8  font-size: 15px;
9  font-weight: 500;
10  white-space: nowrap;
11}

This creates a cleaner visual effect. The rounded badges make each message feel separate while still moving as one track.

You can adjust the colors to match your website. Dark backgrounds with light text are common, but light backgrounds can work just as well.

Making It Responsive

A marquee often spans the full width of the page, so it should work nicely on different screen sizes. Use relative units and avoid fixed widths on the moving track unless you have a clear reason.

css
1.marquee {
2  max-width: 100%;
3}
4
5.marquee-track {
6  gap: clamp(24px, 5vw, 60px);
7}
8
9.marquee-track span {
10  font-size: clamp(14px, 2vw, 18px);
11}

The clamp() function lets values grow and shrink within a safe range. This keeps the spacing and text size balanced across phones, tablets, and larger screens.

Accessibility Tips for Marquee Effects

Motion should be used with care. Some visitors may prefer reduced motion because constant movement can be uncomfortable. You can respect that preference with a media query.

css
1@media (prefers-reduced-motion: reduce) {
2  .marquee-track,
3  .marquee-content {
4    animation: none;
5  }
6}

This stops the marquee for users who have reduced motion turned on in their system settings. It is a simple addition that makes the effect more user-friendly.

Also, avoid placing critical information only inside a moving marquee. If the message is important, make sure it is also available in regular page content.

Complete Example

Here is a complete reusable version you can paste into a project.

html
1<div class="marquee">
2  <div class="marquee-track">
3    <span>Simple CSS animation</span>
4    <span>Clean marquee effect</span>
5    <span>No outdated HTML tag</span>
6    <span>Works with text or badges</span>
7    <span>Simple CSS animation</span>
8    <span>Clean marquee effect</span>
9    <span>No outdated HTML tag</span>
10    <span>Works with text or badges</span>
11  </div>
12</div>
css
1.marquee {
2  width: 100%;
3  overflow: hidden;
4  background: #111827;
5  padding: 16px 0;
6}
7
8.marquee-track {
9  display: flex;
10  width: max-content;
11  gap: 40px;
12  animation: marquee-scroll 20s linear infinite;
13}
14
15.marquee-track span {
16  display: inline-flex;
17  align-items: center;
18  padding: 8px 16px;
19  border-radius: 999px;
20  background: #374151;
21  color: #ffffff;
22  font-size: 16px;
23  font-weight: 600;
24  white-space: nowrap;
25}
26
27.marquee:hover .marquee-track {
28  animation-play-state: paused;
29}
30
31@keyframes marquee-scroll {
32  from {
33    transform: translateX(0);
34  }
35
36  to {
37    transform: translateX(-50%);
38  }
39}
40
41@media (prefers-reduced-motion: reduce) {
42  .marquee-track {
43    animation: none;
44  }
45}

A simple marquee keyframe is one of the easiest CSS animations to add to a website. With a wrapper, a moving track, and a short @keyframes rule, you can create a smooth scrolling message without using outdated HTML. Keep the movement steady, duplicate the content for a cleaner loop, add hover pause for readability, and include a reduced-motion rule for visitors who prefer less animation. The result is a lightweight, flexible marquee that looks polished and remains easy to maintain.