About this snippet

Enhance blog interactions with an interactive bookmark ribbon. Clicking the button drops down a crisp ribbon with genuine spring physics, giving the user highly satisfying feedback that their post is saved.

Size
2.9 KB
Uses
HTML, CSS, JavaScript
Loads
placehold.co
Views
226
<div class="article-card">
  <div class="card-image">
    <img src="https://placehold.co/400x250/1e293b/ffffff?text=Modern+Design" alt="Article">
    
    <!-- The Bookmark Wrapper -->
    <div class="bookmark-container" id="bookmark-trigger">
      <div class="ribbon" id="ribbon">
        <svg viewBox="0 0 24 24" width="20" height="20" fill="#ffffff"><path d="M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z"></path></svg>
      </div>
      <button class="save-btn">
        <svg viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2"><path d="M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z"></path></svg>
      </button>
    </div>
  </div>
  
  <div class="card-text">
    <h3>Designing for the Future</h3>
    <p>Discover how micro-interactions build immense trust with your users and elevate product design.</p>
  </div>
</div>
*, *::before, *::after {
  box-sizing: border-box;
}

body {
  font-family: system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
  margin: 0;
  background: #f8fafc;
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
  padding: 20px;
}

.article-card {
  width: 100%;
  max-width: 400px;
  background: #ffffff;
  border-radius: 20px;
  box-shadow: 0 20px 40px -10px rgba(0,0,0,0.1);
  overflow: hidden;
}

.card-image {
  position: relative;
  width: 100%;
  height: 250px;
}

.card-image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.bookmark-container {
  position: absolute;
  top: 20px;
  right: 20px;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.save-btn {
  position: relative;
  z-index: 2;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: #ffffff;
  border: none;
  color: #64748b;
  cursor: pointer;
  display: flex;
  justify-content: center;
  align-items: center;
  box-shadow: 0 4px 10px rgba(0,0,0,0.1);
  transition: transform 0.2s, color 0.2s;
}

.save-btn:hover {
  transform: scale(1.05);
  color: #0f172a;
}

.ribbon {
  position: absolute;
  top: 22px; /* Starts hidden inside the circle */
  width: 36px;
  height: 60px;
  background: #3b82f6;
  z-index: 1;
  /* Cut the bottom natively like a ribbon */
  clip-path: polygon(0 0, 100% 0, 100% 100%, 50% 85%, 0 100%);
  display: flex;
  justify-content: center;
  padding-top: 26px;
  transform-origin: top center;
  transform: scaleY(0);
  transition: transform 0.5s cubic-bezier(0.34, 1.56, 0.64, 1.5);
}

/* Active State */
.bookmark-container.is-saved .ribbon {
  transform: scaleY(1);
}

.bookmark-container.is-saved .save-btn {
  color: #3b82f6;
}

.card-text {
  padding: 30px;
}

.card-text h3 {
  margin: 0 0 12px 0;
  color: #0f172a;
  font-size: 1.5rem;
}

.card-text p {
  margin: 0;
  color: #64748b;
  line-height: 1.6;
}
const trigger = document.getElementById("bookmark-trigger");

trigger.addEventListener("click", function() {
  trigger.classList.toggle("is-saved");
});
Esc
↑↓ moveEnter select

Start from a template

Open an .html file, or HTML, CSS, JS, Markdown, Less or TypeScript files. You can also drop them here. Styles and scripts go into their panes.

Share

Source

Keyboard shortcuts

Save