Title

CSS Marquee

description

Simpler than a JS Marquee. Despite a duration based glitch often this solution will serve the goal perfectly.

Published 2022-08-03

Modified 2022-08-19

content

				
					.marquee-css {
  position: relative;
  height: 120px;
  overflow: hidden;
}
.marquee-track-css {
  height: 120px;
  position: absolute;
  white-space: nowrap;
  display:inline-flex;
  align-items: center;
  animation: marquee 10s linear infinite;
  background-color:lavender;
  padding:0px;
  margin: 0;
  font-size: 50px;
  line-height:50px;
  text-transform: uppercase;
}

@keyframes marquee {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}
				
			
Lorem ipsum dolor sit amet · consectetur adipiscing elit · quis nostrud exercitation ullamco · sunt in culpa qui officia deserunt ·

After the ‘animation-duration’ time is over, here 10 seconds, the animation will snap back to the starting point

				
					<!-- Make sure content is always at least double the width of the containing parent element or viewport if fullscreen, duplicate content in HTML or size with CSS as needed -->
<div class="marquee-css">
  <div class="marquee-track-css">Lorem ipsum dolor sit amet  · consectetur adipiscing elit  ·  quis nostrud exercitation ullamco  ·  sunt in culpa qui officia deserunt  ·  
  </div>
</div>
				
			

This is fixed by duplicating the content MANY TIMES, and setting the ‘animation-duration’ to a high number so the glitch happens after a long time, and the page visitor is very unlikely to notice it, like here it runs once every 210 seconds:

Lorem ipsum dolor sit amet · consectetur adipiscing elit · quis nostrud exercitation ullamco · sunt in culpa qui officia deserunt · Lorem ipsum dolor sit amet · consectetur adipiscing elit · quis nostrud exercitation ullamco · sunt in culpa qui officia deserunt · Lorem ipsum dolor sit amet · consectetur adipiscing elit · quis nostrud exercitation ullamco · sunt in culpa qui officia deserunt · Lorem ipsum dolor sit amet · consectetur adipiscing elit · quis nostrud exercitation ullamco · sunt in culpa qui officia deserunt · Lorem ipsum dolor sit amet · consectetur adipiscing elit · quis nostrud exercitation ullamco · sunt in culpa qui officia deserunt · Lorem ipsum dolor sit amet · consectetur adipiscing elit · quis nostrud exercitation ullamco · sunt in culpa qui officia deserunt ·
				
					<!-- Make sure content is always at least double the width of the containing parent element or viewport if fullscreen, duplicate content in HTML or size with CSS as needed -->
<div class="marquee-css">
  <div class="marquee-track-css">Lorem ipsum dolor sit amet  · consectetur adipiscing elit  ·  quis nostrud exercitation ullamco  ·  sunt in culpa qui officia deserunt  ·  Lorem ipsum dolor sit amet  · consectetur adipiscing elit  ·  quis nostrud exercitation ullamco  ·  sunt in culpa qui officia deserunt  ·  Lorem ipsum dolor sit amet  · consectetur adipiscing elit  ·  quis nostrud exercitation ullamco  ·  sunt in culpa qui officia deserunt  ·  Lorem ipsum dolor sit amet  · consectetur adipiscing elit  ·  quis nostrud exercitation ullamco  ·  sunt in culpa qui officia deserunt  ·  Lorem ipsum dolor sit amet  · consectetur adipiscing elit  ·  quis nostrud exercitation ullamco  ·  sunt in culpa qui officia deserunt  ·  Lorem ipsum dolor sit amet  · consectetur adipiscing elit  ·  quis nostrud exercitation ullamco  ·  sunt in culpa qui officia deserunt  ·  </div>
</div>
				
			

Simplified, with Elementor HTML widget

Lorem ipsum dolor sit amet · consectetur adipiscing elit · quis nostrud exercitation ullamco · sunt in culpa qui officia deserunt · Lorem ipsum dolor sit amet · consectetur adipiscing elit · quis nostrud exercitation ullamco · sunt in culpa qui officia deserunt · Lorem ipsum dolor sit amet · consectetur adipiscing elit · quis nostrud exercitation ullamco · sunt in culpa qui officia deserunt · Lorem ipsum dolor sit amet · consectetur adipiscing elit · quis nostrud exercitation ullamco · sunt in culpa qui officia deserunt · Lorem ipsum dolor sit amet · consectetur adipiscing elit · quis nostrud exercitation ullamco · sunt in culpa qui officia deserunt · Lorem ipsum dolor sit amet · consectetur adipiscing elit · quis nostrud exercitation ullamco · sunt in culpa qui officia deserunt ·
				
					<div class="marquee-track-css">Lorem ipsum dolor sit amet  · consectetur adipiscing elit  ·  quis nostrud exercitation ullamco  ·  sunt in culpa qui officia deserunt  ·  Lorem ipsum dolor sit amet  · consectetur adipiscing elit  ·  quis nostrud exercitation ullamco  ·  sunt in culpa qui officia deserunt  ·  Lorem ipsum dolor sit amet  · consectetur adipiscing elit  ·  quis nostrud exercitation ullamco  ·  sunt in culpa qui officia deserunt  ·  Lorem ipsum dolor sit amet  · consectetur adipiscing elit  ·  quis nostrud exercitation ullamco  ·  sunt in culpa qui officia deserunt  ·  Lorem ipsum dolor sit amet  · consectetur adipiscing elit  ·  quis nostrud exercitation ullamco  ·  sunt in culpa qui officia deserunt  ·  Lorem ipsum dolor sit amet  · consectetur adipiscing elit  ·  quis nostrud exercitation ullamco  ·  sunt in culpa qui officia deserunt  ·  </div>
				
			
				
					selector {
  overflow: hidden;
}
selector .marquee-track-css {
  height: 120px;
  white-space: nowrap;
  display:inline-flex;
  align-items: center;
  animation: marqueeX 90s linear infinite;
  background-color:lavender;
  font-size: 50px;
  line-height:50px;
  text-transform: uppercase;
}

