Go to homepage

Projects /

Add To Cart Interaction

A floating cart that slides in when the user decides to buy an item.

Add To Cart Interaction
Check our new component library →

We’re used to different patterns when it comes to the “add to cart” process. The basic idea behind this pattern is to notify the user that an item has been added to the cart, and provide them with a link to proceed to the checkout.

We’ve been experimenting with the idea of hiding the cart by default, and showing it when the user clicks the “add to cart” button. This way the user can either check the cart and proceed to checkout or continue shopping. The cart will stick to the bottom of the page, accessible at any time.

👋 Important: this experiment is built using the CodyHouse Framework.

Creating the structure

The cart HTML structure is composed of two main elements: a .cd-cart__trigger for the cart trigger and the cart total, and a .cd-cart__content for the cart content.

<div class="cd-cart cd-cart--empty js-cd-cart">
  <a href="#0" class="cd-cart__trigger text-replace">
    Cart
    <ul class="cd-cart__count"> <!-- cart items count -->
      <li>0</li>
      <li>0</li>
    </ul> <!-- .cd-cart__count -->
  </a>

  <div class="cd-cart__content">
    <div class="cd-cart__layout">
      <header class="cd-cart__header">
        <h2>Cart</h2>
        <span class="cd-cart__undo">Item removed. <a href="#0">Undo</a></span>
      </header>
      
      <div class="cd-cart__body">
        <ul>
          <!-- products added to the cart will be inserted here using JavaScript -->
        </ul>
      </div>

      <footer class="cd-cart__footer">
        <a href="#0" class="cd-cart__checkout">
          <em>Checkout - $<span>0</span>
            <svg class="icon icon--sm" viewBox="0 0 24 24"><g fill="none" stroke="currentColor"><line stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="3" y1="12" x2="21" y2="12"/><polyline stroke-width="2" stroke-linecap="round" stroke-linejoin="round" points="15,6 21,12 15,18 "/></g>
            </svg>
          </em>
        </a>
      </footer>
    </div>
  </div> <!-- .cd-cart__content -->
</div> <!-- cd-cart -->

The unordered list inside the .cd-cart__body element is empty by default (empty cart); when a product is added to the cart, a list item element is inserted using JavaScript.

<div class="cd-cart__body">
  <ul>
    <li class="cd-cart__product">
      <div class="cd-cart__image">
        <a href="#0">
          <img src="assets/img/product-preview.png" alt="placeholder">
        </a>
      </div>

      <div class="cd-cart__details">
        <h3 class="truncate"><a href="#0">Product Name</a></h3>

        <span class="cd-cart__price">$25.99</span>

        <div class="cd-cart__actions">
          <a href="#0" class="cd-cart__delete-item">Delete</a>

          <div class="cd-cart__quantity">
            <label for="cd-product-productId">Qty</label>

            <span class="cd-cart__select">
              <select class="reset" id="cd-product-productId" name="quantity">
                <option value="1">1</option>
                <option value="2">2</option>
                <!-- ... -->
              </select>

              <svg class="icon" viewBox="0 0 12 12"><polyline fill="none" stroke="currentColor" points="2,4 6,8 10,4 "/></svg>
            </span>
          </div>
        </div>
      </div>
    </li>

    <!-- other products added to the cart -->
  </ul>
</div>

Adding style

The .cd-cart__content and .cd-cart__trigger elements are both in position fixed and moved outside the viewport (using a translateY). When an item is added to the cart, the .cd-cart--empty class is removed from the .cd-cart element and the cart is shown.

.cd-cart__trigger,
.cd-cart__content {
  position: fixed;
  bottom: 20px;
  right: 5%;
  transition: transform .2s;
}

.cd-cart--empty .cd-cart__trigger,
.cd-cart--empty .cd-cart__content { // hide cart
  transform: translateY(150px);
}

As for the cart animation: we assign a fixed height and width to the div.cd-cart__layout element (the same of the a.cd-cart__trigger); when the cart is open, we use the .cd-cart--open class to animate its height and width while revealing the cart content.

.cd-cart__layout {
  position: absolute;
  bottom: 0;
  right: 0;
  z-index: 2;
  overflow: hidden;
  height: 72px;
  width: 72px;
  border-radius: var(--radius);
  transition: height .4s .1s, width  .4s .1s, box-shadow .3s;
  transition-timing-function: cubic-bezier(.67,.17,.32,.95);
  background: var(--cd-color-3);
  box-shadow: 0 4px 30px rgba(#000, .17);
}

.cd-cart--open .cd-cart__layout {
  height: 100%;
  width: 100%;
  transition-delay: 0s;
}

The .cd-cart__product--deleted class is used to remove an item from the cart: the deleted element has an absolute position, and the cd-item-slide-out animation is used to create the slide-out effect.

.cd-cart__product--deleted { // this class is added to an item when it is removed form the cart
  position: absolute;
  left: 0;
  width: 100%; 
  opacity: 0;
  animation: cd-item-slide-out .3s forwards;
}

@keyframes cd-item-slide-out {
  0% {
    transform: translateX(0);
    opacity: 1;
  }
  100% {
    transform: translateX(80px);
    opacity: 0;
  }
}

If the user clicks on 'Undo', the .cd-cart__product--deleted class is removed and the element is reinserted in the list.

Events handling

When the user clicks the .js-cd-add-to-cart button, the addProduct() function is used to insert a new list item inside the .cd-cart__body > ul element. The product details used are placeholders, which should be replaced by the real product info:

function addProduct(target) {
  // this is just a product placeholder
  var productAdded = '<li class="cd-cart__product"><div class="cd-cart__image"><a href="#0"><img src="assets/img/product-preview.png" alt="placeholder"></a></div><div class="cd-cart__details"><h3 class="truncate"><a href="#0">Product Name</a></h3><span class="cd-cart__price">$25.99</span><div class="cd-cart__actions"><a href="#0" class="cd-cart__delete-item">Delete</a><div class="cd-cart__quantity"><label for="cd-product-'+ productId +'">Qty</label><span class="cd-cart__select"><select class="reset" id="cd-product-'+ productId +'" name="quantity"><option value="1">1</option><option value="2">2</option><option value="3">3</option><option value="4">4</option><option value="5">5</option><option value="6">6</option><option value="7">7</option><option value="8">8</option><option value="9">9</option></select><svg class="icon" viewBox="0 0 12 12"><polyline fill="none" stroke="currentColor" points="2,4 6,8 10,4 "/></svg></span></div></div></div></li>';
  cartList.insertAdjacentHTML('beforeend', productAdded);
};

Additional functions, like the updateCartCount() or updateCartTotal(), have been defined to update the cart count and total when new products are added/deleted or when the quantity of a product added to the cart is changed.

Project duplicated

Project created

Globals imported

There was an error while trying to export your project. Please try again or contact us.