CSS Ribbon Generator
Design a pure-CSS folded-corner ribbon badge with a live preview and copyable code.
Card content goes here
.ribbon-wrap {
position: relative;
overflow: hidden;
}
.ribbon {
position: absolute;
top: 0;
right: 0;
width: 180px;
padding: 6px 0;
background: #e53e3e;
color: #ffffff;
font-size: 13px;
font-weight: 700;
letter-spacing: 0.05em;
text-align: center;
text-transform: uppercase;
transform: translateX(25%) rotate(45deg);
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.25);
}
.ribbon::before,
.ribbon::after {
content: "";
position: absolute;
bottom: -8px;
border: 4px solid #942828;
z-index: -1;
}
.ribbon::before { left: 0; border-right-color: transparent; }
.ribbon::after { right: 0; border-left-color: transparent; }<div class="ribbon-wrap"> <div class="ribbon">SALE</div> <!-- your card content --> </div>
How the CSS folded-corner ribbon works
A CSS ribbon badge is built from a wrapping element with position: relative; overflow: hidden; and an absolutely positioned bar rotated 45 degrees into the corner with transform: rotate(). The parent's clipped overflow trims the bar into a clean diagonal strip. The optional folded-corner effect is two small triangles drawn with the ::before and ::after pseudo-elements, each using transparent borders on opposite sides to form a triangular wedge in a darker shade of the ribbon color, mimicking a folded strip of paper tucked behind the badge. Pick a corner, tune the size, colors, and font, then copy the generated CSS and HTML directly into your project — everything is computed in your browser.
Built and maintained by Meet Shah · Last updated
What this tool is used for
- Producing a corner badge for a card without an image.
- Getting a folded-corner ribbon effect in pure CSS.
- Comparing corner positions and colours with a preview.
- Adding a 'new' or 'sale' marker to a component.
- Producing the HTML and CSS together for a decorative badge.
Frequently Asked Questions
- How is a corner ribbon built?
- An absolutely positioned bar rotated 45 degrees into the corner of a container, with the container clipping the overflow. The rotation direction differs per corner — negative for top-left and bottom-right, positive for the other two.
- Why does my ribbon get cut off?
- Because the container needs `position: relative` and `overflow: hidden`. Without the clipping the rotated bar sticks out past the card, and without the positioning context it anchors to the wrong ancestor entirely.
- What are the pseudo-elements for?
- The folded tails that make a banner look like real wrapped ribbon. They are triangles built from transparent borders, sitting behind the bar at each end and shaded darker to suggest the fold.
- Is the ribbon text accessible?
- Only if it is real text in the markup, which is what this generates. A ribbon drawn entirely in a pseudo-element's `content` is invisible to some assistive technology and cannot be translated or selected.
- How do I keep it readable at small sizes?
- Rotated text loses legibility quickly, so keep it short and uppercase, hold the contrast against the ribbon colour rather than the card, and resist shrinking the font below about 11px.
- Will it work in right-to-left layouts?
- Not automatically — a top-right ribbon stays top-right when the layout mirrors. Swap the corner under `[dir="rtl"]`, or use logical inset properties so the position follows the writing direction.
Common errors and gotchas
- Relying on the ribbon's text being readable, which small rotated text often is not.
- Positioning the ribbon so it is clipped by a parent's overflow.
- Using it as the only signal of an important state, without a text alternative.
- Forgetting the ribbon needs a positioned ancestor, without which it lands somewhere unexpected.
- Rotating text and losing legibility for readers who need larger type.