@keyframes marqueeX {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}
				
			

CSS Vertical Marquee, just CSS with fixed height

				
					<div class="marquee-css">
        <div class="marquee-track-css">
            <img decoding="async" src="/wp-content/uploads/Note.png"><img decoding="async" src="/wp-content/uploads/Voltage.png"><img decoding="async" src="/wp-content/uploads/NoShit.png"><img decoding="async" src="/wp-content/uploads/Cat-Left.png"><img decoding="async" src="/wp-content/uploads/Open.png"><img decoding="async" src="/wp-content/uploads/NoSnake.png"><img decoding="async" src="/wp-content/uploads/Wham.png">
            
<!-- Make sure content is always at least double the height of the containing parent element or viewport if fullscreen, duplicate content in HTML or size with CSS as needed -->

            <img decoding="async" src="/wp-content/uploads/Note.png"><img decoding="async" src="/wp-content/uploads/Voltage.png"><img decoding="async" src="/wp-content/uploads/NoShit.png"><img decoding="async" src="/wp-content/uploads/Cat-Left.png"><img decoding="async" src="/wp-content/uploads/Open.png"><img decoding="async" src="/wp-content/uploads/NoSnake.png"><img decoding="async" src="/wp-content/uploads/Wham.png">
        </div>
    </div>
				
			
				
					.marquee-css {
  position: relative;
  width:300px;
  height:1800px;
  overflow:hidden;
  background-color:green;
}

.marquee-track-css {
  position: absolute;
  width:100%;
  padding:10px;
  will-change: transform;
  animation: marqueeY 180s linear infinite;
}

.marquee-css img {
  margin-right:0;
  margin-left: auto;
  margin-bottom: 24px;
  display: block;}

@keyframes marqueeY {
  from { transform: translateY(0); }
  to { transform: translateY(-50%); }
}

.marquee-css img:nth-of-type(odd){margin-right: auto;margin-left:0;}

				
			

CSS Vertical Marquee, using the Elementor column and section

				
					/* Column containing the HTML widget with the marquee */
selector {overflow: hidden;}

				
			

The left column will take on the height of this column. There is no height set to the HTML widget, so just the overflow makes the content visible. Set the HTML widget position to absolute.

HTML widget content

				
					<img decoding="async" src="/wp-content/uploads/Note.png"><img decoding="async" src="/wp-content/uploads/Voltage.png"><img decoding="async" src="/wp-content/uploads/NoShit.png"><img decoding="async" src="/wp-content/uploads/Cat-Left.png"><img decoding="async" src="/wp-content/uploads/Open.png"><img decoding="async" src="/wp-content/uploads/NoSnake.png"><img decoding="async" src="/wp-content/uploads/Wham.png">
            
<!-- Make sure content is always at least double the height of the containing parent element or viewport if fullscreen, duplicate content in HTML or size with CSS as needed -->

<img decoding="async" src="/wp-content/uploads/Note.png"><img decoding="async" src="/wp-content/uploads/Voltage.png"><img decoding="async" src="/wp-content/uploads/NoShit.png"><img decoding="async" src="/wp-content/uploads/Cat-Left.png"><img decoding="async" src="/wp-content/uploads/Open.png"><img decoding="async" src="/wp-content/uploads/NoSnake.png"><img decoding="async" src="/wp-content/uploads/Wham.png">
				
			

HTML widget css

				
					selector {
  animation: marqueeY 120s linear infinite;
  padding:10px;
}

selector img {
  margin-right:0;
  margin-left: auto;
  margin-bottom: 24px;
  display: block;}

@keyframes marqueeY {
  from { transform: translateY(0); }
  to { transform: translateY(-50%); }
}

selector img:nth-of-type(odd){margin-right: auto;margin-left:0;}
				
			

Sources & References