
Ever needed to add one of those diagonal, infinitely scrolling image ribbons to a section of a page?
Maybe for a client logo scroller, a decorative background, or just something visually distinct.
Doing it purely with CSS can get a bit fiddly with transforms, overflow, and getting the animation just right.
I recently came across ribbon-tile, a Vanilla JS web component that packages this exact functionality nicely.
ribbon-tile lets you drop a custom HTML element (<ribbon-tile>) onto your page, configure it with a few attributes, and get a responsive, animated ribbon.
It handles the CSS, the animation, the rotation calculation, and the image tiling internally using the Shadow DOM.
See it in action:
Features:
- Custom Element implementation – no framework dependencies
- Built-in animation with customizable duration
- Supports gradient overlays for smooth edge fading
- Works with any image as the tile source
- Automatic rotation calculation based on container dimensions
- Shadow DOM encapsulation for style isolation
- Customizable shadow effects
How to use it:
1. Download and include the RibbonTile.js script on your webpage.
<script src="/path/to/RibbonTile.js" defer></script>
2. Once imported, you can use the <ribbon-tile> Custom Element anywhere in your HTML:
| Attribute | Description | Required | Default |
|---|---|---|---|
ribbon-width | Width of the ribbon (px, rem, etc.) | Yes | – |
ribbon-space | Total vertical space the component uses | Yes | – |
image-url | URL to your tile image (must be 1:1 ratio) | Yes | – |
gradient-color | Color for edge fading (any CSS color format) | No | rgba(1, 1, 1, 0) |
shadow-color | Color for the ribbon shadow | No | rgba(1, 1, 1, 0) |
animation-duration | Duration of the scroll animation in seconds | No | 180s |
<ribbon-tile ribbon-width="6rem" ribbon-space="12rem" image-url="/path/to/1.jpg" gradient-color="rgba(1, 1, 1, 0)" shadow-colro="rgba(1, 1, 1, 0)" animation-duration="180s" / >
FAQs
Q: Can I change the animation direction or easing?
A: Not via attributes. The animation is hardcoded as linear infinite. You’d need to modify the component’s internal CSS (@keyframes pan and the animation property) to change direction (e.g., reverse) or easing.
Q: What if my ribbon-space isn’t much larger than ribbon-width?
A: The rotation angle will be very shallow. If ribbon-space equals ribbon-width, the angle would be 0 degrees (no rotation). You need sufficient vertical space difference for a noticeable diagonal effect.
Q: Can I use multiple <ribbon-tile> elements on one page?
A: Yes. Each instance is self-contained thanks to the Shadow DOM. Just be mindful of the potential performance impact of many simultaneous CSS animations if you go overboard.






