A .marquee scrolls a row of logos, images or text
without end.
Write the items twice, as two identical
<ul class="marquee-content"> groups. The second
group is a copy that fills the gap as the first scrolls out. Mark
it aria-hidden="true" and give each link or button in
it tabindex="-1". Each group is at least as wide as the
strip and spreads short content out, so one copy is enough.
Add fade to fade the items out at both edges. Hovering
over the strip or focusing a link inside stops it. The marquee is CSS only.
- Launchpad
- Voltage
- Greenleaf
- Facet
- Tidewater
- Summit
<div class="marquee fade">
<ul class="marquee-content" aria-label="Customers">
<li><img src="launchpad.svg" alt="Launchpad"></li>
<li><img src="voltage.svg" alt="Voltage"></li>
<li><a href="/customers/greenleaf"><img src="greenleaf.svg" alt="Greenleaf"></a></li>
</ul>
<ul class="marquee-content" aria-hidden="true">
<li><img src="launchpad.svg" alt="Launchpad"></li>
<li><img src="voltage.svg" alt="Voltage"></li>
<li><a href="/customers/greenleaf" tabindex="-1"><img src="greenleaf.svg" alt="Greenleaf"></a></li>
</ul>
</div>
Direction and speed
A strip scrolls toward the start of the line: left, or right on a
right-to-left page. Add reverse to scroll the other
way. --md-comp-marquee-duration is the time one group
takes to pass, so a longer group needs a longer duration to keep
the same speed.
- Free shipping on orders over $50
- New arrivals every Friday
- Returns within 30 days
<div class="marquee reverse" style="--md-comp-marquee-duration: 40s">
<ul class="marquee-content">
<li>Free shipping on orders over $50</li>
<li>New arrivals every Friday</li>
<li>Returns within 30 days</li>
</ul>
<ul class="marquee-content" aria-hidden="true">
<li>Free shipping on orders over $50</li>
<li>New arrivals every Friday</li>
<li>Returns within 30 days</li>
</ul>
</div>
Vertical
Add vertical to scroll up, or down with reverse.
The strip is 320px tall. Set height to change it.
<div class="marquee vertical fade" style="height: 360px">
<ul class="marquee-content">
<li><img src="lake.jpg" alt=""></li>
<li><img src="forest.jpg" alt=""></li>
</ul>
<ul class="marquee-content" aria-hidden="true">
<li><img src="lake.jpg" alt=""></li>
<li><img src="forest.jpg" alt=""></li>
</ul>
</div>
Pause button
Add paused to stop the strip. When it runs next to
other content for more than five seconds, give people a button that
stops it, and keep the button outside the strip so it stays put.
- Launchpad
- Voltage
- Greenleaf
- Facet
- Tidewater
- Summit
<button type="button" class="icon-button" id="marquee-pause"
aria-label="Pause scrolling" aria-pressed="false">
<span class="material-symbols-outlined" aria-hidden="true">pause</span>
</button>
<div class="marquee" id="paused-marquee">…</div>
<script>
const button = document.getElementById('marquee-pause');
const marquee = document.getElementById('paused-marquee');
button.addEventListener('click', () => {
const paused = button.getAttribute('aria-pressed') !== 'true';
button.setAttribute('aria-pressed', String(paused));
marquee.classList.toggle('paused', paused);
});
</script>
Accessibility
-
Screen readers read the first group once and skip the
aria-hiddencopy. Name the first list when its purpose is not clear from the page, as inaria-label="Customers". -
Give each logo image the brand's name as its
alttext. Decorative photos takealt="". -
Hover and keyboard focus inside the strip pause it. A link in
the copy has
tabindex="-1", so Tab reaches each link once, and clicking the copy still follows it. - With reduced motion, the strip stops and hides the copy. When its items overflow, people scroll the strip by hand.
- Do not put information people need only in a marquee. Each item is on screen for a few seconds at a time.
Tokens
Set these on the .marquee.
| Token | Default |
|---|---|
--md-comp-marquee-duration |
20s; the time one group takes to pass |
--md-comp-marquee-gap |
32px; space between items and between the two groups |
--md-comp-marquee-fade-size |
48px; length of each edge fade with fade |